2

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!

4
  • 1
    before(date) - after(date) validations will help you. Details on : laravel.com/docs/7.x/validation#available-validation-rules Commented Jul 29, 2020 at 7:27
  • Can I not create custom validation to put complicated logics? Commented Jul 29, 2020 at 9:46
  • If you want custom error messages read the page : laravel.com/docs/7.x/validation#custom-error-messages Commented Jul 29, 2020 at 9:50
  • Not only the message, I want to put custom validation logic before storing data. When a user tries to create a request, system has to check if any vehicle is available at that date & time. If not available, controller has to return an error message to the request form. Wondering how can I put those logic and send back the message to the form. TIA Commented Jul 29, 2020 at 10:14

3 Answers 3

2

Creating new Rule Class

You can create your custom rule with the artisan command: php artisan make:rule YourRuleNamethis will create a new Rule Class file into the Rules folder.

By default the created file contains a constructor, a passes method and a message method.

Rules Logic

If you have some complicated rules where you need the request or some models, you can pass them via the constructor.

  public function __construct(Request $request, User $user, ....)
    {
    //save them into class variables to access them later
        $this->request = $request;
        $this->user = $user;

    }

Otherwise you can directly put your validation logic into the passes method:

public function passes($attribute, $value){
    //some code
    return #myCondition
}

Last you are able to specify the message if the validation fails.

    public function message()
    {
        return 'Your message';
    }

To use your rule simply add it to your rules array:

$rules = [
'my_attribute' => [new MyCustomRule(),...],
]
Sign up to request clarification or add additional context in comments.

2 Comments

This solution looks promising! I will try this and get back here with results.
But on what input it should be added? I want to run rule on specific set of inputs only once - some validator logic which depends on many inputs.
0

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 App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;

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 app\Providers\AppServiceProvider, 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');
}

Comments

0

Example how make custom rule for validation in Laravel 8.x / Lumen 8.x.

public static function rules(){
    return [
       'number' => [
          'required', 'min:1', 'max:30', 'string', self::testNumber(),
       ],
    ];
}


public static function testNumber(){
    return function($attribute, $value, $fail){
        if ($value === 'foo'){
            $fail('The '.$attribute.' is invalid.');
        }            
    };
} 

Comments

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.