Skip to content
Advertisement

How to create custom validation rule for dependent input fields in laravel

In my input form, I have two fields; momentFrom & momentTo. I need to put a validation which gives error message if any of the following criteria fails.

  • momentFrom is greater than or equal to momentTo.
  • momentFrom is less than now.

My code for storing the data:

public function store(Request $request, Requisition $requisitionObj) {
    $momentFrom = strtotime($request->txtTravelDate . " " . $request->txtTimeFrom);
    $momentTo = strtotime($request->txtTravelDate . " " . $request->txtTimeTo);

    $timeValidation = $requisitionObj->validateTiming($momentFrom, $momentTo);
    if ($timeValidation['error']) {
        echo 'ERROR: ' . $timeValidation['message'];
        return view('requisitions.create');
    } else {
        /* store form data into requisition object */
        $requisitionObj->travel_date = $request->txtTravelDate;
        $requisitionObj->moment_from = $momentFrom;
        $requisitionObj->moment_to = $momentTo;

        $requisitionObj->save();
        
        return redirect()->route('requisitions.index');
    }
}

I have seen laravel custom validation rules where only one field can be validated at a time. But in my scenario I need to check both fields at a time depending on each other. How can I achieve this?

Thanks for any help in advance!

Advertisement

Answer

At last, I have solved this problem using FormRequest and AppServiceProvider. Thought this would help others who come to this place.

First I have created FormRequest validator using following artisan command.

php artisan make:request StoreRequisition

Then added primary validation rules and messages into it.

namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;

class StoreRequisition extends FormRequest {
    public function authorize() {
        return true;
    }

    public function rules() {
        $rules = [
        'txtTravelDate' => 'required|date_format:Y-m-d|after_or_equal:today',
        'txtTimeFrom' => 'required|date_format:H:i|travel_time_validate',
        'txtTimeTo' => 'required|date_format:H:i',
        ];
        return $rules;
    }


    public function messages() {
        return [
            'txtTravelDate.required' => 'Travel date is required!',
            'txtTravelDate.date_format' => 'Invalid format for Travel Date!',
            'txtTravelDate.after_or_equal' => 'Travel Date should be today or later!',
            'txtTimeFrom.required' => 'Time From is required!',
            'txtTimeFrom.date_format' => 'Invalid format for Time From!',
            'txtTimeFrom.travel_time_validate' => 'Invalid time selected!',
            'txtTimeTo.required' => 'Time To is required!',
            'txtTimeTo.date_format' => 'Invalid format for Time To!',
            'listFunction.required' => 'Department to be selected!',
            'txtPickLoc.required' => 'Pickup Location is required!',
            'txtDropLoc.required' => 'Drop Location is required!',
            'listPurpose.required' => 'Travel Purpose to be selected!'
        ];
    }
}

Then inside appProvidersAppServiceProvider, added the extra validation logic.

public function boot() {
    Validator::extend(
        'travel_time_validate',
        function ($attribute, $value, $parameters, $validator) {
            $inputs = $validator->getData();
            /* convert time to moments */
            $momentFrom = strtotime($inputs['txtTravelDate'] . " " . $inputs['txtTimeFrom']);
            $momentTo = strtotime($inputs['txtTravelDate'] . " " . $inputs['txtTimeTo']);

            $result = true;
            if ($momentFrom >= $momentTo) {
                $result = false;
            }
            return $result;
        }
    );
}

My Controller:

public function store(StoreRequisition $request, Requisition $requisitionObj) {

    $validatedData = $request->validated();

    /* store form data into requisition object */
    $requisitionObj->requester_id = Auth::user()->id;
    $requisitionObj->travel_date = $request->txtTravelDate;
    $requisitionObj->time_from = $request->txtTimeFrom;
    $requisitionObj->time_to = $request->txtTimeTo;
    $requisitionObj->purpose_id = $request->listPurpose;

    /* Finally save the record into the database */
    $requisitionObj->save();

    return redirect()->route('requisitions.index');
}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement