简体   繁体   中英

Conditional jquery validation on nested inputs with custom validator

I have the following HTML:

<div class='headerWithYesNo'>
    <p>Text....</p>
    <div class='choices'>
        <input type="radio" name="choices" value="yes" />
        <input type="radio" name="choices" value="no" />
    </div>
    <div class='headerWithYesNoChild hidden'>
        <input type="checkbox" />
        <input type="checkbox" />
    </div>
</div>

I have a jquery validator requiring the user to select yes or no. When the user selects yes the 'headerWithYesNoChild' div is displayed. If yes is selected I want to require a user to select one of the checkboxes. So I have added the following custom validator:

jQuery.validator.addMethod("headerWithYesNo", function(value, element) {
    //If the value === no return valid
    if (value === 'no') return true;

    var yesNoChild = $(element).closest('.headerWithYesNo').children('.headerWithYesNoChild');
    var checkedInputs = yesNoChild.find('input:checked');

    //If any inputs are checked, return valid
    if (checkedInputs.length > 0) {
        return this.optional(element);
    }

    return false;
});

I add the validator with the following JavaScript:

$('.headerWithYesNo .choices input:radio').each(function () {
    $(this).rules("add", {
        headerWithYesNo: true,
        messages: {
            headerWithYesNo: "Make a selection from the options below or select 'No'"
        }
    })
});

The only options I add to my validate function is to change the error placement:

$('form').validate({
    errorPlacement: function(error, element) {
        ... error placement logic
    }
});

This works great... with one issue. As soon as yes is selected the validation is fired, before the user has a chance to make a selection. I want the validation to fire when the user selects 'no' (to clear out any failed validation) or on form submit. How can I achieve this?

What I ended up doing was adding a depends to my rule:

$('.headerWithYesNo .choices input:radio').each(function () {
    $(this).rules("add", {
        headerWithYesNo: {
            depends: function(element) {
                var targetType = $(event.target).attr('type');
                if (element.value === 'no' || targetType === 'submit') {
                    return true;
                }
                return false;
            }
        },
        messages: {
            headerWithYesNo: "Make a selection from the options below or select 'No'"
        }
    })
});

So if the value of the radio is 'no' required is set to true. Or if the target is a submit input. However I think @Sparky made some good suggestions about onclick, I just couldn't figure out how to apply it to just one rule. I'm open to more feedback on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM