user558085 user558085 - 5 months ago 11
jQuery Question

Looping of rules Jquery

I have a form which allows people to refer up to 5 people. Within the form, if referral 1's name is filled, the jquery code below checks and prompts the user to fill in the other form fields related to referral 1.

I am wondering is it possible to create a loop which does the checking 5x instead of copying and pasting the below code for each set of referral?

$("#customer_referral").validate({

rules: {

Referral_1_Salutation: {
required: function(element) {
if($('[name="Referral_1_Name"]').is(':filled')||$('[name="Referral_1_Email"]').is(':filled')||$('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')||($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)){
return true;
} else {
return false;
}
}
},

Referral_1_Name: {
required: function(element) {
if(($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Email"]').is(':filled') || $('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')||($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)){
return true;
} else {
return false;
}
}
},
Referral_1_Email: {
required: function(element) {
if(($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Name"]').is(':filled') || $('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')||($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)){
return true;
} else {
return false;
}
}
},

Referral_1_Best_Time_To_Call: {
required: function(element) {
if(($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Name"]').is(':filled') || $('[name="Referral_1_Email"]').is(':filled') || $('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')){
return true;
} else {
return false;
}
}
},

//Check if any one of the contact number is filled
Referral_1_Contact_Number_Mobile: {
require_from_group_contact: function(element) {
if (($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Name"]').is(':filled') || $('[name="Referral_1_Email"]').is(':filled') || ($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)) {
return [1, ".oneormore"];
} else {
return [0, ".oneormore"];
}
}
},

Referral_1_Contact_Number_Home: {
require_from_group_contact: function(element) {
if (($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Name"]').is(':filled') || $('[name="Referral_1_Email"]').is(':filled') || ($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)) {
return [1, ".oneormore"];
} else {
return [0, ".oneormore"];
}
}
},
Referral_1_Contact_Number_Office: {
require_from_group_contact: function(element) {
if (($('[name="Referral_1_Salutation"]').prop("selectedIndex")!=0) || $('[name="Referral_1_Name"]').is(':filled') || $('[name="Referral_1_Email"]').is(':filled') || ($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)) {
return [1, ".oneormore"];
} else {
return [0, ".oneormore"];
}
}
}
//End of check if any one of the contact number is filled

},
});

Answer

Rules can also be applied via the .rules() method, which gives you the ability to use jQuery selectors that target things more generically. So when the selector targets multiple items, you can use a jQuery .each() to loop through them all.

$('.myfields').each(function() {
    $(this).rules('add', {
        required: true,
        // other rules
    });
});

On a side-note...

required: function(element) {                  
    if ($('[name="Referral_1_Name"]').is(':filled')||$('[name="Referral_1_Email"]').is(':filled')||$('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')||($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0)) {
        return true;                            
    } else {                    
        return false;
    } 
}   

Since you're returning a boolean based on a boolean condition, your function could be greatly simplified by just returning the result of the conditional...

required: function(element) {                    
    return ($('[name="Referral_1_Name"]').is(':filled')||$('[name="Referral_1_Email"]').is(':filled')||$('[name="Referral_1_Contact_Number_Mobile"]').is(':filled') || $('[name="Referral_1_Contact_Number_Home"]').is(':filled') || $('[name="Referral_1_Contact_Number_Office"]').is(':filled')||($('[name="Referral_1_Best_Time_To_Call"]').prop("selectedIndex")!=0));
}   

EDIT:

Firstly, everything needs to be re-worked to be more generic. I took the code from your previous question and reworked it a bit to get something more generic. Instead of conditionally looking at every field, I've employed the skip_or_fill_minimum rule to replace the required rule.

DEMO: http://jsfiddle.net/yo2vjwus/

Now that we have a working model that is generic enough, we can use the .rules() method to apply these rules to multiple fields at once.

$('[name^=Referral_1_]:not("[name^=Referral_1_Contact]")').each(function() {
    $(this).rules('add', {
        skip_or_fill_minimum: [4, '[name^=Referral_1_]:not("[name^=Referral_1_Contact]")']
    });
});

$('[name^="Referral_1_Contact"]').each(function() {
    $(this).rules('add', {
        require_from_group: function(element) {
            if ($('[name="Referral_1_Salutation"]').is(':filled')) {
                return [1, '[name^=Referral_1_Contact]'];
            } else {
                return [0, '[name^=Referral_1_Contact]'];
            }
        }
    });
});

DEMO: http://jsfiddle.net/yo2vjwus/1/

As far as the remaining four sets of fields, you will have to duplicate this code OR make it even more generic and put everything inside of another jQuery .each().

var i = 1;

$('[id^="Referral"]').each(function() {

    $('[name^=Referral_' + i + '_]:not("[name^=Referral_' + i + '_Contact]")').each(function() {
        $(this).rules('add', {
            skip_or_fill_minimum: [4, '[name^=Referral_' + i + '_]:not("[name^=Referral_' + i + '_Contact]")']
        });
    });

    $('[name^="Referral_' + i + '_Contact"]').each(function() {
        $(this).rules('add', {
            require_from_group: function(element) {
                if ($(element).parents('.parentClass').find('[name$="_Salutation"]').is(':filled')) {
                    return [1, '[name^="Referral_' + i + '_Contact"]'];
                } else {
                    return [0, '[name^="Referral_' + i + '_Contact"]'];
                }
            }
        });
    });

    i++;

});

DEMO: http://jsfiddle.net/yo2vjwus/2/

Comments