Forum

Validator : Greater than other field

Hi,

I'm posting 2 inputboxes in my app which are both numeric. I want my validator to to this :

if field 2 is greater than field 1 = OK if field 2 is equal to or smaller than field 1 = FAIL

How can i do this?

dennusb
dennusb
  • 2 years ago

You need to extend the Validator Class

Validator::extend('greater_than', function($attribute, $value, $parameters)
{
    $other = Input::get($parameters[0]);

    return isset($other) and intval($value) > intval($other);
});

$validation = Validator::make(Input::all(), ['field2' => 'greater_than:field1']);

Hi neilpato22,

How does one solve the problem if the validation needs to be done against some other local array that is passed as the first parameter to the Validator::make function and not on the Input::all() array?

In such case, the code in the closure does not have access to the local array. Is there a way to work around this problem?

My validation rules are defined in the Model and it was written in a way that separate the validation from the request. That is, I do not tie the validation to the existence of Input:all(). Instead, I pass an associative array to be validated.

Thanks

I found a solution to my own problem:

Before invoking the Validator::make() function, modify the set of rules by appending the value to compare to like so:

Validator::extend('greater_than', function($attribute, $value, $parameters)
{
    if (isset($parameters[1])) {
       $other = $parameters[1]);

       return intval($value) > intval($other);
    } else {
      return true;
   }
});

$validation = Validator::make($input, ['field2' => 'greater_than:field1,' . $data['field1']]);

what's a good place in laravel folder structure to put validators if I want to share them?

I'm putting them in the AppServiceProvider. Not sure this is best, but it seems to work well. Here's a complete minimal example.

<?php

namespace App\Providers;
use Validator;
use Input;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('greater_than', function($attribute, $value, $params, $validator){


            $other = Input::get($params[0]);
            return intval($value) > intval($other);
        });

        Validator::replacer('greater_than', function($message, $attribute, $rule, $params) {
            return str_replace('_', ' ' , 'The '. $attribute .' must be greater than the ' .$params[0]);
        });

    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
         ...
    }
}

Works like a charm!

Thanks @bryanwokich