0

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'
        ]
    );
}
15
  • You have to create custom rule for such kind of validation Commented May 2, 2019 at 7:39
  • @SagarGautam Kindly assist me on that.... Commented May 2, 2019 at 7:40
  • All you have to do is pass the relation data in array. Then, you can create custom rule using artisan command. after that you can write logic to check only one husband or wife. return true if data is valid other wise return false. See official docs about it laravel.com/docs/5.8/validation#custom-validation-rules Commented May 2, 2019 at 7:44
  • If you even confused after reading docs i will explain it later Commented May 2, 2019 at 7:46
  • 1
    @SagarGautam Is this applicable in Laravel 5.4 cause am using that version Commented May 2, 2019 at 7:58

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

Hi,, thanks for help,, unfortunately am using an old version of Laravel 5.4,, I have tried implementing your code in App/Providers/AppServiceProvider.php in my app but it fails,, I have referened to this url: laravel.com/docs/5.4/validation#custom-validation-rules kindly assist?
Please give more details on "it fails", what exception are you getting?
.. Kindly check the updated code,, I have added how am using your logic in App/Providers/AppServiceProvider.php file and referring it from the view...
Kindly assist me on that,, am a newbie in Laravel
1

I think I will use this method, hoping to help you Use rule in of laravel

$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),
]
);

1 Comment

Thanks alot for your help,, I need to notify the user to change on his side,, Kindly assist on that..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.