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

[PROPOSAL] A conditional validator #2406

Closed
gimox opened this issue Feb 11, 2014 · 32 comments
Closed

[PROPOSAL] A conditional validator #2406

gimox opened this issue Feb 11, 2014 · 32 comments
Labels
Milestone

Comments

@gimox
Copy link
Contributor

@gimox gimox commented Feb 11, 2014

If i create a custom validation in model, it not fire if the field is not send (=null) or required.

So if i need somthink like this.

If this field is null then this other field ....
i need to add some logic to controller, but now i have the validation both controller and model and is not so good...

My proposal is to add a conditional validator and make custom validation work if field is null.

@qiangxue
Copy link
Member

@qiangxue qiangxue commented Feb 11, 2014

Did you set skipOnEmpty to be false for your custom validator if you want it to be used all the time?

@gimox
Copy link
Contributor Author

@gimox gimox commented Feb 11, 2014

where i need to set this????

@qiangxue
Copy link
Member

@qiangxue qiangxue commented Feb 11, 2014

Configure the rule in rules(), something like this: ['name', 'myvalidator', 'skipOnEmpty' => false].

@qiangxue qiangxue closed this Feb 11, 2014
@gimox
Copy link
Contributor Author

@gimox gimox commented Feb 12, 2014

Thanks i try it tomorrow.
Can you add it in model docs?

@cebe cebe added the type:docs label Feb 12, 2014
@cebe cebe reopened this Feb 12, 2014
@cebe cebe closed this in d8508cd Feb 12, 2014
@cebe cebe added this to the 2.0 Beta milestone Feb 12, 2014
@thiagotalma
Copy link
Contributor

@thiagotalma thiagotalma commented Feb 26, 2014

And if the condition is another attribute to be equal to or different from any value?

@cebe
Copy link
Member

@cebe cebe commented Feb 26, 2014

You can check for that in your custom validator...

@thiagotalma
Copy link
Contributor

@thiagotalma thiagotalma commented Feb 26, 2014

Yes, I can.

But it would be nice being able to do conditional validation in standard validators. :)

@samdark
Copy link
Member

@samdark samdark commented Feb 26, 2014

I think it may complicate validators a lot.

@thiagotalma
Copy link
Contributor

@thiagotalma thiagotalma commented Feb 26, 2014

That would be beautiful:

['state', 'required', 'if' => ['equals' => ['country', Country::USA]]],
['stateOthers', 'required', 'if' => ['notEequals' => Country::USA]],
['mother', 'required', 'if' => [['and' => ['lt' => ['age', 18], 'notEequals' => ['married', Helper::YES]]]]]

Maybe some day ...

@cebe
Copy link
Member

@cebe cebe commented Feb 26, 2014

Rather than introducing a new syntax we could allow using php code:

['state', 'required', 'if' => function($model) { return $model->country == Country::USA; }],
['stateOthers', 'required', 'if' => function($model) { return $model->country != Country::USA; }],
['mother', 'required', 'if' => function($model) { return $model->age < 18 && $model->married != true; }],

Can be written like this for better readability:

public function rules()
{
    $usa = function($model) { return $model->country == Country::USA; };
    $notUsa = function($model) { return $model->country != Country::USA; };
    $child = function($model) { return $model->age < 18 && $model->married != true; };
    return [
        ['state', 'required', 'if' => $usa],
        ['stateOthers', 'required', 'if' => $notUsa], // note that it is not possible to write !$usa
        ['mother', 'required', 'if' => $child],
    ];
}
@cebe cebe reopened this Feb 26, 2014
@cebe cebe added type:feature and removed type:docs labels Feb 26, 2014
@cebe cebe removed this from the 2.0 Beta milestone Feb 26, 2014
@thiagotalma
Copy link
Contributor

@thiagotalma thiagotalma commented Feb 26, 2014

Very, very good! 👍

Avoid the need for us to create inline validators for every different thing.

@qiangxue
Copy link
Member

@qiangxue qiangxue commented Feb 26, 2014

Probably use the name when as if is a reserved word.

@RusAlex
Copy link
Contributor

@RusAlex RusAlex commented Feb 26, 2014

Thats the most beautyful solution i ever seen.

@cebe
Copy link
Member

@cebe cebe commented Feb 26, 2014

Thanks :)

@gimox
Copy link
Contributor Author

@gimox gimox commented Feb 26, 2014

very interesting solution..

