Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote validation only validates the first array element #465

Open
bytestream opened this issue Jun 24, 2020 · 6 comments
Open

Remote validation only validates the first array element #465

bytestream opened this issue Jun 24, 2020 · 6 comments
Labels

Comments

@bytestream
Copy link
Collaborator

Subject of the issue

Remote validation will only validate the first item in an array.

Your environment

  • version of this package: 4.0.0
  • version of Laravel: 6.18.3

Steps to reproduce

<select name="domain">
    <option value="http://google.com">http://google.com</option>
    <option value="http://jquery_dev">http://jquery_dev</option>
</select>
[
    'domain' => [ 'required', 'array' ],
    'domain.*' => ['url'],
];

Expected behaviour

Should fail because jquery_dev is not valid - the url validation does not permit _ in URLs

Actual behaviour

Validation passes because it only validates domain.0

@bytestream bytestream added the bug label Jun 24, 2020
@bytestream
Copy link
Collaborator Author

This should only affect select-multiple elements. We expect it to validate against domain.0 in every other case because .val() will produce String not an Array

@jshah4517
Copy link

This problem seems to come from src/Remote/Validator.php, complex to solve.

parseAttributeName function

It's converting domain[] to domain.0, it should be domain.*.

setRemoteValidation function

This is checking if a rule exists for the attribute and then setting the validator rules to just that rule only:
$rules = isset($rules[$attribute]) ? $rules[$attribute] : [];

Problem is the line above $validator->getRules() automatically converts the rules to domain.0 and domain.1. So the above check will fail even if the attribute name is corrected.

validateJsRemoteRequest function

The escaping assumes the validator messages will just have one element, needs to be adapted to work for array rules like this.

@HadiAghandeh
Copy link

HadiAghandeh commented Jul 1, 2020

I am having an issue that seems to be related to this issue.
I have repetitive question and answers input, and the following is my rules.

        'question' => 'required|array|min:1',
        'question.*' => 'required|array',
        'question.*.title' => 'required|string|min:3|max:500',
        'question.*.answer' => 'required|array|min:1',
        'question.*.answer.*' => 'nullable|string|min:3|max:500',
         //while the quantity of answers is arbitrary but there must be at least two answers:
        'question.*.answer.0' => 'required_with:question.*.title|string|min:3|max:500',
        'question.*.answer.1' => 'required_with:question.*.title|string|min:3|max:500',
        'question.*.correct' => 'nullable|integer'

it will ignore validation on name="question[0][answer][*]" in a form like below:
in this example I want every question have at least two answers.

                        <input placeholder="Question" name="question[0][title]" type="text">
                        <input placeholder="Answer 1" name="question[0][answer][0]" type="text">
                        <input placeholder="Answer 2" name="question[0][answer][1]" type="text">
                        <input placeholder="Answer 3" name="question[0][answer][2]" type="text">
                        <input placeholder="Answer 4" name="question[0][answer][3]" type="text">

@bytestream
Copy link
Collaborator Author

@hadiaec20h

'question.*.answer.*' => 'nullable|string|min:3|max:500',
         //while the quantity of answers is arbitrary but there must be at least two answers:
        'question.*.answer.0' => 'required_with:question.*.title|string|min:3|max:500',

These rules look suspect. .* will be expanded to .0, .1.2 deepening in the input data. I would think by manually defining a .0 rule for either overriding the .* or the .* is overriding the .0 rule. If that makes sense

@HadiAghandeh
Copy link

HadiAghandeh commented Jul 1, 2020

@hadiaec20h

'question.*.answer.*' => 'nullable|string|min:3|max:500',
         //while the quantity of answers is arbitrary but there must be at least two answers:
        'question.*.answer.0' => 'required_with:question.*.title|string|min:3|max:500',

These rules look suspect. .* will be expanded to .0, .1.2 deepening in the input data. I would think by manually defining a .0 rule for either overriding the .* or the .* is overriding the .0 rule. If that makes sense

The default validation of Laravel doesn't override.

I also tested this with the following rules, the issue persist:

            'question' => 'required|array|min:1',
            'question.*' => 'required|array',
            'question.*.title' => 'required|string|min:3|max:500',
            'question.*.answer' => 'required|array|min:1',
            'question.*.answer.*' => 'required|string|min:3|max:500',
            'question.*.correct' => 'nullable|integer'

it would be a good idea in these situations that the default behavior of JsValidation doesn't work as one would expect. One Could have the option to make the validation ajax only. so every thing would be validated by ajax and the behavior would be exactly what Laravel validation produce;

@bytestream
Copy link
Collaborator Author

@hadiaec20h please open another issue with steps to reproduce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants