Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding jQuery validation rules based on data- attributes in a loop

I'm using the jQuery validation plugin trying to add rules based on data- attributes. I'm adding min/maxlength rules based on data-minlength or data-maxlength. Here's some sample HTML:

<form>
    <input name="input1" data-maxlength="5" data-minlength="3" required>
    <input name="input2" data-maxlength="5" required>
    <input name="input3" data-minlength="3" required>
    <button>Submit</button>
</form>

I'm doing this to add the rules and it's working fine:

$('input[data-minlength]').each(function(){
    if ($(this).data('minlength')) {
        $(this).rules("add", {
            minlength: $(this).data('minlength')
        });
    }
});

$('input[data-maxlength]').each(function(){
    if ($(this).data('maxlength')) {
        $(this).rules("add", {
            maxlength: $(this).data('maxlength')
        });
    }
});

But I wanted to shorten it up, so I tried this and it's not working:

['minlength', 'maxlength'].forEach(function(item){
    $('input[data-'+item+']').each(function(){
        if ($(this).data(item)) {
            // alert(item) shows the correct rule name
            $(this).rules("add", {
                // Next line fails, but hardcoding a rule name works
                item: $(this).data(item)
            });
        }
    });
});

The error is because $.validator.methods[method] is undefined. Somehow it's getting the wrong method name passed to it, even though alert(item) tells me the rule name is correct.

Does anyone have any idea why, or have an alternate solution I can use to shorten up the repetitive, working code above?

Demo: http://jsfiddle.net/kaVKe/1/

like image 329
Wesley Murch Avatar asked Jan 25 '12 15:01

Wesley Murch


2 Answers

It doesn't work because you are creating an object literal with a new property called item.

how about this?

['minlength', 'maxlength'].forEach(function(item){
    $('input[data-'+item+']').each(function(){
        if ($(this).data(item)) {
            // alert(item) shows the correct rule name
            var options = {};
            options[item] = $(this).data(item);

            $(this).rules("add", options);
        }
    });
});

This creates an options object and adds the proper property you need.

like image 129
BNL Avatar answered Nov 12 '22 23:11

BNL


Try:

['minlength', 'maxlength'].forEach(function(item){
    $('input[data-'+item+']').each(function(){
        if ($(this).data(item)) {
            var rule = {};
            rule[item] = $(this).data(item);
            $(this).rules("add", rule);
        }
    });
});

Your solution does not work because in object literal notation, property names will not be interpreted as variables:

{
  item: ... // <-- this one
}
like image 5
Yoshi Avatar answered Nov 12 '22 22:11

Yoshi