1

Laravel easily validates array based form input fields

<input name='input_name[0][0]">
<input name='input_name[0][1]">

with

'input_name.* = 'required',

https://laravel.com/docs/5.5/validation#validating-arrays

But how can I validate array based select fields?

I have a form where customer info is added, user has to choose the customer's gender and it's possible to add infinite number of customer.

So i have a select for 1 customer:

<select name="gender[0]">
<option selected="selected" disabled="disabled" hidden="hidden" value="">Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option></select>

and then

<select name="gender[1]">...
<select name="gender[N]">

When I set the rule as:

'gender.*' => 'required'

It doesn't recognize an 'unchoosen' select-box as an error....

But if I update validation rules to:

'gender[0]'=>'required'
'gender[1]'=>'required'
'gender[N]'=>'required'

It works absolutely fine... (by "it works", I mean that it returns a mistake "Gender field is required").

So, apparently Laravel has some problems with array based select names.

Appreciate any help!

1
  • put it in a loop! Commented Sep 15, 2017 at 16:30

2 Answers 2

1
public function rules() {
    $rules = [];

    $gender = $this->input('gender');
    foreach ($gender as $index => $item) {
        $rules["gender.{$index}"] = 'required';
    }

    return $rules;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I've decided o answer the question myself.

1) First solution is to make the first "placeholder" option not disabled (as was in my case, see above - it's because I use LaravelCollective and they have it by default):

<select name="gender[0]">
<option selected="selected" hidden="hidden" value="">Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option></select>

When you remove 'disabled' from option-1 of your select then it sends ' ' when posting (instead of sending nothing with 'disabled'). So it sends

gender[0] = '';
gender[1] = '';

etc...

Actually, if you have a lot of gender[N] (or maybe other array based selects) I think it's the neatest solution.

2) Second solution is provided below by omadonex:

public function rules() {
    $rules = [];

    $gender = $this->input('gender');
    foreach ($gender as $index => $item) {
        $rules["gender.{$index}"] = 'required';
    }

    return $rules;
}

in this case you'll have a separate rule for every array-based select and it will work (see why in the end of my topicstarter-post). I prefer this solution less than 1st one because you'll have a long list of "gender"-rules if you have a lot of ...

3) Also I've undertood why 'gender[0]'=>'required' works

and 'gender.*' => 'required' does not

for array based selects like <select name=gender[0]>

It's kind of obvious if you think about it: when POSTING select tag with first option (a placeholder) being disabled, as in my example above:

<option selected="selected" disabled="disabled" hidden="hidden" value="">Gender</option>

the $POST sends nothing....

So if Laravel's validation rule is 'gender[0]'=>'required' Laravel "thinks": "OKAY, I've received no "gender[0]", but I know what is required exactly ("gender[0]", of course) . I have to send a mistake because there is no "gender[0]".

But if rule is 'gender.*' => 'required' and Laravel get's no input of "gender" kind, then it also doesn't know what EXACTLY is required ('gender.*' may mean gender[0]... gender [12345] ... gender[anything]). Laravel can't send a mistake, because infinite number of gender[...] is missing, so he simply omits it....

PS. If you work with LaravelCollective forms of newer versions, they create placeholder "disabled" by default. Here is a macro to avoid it.

{!! 
        Form::macro('selectNonDisabled', function($value, $placeholder, $array, $disabled=null, $class=null) {
        $select  = "<select class='form-control $class' $disabled name='$value'>";

        $select .= "<option selected='selected' hidden='hidden' value=''>$placeholder</option>";

        foreach ($array as $key => $value) {

        $select .= "<option value='$key'>$value</option>";

        }

        $select .= "</select>";

    return $select;

        });
!!}

2 Comments

You're in my first search, you really solved the problem. Good Job. Thx
:) you are welcome. Wish you success with your projects:)

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.