Sigal Zahavi
Sigal Zahavi

Reputation: 1063

Laravel conditional validation does not work

I have a form with these fields:
shipping_method (hidden field with value="2" in my testing case)
courier_id
tracking_no
delivery_date

The courier_id field is required only if the shipping_method is 2

<div class="form-group{{ $errors->has('courier_id') ? ' has-error' : ''}}">
    <label>Courier</label>

    <select name="courier_id" class="form-control">
        <option value="">Select...</option>
        @foreach($couriers as $courier)
            <option value="{{ $courier->id }}">{{ $courier->name }}</option>
        @endforeach
    </select>

    @if ($errors->has('courier_id'))
    <span class="help-block">
        <strong>{{ $errors->first('courier_id') }}</strong>
    </span>
    @endif
</div>

In my controller:

public function update(Request $request, $id)
{
    $delivery_date = Null;
    $courier_id = Null;
    $order = Order::findOrFail($id);
    $status = 0;

    if($order->status == 2) {
        $status = 3;
        $courier_id = $request->courier_id;

        $messages = [ 'courier_id.required' => 'Please select a courier'];

        $v = Validator::make(Input::all(), [
            'tracking_no' => 'required',
            'delivery_date' => 'required|date_format:d/m/Y'
        ], $messages)->validate();

        $v->sometimes('courier_id', 'required', function (Request $request) {
          return true;
            //return $request->shipping_method == 2;
        });

Even though the courier_id is empty, I don't get the error for it.

I have three questions:

  1. Why even when I just return true on the sometimes check, I don't get the error

  2. Not sure what is the parameter I should send to the sometimes check, is it Request $request?

  3. I tried to send the order to the sometimes check instead of the request so I won't have to have a hidden field for it on the form, e.g.

    $v->sometimes('courier_id', 'required', function ($order) { return $order->shipping_method == 2; });

Again, no error is displayed.

The order status is 2 for sure.

I also tried:

 $v->sometimes('courier_id', 'required', function ($order) {
        return $order->shipping_method == '2';
     });

If I remove the sometimes check, and just add the courier_id validation as required, I do get the error on the form.

Upvotes: 1

Views: 497

Answers (1)

chanafdo
chanafdo

Reputation: 5124

You are adding the conditional rule after you validate the data thus making the validator uninformed about that rule. That should answer your first question

For your question 2, 3 the document states that

The $input parameter passed to your Closure will be an instance of Illuminate\Support\Fluent and may be used to access your input and files.

First add the custom rule to the validator. Then validate the data.

$v = Validator::make(Input::all(), [
    'tracking_no' => 'required',
    'delivery_date' => 'required|date_format:d/m/Y'
], $messages);

$v->sometimes('courier_id', 'required', function (Request $request) {
    return $request->shipping_method == 2;
});

$v->validate();

You should be able to do this without a conditional rule.

You can add the following to your existing rule set which should validate

'courier_id' => 'required_if:shipping_method,2'

So your validation should be

$v = Validator::make(Input::all(), [
    'tracking_no' => 'required',
    'delivery_date' => 'required|date_format:d/m/Y',
    'courier_id' => 'required_if:shipping_method,2'
], $messages)->validate();

Upvotes: 2

Related Questions