How To: Custom Client Validation On Checkbox Toggle and Optional Input Field

I just chased my tail around for a bit today. I got lost with setting the status of all inputs, and banging my head on why the "validate" function just wasn't working.

It seems that the "validate" function does not work when you already have had validation on an input. Once the input has been validated, your custom client validation code does not override it to set it as valid/invalid. It skips it because it was already validated.

You do not need to reset the status of all the inputs on your form.

You do not need to set the "submitting" value to true, as illustrated in the Yii2 Cookbook (linked to from the Yii2 docs on Client Validation).

Use Case

You have a form with a checkbox and a text input. The checkbox is not required, but if it is checked, the text input should then be required. If the checkbox is un-checked, the text input should no longer be required. In my case, it is for using Gravatar for user profile pics. If they have Gravatar, they check the box and enter in their Gravatar email address (since it may not match the email they used to register on my site). Later, I will be pairing it with cebe's yii2-gravatar extension. It is actually quite simple :)

Model:

['gravatar_email', 'required', 'when' => function($model) {
        return $model->use_gravatar == true;
    }, 'whenClient' => "isUseGravatarChecked"
],

View:

<?php $this->registerJs('
    function isUseGravatarChecked (attribute, value) {
        return $("#userprofile-use_gravatar").prop("checked") ? true : false;
    };
    jQuery( "#userprofile-use_gravatar" ).change(function() {
        $("#w0").yiiActiveForm("validateAttribute", "userprofile-gravatar_email");
    });
    jQuery( "#userprofile-gravatar_email" ).keyup(function() {
        $("#w0").yiiActiveForm("validateAttribute", "userprofile-gravatar_email");
    });
'); ?>

Please Note: I left out the rules in the model, for the "email" rule and declaring that the checkbox is an integer. I left them out because they are more dependant on my database setup. I have "use_gravatar" as a boolean in my database, but in Yii's eyes it is an integer. Really, it is an integer in the db if you want to be technical. Also, for those not using this on a text input for an email address, I didn't want them copying my code and getting confused. So you need to still have your other rules on these if you need them. This just illustrates how to pair the two inputs together with client validation.