Am working on a Laravel application whereby am capturing some input fields consisting of dropdown fields on some cards whereby I submit them to the backend via AJAX.
On the backend I want to create a validation logic whereby there should be only one husband or wife from the select dropdown inputs captured on the frontend. This means the user should only select only one husband or wife from the select dropdown on the cards on the frontend
Form template
<form method="POST" action="#" id="phase3" accept-charset="UTF-8">
<!-- CSRF TOKEN-->
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
<!-- Card 1-->
<div class="col-md-4 col-sm-12 phonecard3">
<div class="innerDiv">
<!-- Gender -->
<div class="row">
<label class="fm-input"> Relation :</label>
<select class="fm-input otherMenu" id="relation1" required>
<option value="Husband"> Husband </option>
<option value="Wife"> Wife </option>
<option value="Son"> Son </option>
<option value="Daughter"> Daughter </option>
</select>
</div>
<!-- END -->
</div>
</div>
<!-- End card 1-->
<!-- Card 2-->
<div class="col-md-4 col-sm-12 phonecard3">
<div class="innerDiv">
<!-- Gender -->
<div class="row">
<label class="fm-input"> Relation :</label>
<select class="fm-input otherMenu" id="relation2" required>
<option value="Husband"> Husband </option>
<option value="Wife"> Wife </option>
<option value="Son"> Son </option>
<option value="Daughter"> Daughter </option>
</select>
</div>
<!-- END -->
</div>
</div>
<!-- End card 2-->
<!-- Card 3-->
<div class="col-md-4 col-sm-12 phonecard3">
<div class="innerDiv">
<!-- Gender -->
<div class="row">
<label class="fm-input"> Relation :</label>
<select class="fm-input otherMenu" id="relation3" required>
<option value="Husband"> Husband </option>
<option value="Wife"> Wife </option>
<option value="Son"> Son </option>
<option value="Daughter"> Daughter </option>
</select>
</div>
<!-- END -->
</div>
</div>
<!-- End card 3-->
<div class="row">
<div class="col-md-6 col-md-offset-3">
<button class="btn btn-lg lov1" type="submit"> Save & Create for Spouse & Children <i class="fa fa-check-circle" ></i></button>
</div>
</div>
</form>
AJAX code to submit form details
$("#phase3").submit(function( event ) {
event.preventDefault();
//Fetch data
var token = $('#token').val();
var relation1 = $("#relation1").val();
var relation2 = $("#relation2").val();
var relation3 = $("#relation3").val();
//Store in a JS object
var type ={
'token': token,
//Relations
'relation1' : relation1,
'relation2' : relation2,
'relation3' : relation3
};
//console.log(type);
$.ajax({
type: "POST",
url: "submitPhase3",
data:JSON.stringify(type),
contentType: 'application/json',
dataType: "json",
success: function(response){
//console.log(response);
},
//Alert errors from backend
error: function(data) {
//console.log(data);
}
});
});
Backend PHP function to handle request
public function submitPhase3(Request $request){
dd($request->all());
$validation = $this->validate($request, [
//Relations
'relation1'=> isset($request->relation1) ? $request->relation1 : null,
'relation2'=> isset($request->relation2) ? $request->relation2 : null,
'relation3'=> isset($request->relation3) ? $request->relation3 : null,
]
);
}
Custom validator in App/Providers/AppServiceProvider.php file
public function boot(){
//Custom Validation
Validator::extend('relation',
function ($attribute, $value, $parameters, $validator){
$relationMaxMap = [];//create a map with key=>'value', value=>'maximum'
$relations = Config::get('app.relations');
foreach($relations as $relation) {
$relationMaxMap[$relation['value']] = $relation['maximum'];
}
//$relationMaxMap will be [1=>1, 2=>1,3=>10,4=>10];
$requestMap = []; //map from the request 'value'=>'count', this way you know what relations has been selected and how many times
foreach($values as $value) {
if(!isset($values[$value])) { //at the begining
$requestMap[$value] = 1;
}
$requestMap[$value]++;
}
//Compare the maps to check if it execedes the maximum allowed in your app
foreach($relationMaxMap as $value=>$maximum) {
if($requestMap[$value] > $maximum) {
return false;
}
}
return true;
});
}
New Function
public function submitPhase3(Request $request){
dd($request->all());
$validation = $this->validate($request, [
//Pull code from custom validator
'relation' => 'relation'
]
);
}
I would define a list of values in a config and pass them to the given view (key being the value and the text being what is displayed):
$relations=[
['value'=>1,'display'=>'Wife','maximum'=>1]
['value'=>2,'display'=>'Husband','maximum'=>1],
['value'=>3,'display'=>'Son','maximum'=>10],
['value'=>4,'display'=>'Daughter','maximum'=>10]
];
Controller:
[...]
return view('my_view', Config::get('app.relations');
[...]
View:
[...]
@foreach ($relations as $relation)
<option value="{{$relation['value']}}">{{$relation['display']}}</option>
@endforeach
[...]
I would also pass the relations
as an array in a custom validator:
<?php
class CustomValidator extends \Illuminate\Validation\Validator
{
public function validateRelations($attribute, $values, $parameters)
{
$relationMaxMap = [];//create a map with key=>'value', value=>'maximum'
$relations = Config::get('app.relations');
foreach($relations as $relation) {
$relationMaxMap[$relation['value']] = $relation['maximum'];
}
//$relationMaxMap will be [1=>1, 2=>1,3=>10,4=>10];
$requestMap = []; //map from the request 'value'=>'count', this way you know what relations has been selected and how many times
foreach($values as $value) {
if(!isset($values[$value])) { //at the begining
$requestMap[$value] = 1;
}
$requestMap[$value]++;
}
//Compare the maps to check if it execedes the maximum allowed in your app
foreach($relationMaxMap as $value=>$maximum) {
if($requestMap[$value] > $maximum) {
return false;
}
}
return true;
}
}
NOTE: Code not tested, but this is how I would approach this
Also I would use the validator is a form request
I think I will use this method, hoping to help you
$options = ['Husband', 'Wife', 'Son', 'Daughter']; // rule default
$relation1 = $request->input('relation1'); // value of relation 1
$relation2 = $request->input('relation2') // value of relation 2
// get rule of relation 2, if relation 1 choose husband
//then relation2 will remove husband --> ['Wife', 'Son', 'Daughter']
$ruleForRelation2 = array_diff($options, [$relation1]);
// same relation 1
$ruleForRelation3 = array_diff($options, [$ruleForRelation2]);
$validation = $this->validate($request, [
'relation1'=> Rule::in($options),
'relation2'=> Rule::in($ruleForRelation2),
'relation3'=> Rule::in($ruleForRelation3),
]
);