@samdark
Copy link
Member

@samdark samdark commented Feb 26, 2014

Interesting solution.

@cebe
Copy link
Member

@cebe cebe commented Feb 27, 2014

Wasn't that obvious? :-D never used something like that before to be honest ;)

@samdark
Copy link
Member

@samdark samdark commented Feb 27, 2014

Well, it was but I'm too used to anonymous function-less 5.2 :)

@andy5
Copy link
Contributor

@andy5 andy5 commented Feb 27, 2014

Can it somehow be applied to a client validation too? Will need to specify a php function + js function fired before field validation.

@cebe cebe added this to the 2.0 RC milestone Feb 27, 2014
qiansen1386 pushed a commit to qiansen1386/yii2 that referenced this issue Mar 9, 2014
drenty added a commit to drenty/yii2 that referenced this issue Mar 19, 2014
qiangxue added a commit that referenced this issue Mar 23, 2014
Implemented conditional validators (see #2406)
@qiangxue qiangxue modified the milestones: 2.0 Beta, 2.0 RC Mar 23, 2014
@qiangxue qiangxue closed this Mar 23, 2014
@6pblcb
Copy link

@6pblcb 6pblcb commented Apr 4, 2014

Missed the discussion (
As a complement.

//string the name attribute, whose value will be used for comparison.
public $dependentAttribute;
//string|integer|array second comparison value
public $compare;
//string the operator of comparison. If $compare is array, $operator can take values, only '==', '===', '!=', '!=='.
public $operator = '==';
//use
['foo', 'required', 'dependentAttribute'=>'bar', 'compare'=>'baz'],

Plus the add-on that can be done enableClientValidation = true

@cebe
Copy link
Member

@cebe cebe commented Apr 4, 2014

the implemented solution is more flexible as it allows arbitrary conditions.

@6pblcb
Copy link

@6pblcb 6pblcb commented Apr 5, 2014

I do not suggest it, cancel. This supplement. I understand that this is partly duplication. But allows you to make client-side interfaces more flexible.
Perhaps my question is resolved: #1422

@packcode
Copy link

@packcode packcode commented May 5, 2015

Hello guys i am trying to achieve conditional validation but it always returns true,here is my code,
[['amount'], 'required', 'when' => function ($model) {
                    return (($model->shid != 134) || ($model->shid != 76));
                    }, 
                    'whenClient' => "function (attribute, value) {
                    return ($('#dropdownid').val() != 134 || $('#dropdownid').val() != 76);
                    }"
            ],

Can anyone tell me what is i am doing wrong?

@freezy-sk
Copy link
Contributor

@freezy-sk freezy-sk commented May 5, 2015

@packcode that's because your condition is always true. you want amount to be not required when shid is 134 or 76?

@packcode
Copy link

@packcode packcode commented May 7, 2015

@freezy-sk yes that is precisely what I want

@freezy-sk
Copy link
Contributor

@freezy-sk freezy-sk commented May 11, 2015

@packcode so you have to change your condition to be false when its 134 or 76 !($model->shid == 134 || $model->shid == 76) or with equivalent ($model->shid != 134 && $model->shid != 76)

@packcode
Copy link

@packcode packcode commented May 11, 2015

Problem solved. Thanks anyways.!!!

@husein-bt
Copy link

@husein-bt husein-bt commented Apr 15, 2016

Hello guys i have the same proplem that occurred with @packcode
Please check it
['end_price', 'required', 'when' => function ($model) { return ($model->start_price!=""); }, 'whenClient' => "function (attribute, value) { if( $('#site-start_price').val() === undefined){ false; }else{ true; } }" ]

@freezy-sk
Copy link
Contributor

@freezy-sk freezy-sk commented Apr 15, 2016

@husein-bt

['end_price', 'required', 'when' => function ($model) {
    return ($model->start_price != '');
}, 'whenClient' => "function (attribute, value) {
    return ($('#site-start_price').val() != '');
}" ]
@husein-bt
Copy link

@husein-bt husein-bt commented Apr 15, 2016

Thank you @freezy-sk it works
but how can i make compare validation between tow fields in the form

@freezy-sk
Copy link
Contributor

@freezy-sk freezy-sk commented Apr 15, 2016

@husein-bt sorry but that's off-topic here

@husein-bt
Copy link

@husein-bt husein-bt commented Apr 15, 2016

Thank you @freezy-sk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.