绑定点击事件后无法取消复选框

jQuery: Not able to uncheck checkbox after binding click event

本文关键字:取消 复选框 事件 绑定      更新时间:2023-09-26

使用jQuery Validation插件作为基础,我创建了一个函数来验证字段,而不使用表单。该函数还将事件绑定到表单元素,以便实时执行验证。

在一些情况下,表单标签的使用是不可能的,因此创建了这个函数。

一切似乎都正常工作,除了复选框在第二次被选中时是不可选中的。

谁能告诉我我做错了什么

  
<html>
<head>
    <title></title>
</head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
    jQuery(document).ready(function() {
        jQuery('#submit').click(function(){
            var options = {
                'name' : {
                    required: true
                },
                'email' : {
                    required: true,
                    email: true
                },
                'number' : {
                    required: true,
                    digits: true
                },
                'select' : {
                    required: true
                },
                'select-multiple' : {
                    required: true
                },
                'radio' : {
                    required: true
                },
                'checkbox' : {
                    required: true
                },
                'checkbox-single' : {
                    required: true
                },
                'multiple-emails' : {
                    required: true,
                    multipleEmails: true
                }
            };
    				
            if(customValidation(options)){
                alert('Form validated!');
            }else{
                alert('Form not validated!');
            }
        });
    });
    function customValidation(options, bindEvents){
        var fieldsValid = true;
        bindEvents = (typeof bindEvents === 'undefined') ? true : bindEvents;
        var errorDiv = jQuery('#errorDiv');
    				
        jQuery.each(options, function(elementIdorName, rules){
            var element = (jQuery('#' + elementIdorName).length) ? jQuery('#' + elementIdorName) : jQuery('input[name=' + elementIdorName + ']:first');
            var elementType = element.prop('type');
            var elementName = element.prop('name');
    					
            var elementValid = true;
    					
            // First remove any validation errors
            jQuery('.error-' + elementName).hide();
    					
            jQuery.each(rules, function(rule, ruleOption){
                // Required
                if(rule == 'required' && ruleOption == true){
                    // Select
                    if(elementType && (elementType.toLowerCase() === 'select' || elementType.toLowerCase() === 'select-one' || elementType.toLowerCase() === 'select-mulitple')){
                        var val = element.val();
                        if(val && val.length > 0){
                            // Do nothing
                        }
                        else{
                            elementValid = false;
                        }
                    }
    							
                    // Checkbox and Radio
                    if((/radio|checkbox/i).test(elementType)){
                        if(jQuery('input[name=' + elementName + ']:checked').length > 0){
                            // Do nothing
                        }
                        else{
                            elementValid = false;
                        }
                    }
    							
                    // Text, Email, Number and Textarea
                    if(jQuery.trim(element.val()).length > 0){
                        // Do nothing
                    }
                    else{
                        elementValid = false;
                    }
    							
                    if(!elementValid){
                        fieldsValid = false;
                        if(jQuery('.error-' + elementName).length == 0) {
                            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                        }
                        else{
                            jQuery('.error-' + elementName).show();
                        }
                    }
                }
    						
                // Email
                if(rule == 'email' && ruleOption == true){
                    if((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(element.val())){
                        // Do nothing
                    }
                    else{
                        elementValid = false;
                    }
    							
                    if(!elementValid){
                        fieldsValid = false;
                        if(jQuery('.error-' + elementName).length == 0) {
                            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                        }
                        else{
                            jQuery('.error-' + elementName).show();
                        }
                    }
                }
    						
                // Number
                if(rule == 'number' && ruleOption == true){
                    if((/^-?(?:'d+|'d{1,3}(?:,'d{3})+)?(?:'.'d+)?$/).test(element.val())){
                        // Do nothing
                    }
                    else{
                        elementValid = false;
                    }
    							
                    if(!elementValid){
                        fieldsValid = false;
                        if(jQuery('.error-' + elementName).length == 0) {
                            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                        }
                        else{
                            jQuery('.error-' + elementName).show();
                        }
                    }
                }
    						
                // Digits
                if(rule == 'digits' && ruleOption == true){
                    if((/^'d+$/).test(element.val())){
                        // Do nothing
                    }
                    else{
                        elementValid = false;
                    }
    							
                    if(!elementValid){
                        fieldsValid = false;
                        if(jQuery('.error-' + elementName).length == 0) {
                            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                        }
                        else{
                            jQuery('.error-' + elementName).show();
                        }
                    }
                }
    						
                // Multiple Emails
                if(rule == 'multipleEmails' && ruleOption == true){
                    var emailsArr = element.val().replace(/'s/g, '').split(/,|;/);
                    for(var i = 0; i < emailsArr.length; i++){
                        if((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(emailsArr[i])){
                            // Do nothing
                        }
                        else{
                            elementValid = false;
                        }
                    }
    							
                    if(!elementValid){
                        fieldsValid = false;
                        if(jQuery('.error-' + elementName).length == 0) {
                            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                        }
                        else{
                            jQuery('.error-' + elementName).show();
                        }
                    }
                }
            });
    					
            if(bindEvents){
                var currentOption = {};
                currentOption[elementIdorName] = rules;
    						
                // Bind events to validate on the fly
                switch(elementType){
                    case 'text':
                    case 'email':
                    case 'number':
                    case 'textarea':
                        element.unbind('keyup.customValidation-' + elementName).bind('keyup.customValidation-' + elementName, function(e){
                            return customValidation(currentOption, false);
                        });
                        break;
                    case 'radio':
                    case 'checkbox':
                        jQuery('input[name=' + elementIdorName + ']').each(function (){
                            jQuery(this).unbind('click.customValidation-' + elementName).bind('click.customValidation-' + elementName, function(e){
                                return customValidation(currentOption, false);
                            });
                        });
                        break;
                    case 'select':
                    case 'select-one':
                    case 'select-multiple':
                        element.unbind('change.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e){
                            return customValidation(currentOption, false);
                        });
                        break;
                }
            }
        });
    				
        return fieldsValid;
    }
</script>
<body>
    <div id="errorDiv">
    </div>
    <br />
    <br />
    <input type="text" name="name" id="name" />
    <br />
    <br />
    <input type="email" name="email" id="email" />
    <br />
    <br />
    <input type="number" name="number" id="number" />
    <br />
    <br />
    <select name="select" id="select">
        <option></option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
    <br />
    <br />
    <select name="select-multiple" id="select-multiple" multiple>
        <option></option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
        <option>Option 4</option>
        <option>Option 5</option>
        <option>Option 6</option>
    </select>
    <br />
    <br />
    <input type="radio" name="radio" />Yes
    			<input type="radio" name="radio" />No
    			<br />
    <br />
    <input type="checkbox" name="checkbox" />Yes
    			<input type="checkbox" name="checkbox" />No
    			<br />
    <br />
    <input type="checkbox" name="checkbox-single" id="checkbox-single" />No
    			<br />
    <br />
    <textarea name="multiple-emails" id="multiple-emails"></textarea>
    <br />
    <br />
    <button id="submit">Submit</button>
</body>
</html>

关于JSFiddle的示例

jQuery(document).ready(function() {
  jQuery('#submit').click(function() {
    var options = {
      'name': {
        required: true
      },
      'email': {
        required: true,
        email: true
      },
      'number': {
        required: true,
        digits: true
      },
      'select': {
        required: true
      },
      'select-multiple': {
        required: true
      },
      'radio': {
        required: true
      },
      'checkbox': {
        required: true
      },
      'checkbox-single': {
        required: true
      },
      'multiple-emails': {
        required: true,
        multipleEmails: true
      }
    };
    if (customValidation(options)) {
      alert('Form validated!');
    } else {
      alert('Form not validated!');
    }
  });
});
function customValidation(options, bindEvents) {
  /***
		Function is based on jQuery Validation Plugin v1.13.1 but doesn't require a <form> tag
	
		Add custom validations in this function as required
		
		Currently supported validations are:
		
		Required - Field cannot be blank
		Email - Validates an email address
		Mutliple Emails - Validates mutliple email addresses
		Number - Validates a decimal number
		Digits - Validates digits only
		
		Todo:
		
		Equal To validation
		Allow specifying parent element for Checkbox and Radio elements to apply an error class
		Allow specifying custom error and success functions through function parameter and individual options			
	***/
  var fieldsValid = true;
  bindEvents = (typeof bindEvents === 'undefined') ? true : bindEvents;
  var errorDiv = jQuery('#errorDiv');
  jQuery.each(options, function(elementIdorName, rules) {
    var element = (jQuery('#' + elementIdorName).length) ? jQuery('#' + elementIdorName) : jQuery('input[name=' + elementIdorName + ']:first');
    var elementType = element.prop('type');
    var elementName = element.prop('name');
    var elementValid = true;
    // First remove any validation errors
    jQuery('.error-' + elementName).hide();
    jQuery.each(rules, function(rule, ruleOption) {
      // Required
      if (rule == 'required' && ruleOption == true) {
        // Select
        if (elementType && (elementType.toLowerCase() === 'select' || elementType.toLowerCase() === 'select-one' || elementType.toLowerCase() === 'select-mulitple')) {
          var val = element.val();
          if (val && val.length > 0) {
            // Do nothing
          } else {
            elementValid = false;
          }
        }
        // Checkbox and Radio
        if ((/radio|checkbox/i).test(elementType)) {
          if (jQuery('input[name=' + elementName + ']:checked').length > 0) {
            // Do nothing
          } else {
            elementValid = false;
          }
        }
        // Text, Email, Number and Textarea
        if (jQuery.trim(element.val()).length > 0) {
          // Do nothing
        } else {
          elementValid = false;
        }
        if (!elementValid) {
          fieldsValid = false;
          if (jQuery('.error-' + elementName).length == 0) {
            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
          } else {
            jQuery('.error-' + elementName).show();
          }
        }
      }
      // Email
      if (rule == 'email' && ruleOption == true) {
        if ((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(element.val())) {
          // Do nothing
        } else {
          elementValid = false;
        }
        if (!elementValid) {
          fieldsValid = false;
          if (jQuery('.error-' + elementName).length == 0) {
            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
          } else {
            jQuery('.error-' + elementName).show();
          }
        }
      }
      // Number
      if (rule == 'number' && ruleOption == true) {
        if ((/^-?(?:'d+|'d{1,3}(?:,'d{3})+)?(?:'.'d+)?$/).test(element.val())) {
          // Do nothing
        } else {
          elementValid = false;
        }
        if (!elementValid) {
          fieldsValid = false;
          if (jQuery('.error-' + elementName).length == 0) {
            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
          } else {
            jQuery('.error-' + elementName).show();
          }
        }
      }
      // Digits
      if (rule == 'digits' && ruleOption == true) {
        if ((/^'d+$/).test(element.val())) {
          // Do nothing
        } else {
          elementValid = false;
        }
        if (!elementValid) {
          fieldsValid = false;
          if (jQuery('.error-' + elementName).length == 0) {
            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
          } else {
            jQuery('.error-' + elementName).show();
          }
        }
      }
      // Multiple Emails
      if (rule == 'multipleEmails' && ruleOption == true) {
        var emailsArr = element.val().replace(/'s/g, '').split(/,|;/);
        for (var i = 0; i < emailsArr.length; i++) {
          if ((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(emailsArr[i])) {
            // Do nothing
          } else {
            elementValid = false;
          }
        }
        if (!elementValid) {
          fieldsValid = false;
          if (jQuery('.error-' + elementName).length == 0) {
            errorDiv.append('<div class="error-' + elementName + '">' + elementName + '</div>');
          } else {
            jQuery('.error-' + elementName).show();
          }
        }
      }
    });
    if (bindEvents) {
      var currentOption = {};
      currentOption[elementIdorName] = rules;
      // Bind events to validate on the fly
      switch (elementType) {
        case 'text':
        case 'email':
        case 'number':
        case 'textarea':
          element.unbind('keyup.customValidation-' + elementName).bind('keyup.customValidation-' + elementName, function(e) {
            return customValidation(currentOption, false);
          });
          break;
        case 'radio':
        case 'checkbox':
          jQuery('input[name=' + elementIdorName + ']').each(function() {
            jQuery(this).unbind('click.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e) {
              console.log(e);
              return customValidation(currentOption);
            });
          });
          break;
        case 'select':
        case 'select-one':
        case 'select-multiple':
          element.unbind('change.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e) {
            return customValidation(currentOption, false);
          });
          break;
      }
    }
  });
  return fieldsValid;
}

正如@Sandeeproop正确指出的那样,动态事件返回false,这不允许复选框被选中。我只需要在click事件中不返回任何东西。更新了下面的代码,也更新了JSFiddle示例。

<html>
    <head>
        <title></title>
    </head>
    <style>
        #errorContainer { color: #ff0000; }
    </style>
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script>
        jQuery(document).ready(function() {
            jQuery('#submit').click(function(){
                var options = {
                    'name' : {
                        required: true
                    },
                    'email' : {
                        required: true,
                        email: true
                    },
                    'number' : {
                        required: true,
                        digits: true
                    },
                    'select' : {
                        required: true
                    },
                    'select-multiple' : {
                        required: true
                    },
                    'radio' : {
                        required: true
                    },
                    'checkbox' : {
                        required: true
                    },
                    'checkbox-single' : {
                        required: true
                    },
                    'multiple-emails' : {
                        required: true,
                        multipleEmails: true
                    }
                };
                if(customValidation(options)){
                    alert('Form validated!');
                }else{
                    alert('Form not validated!');
                }
            });
        });
        function customValidation(options){
            var fieldsValid = true;
            var errorMessages = jQuery('#errorMessages');
            jQuery.each(options, function(elementIdorName, rules){
                var element = (jQuery('#' + elementIdorName).length) ? jQuery('#' + elementIdorName) : jQuery('input[name=' + elementIdorName + ']:first');
                var elementType = element.prop('type');
                var elementName = element.prop('name');
                var elementValid = true;
                // First remove any validation errors
                jQuery('.error-' + elementName).hide();
                jQuery.each(rules, function(rule, ruleOption){
                    // Required
                    if(rule == 'required' && ruleOption == true){
                        // Select
                        if(elementType && (elementType.toLowerCase() === 'select' || elementType.toLowerCase() === 'select-one' || elementType.toLowerCase() === 'select-mulitple')){
                            var val = element.val();
                            if(val && val.length > 0){
                                // Do nothing
                            }else{
                                elementValid = false;
                            }
                        }
                        // Checkbox and Radio
                        if((/radio|checkbox/i).test(elementType)){
                            if(jQuery('input[name=' + elementName + ']:checked').length > 0){
                                // Do nothing
                            }else{
                                elementValid = false;
                            }
                        }
                        // Text, Email, Number and Textarea
                        if(jQuery.trim(element.val()).length > 0){
                            // Do nothing
                        }else{
                            elementValid = false;
                        }
                        if(!elementValid){
                            fieldsValid = false;
                            if(jQuery('.error-' + elementName).length == 0) {
                                errorMessages.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                            }else{
                                jQuery('.error-' + elementName).show();
                            }
                        }
                    }
                    // Email
                    if(rule == 'email' && ruleOption == true){
                        if((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(element.val())){
                            // Do nothing
                        }else{
                            elementValid = false;
                        }
                        if(!elementValid){
                            fieldsValid = false;
                            if(jQuery('.error-' + elementName).length == 0) {
                                errorMessages.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                            }else{
                                jQuery('.error-' + elementName).show();
                            }
                        }
                    }
                    // Number
                    if(rule == 'number' && ruleOption == true){
                        if((/^-?(?:'d+|'d{1,3}(?:,'d{3})+)?(?:'.'d+)?$/).test(element.val())){
                            // Do nothing
                        }else{
                            elementValid = false;
                        }
                        if(!elementValid){
                            fieldsValid = false;
                            if(jQuery('.error-' + elementName).length == 0) {
                                errorMessages.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                            }else{
                                jQuery('.error-' + elementName).show();
                            }
                        }
                    }
                    // Digits
                    if(rule == 'digits' && ruleOption == true){
                        if((/^'d+$/).test(element.val())){
                            // Do nothing
                        }else{
                            elementValid = false;
                        }
                        if(!elementValid){
                            fieldsValid = false;
                            if(jQuery('.error-' + elementName).length == 0) {
                                errorMessages.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                            }else{
                                jQuery('.error-' + elementName).show();
                            }
                        }
                    }
                    // Multiple Emails
                    if(rule == 'multipleEmails' && ruleOption == true){
                        var emailsArr = element.val().replace(/'s/g, '').split(/,|;/);
                        for(var i = 0; i < emailsArr.length; i++){
                            if((/^[a-zA-Z0-9.!#$%&'*+'/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:'.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/).test(emailsArr[i])){
                                // Do nothing
                            }else{
                                elementValid = false;
                            }
                        }
                        if(!elementValid){
                            fieldsValid = false;
                            if(jQuery('.error-' + elementName).length == 0) {
                                errorMessages.append('<div class="error-' + elementName + '">' + elementName + '</div>');
                            }else{
                                jQuery('.error-' + elementName).show();
                            }
                        }
                    }
                });
                var currentOption = {};
                currentOption[elementIdorName] = rules;
                // Bind events to validate on the fly
                switch(elementType){
                    case 'text':
                    case 'email':
                    case 'number':
                    case 'textarea':
                        element.unbind('keyup.customValidation-' + elementName).bind('keyup.customValidation-' + elementName, function(e){
                            customValidation(currentOption);
                        });
                    break;
                    case 'radio':
                    case 'checkbox':
                        jQuery('input[name=' + elementIdorName + ']').each(function (){
                            jQuery(this).unbind('click.customValidation-' + elementName).bind('click.customValidation-' + elementName, function(e){
                                customValidation(currentOption);
                            });
                        });
                    break;
                    case 'select':
                    case 'select-one':
                    case 'select-multiple':
                        element.unbind('change.customValidation-' + elementName).bind('change.customValidation-' + elementName, function(e){
                            customValidation(currentOption);
                        });
                    break;
                }
            });
            return fieldsValid;
        }
    </script>
    <body>
        <div id="errorContainer">
            <div>The following field have errors:</div>
            <div id="errorMessages"></div>
        </div>
        <br /><br />
        <input type="text" name="name" id="name" />
        <br /><br />
        <input type="email" name="email" id="email" />
        <br /><br />
        <input type="number" name="number" id="number" />
        <br /><br />
        <select name="select" id="select">
            <option></option>
            <option>Option 1</option>
            <option>Option 2</option>
            <option>Option 3</option>
        </select>
        <br /><br />
        <select name="select-multiple" id="select-multiple" multiple>
            <option></option>
            <option>Option 1</option>
            <option>Option 2</option>
            <option>Option 3</option>
            <option>Option 4</option>
            <option>Option 5</option>
            <option>Option 6</option>
        </select>
        <br /><br />
        <input type="radio" name="radio" />Yes
        <input type="radio" name="radio" />No
        <br /><br />
        <input type="checkbox" name="checkbox" />Yes
        <input type="checkbox" name="checkbox" />No
        <br /><br />
        <input type="checkbox" name="checkbox-single" id="checkbox-single" />No
        <br /><br />
        <textarea name="multiple-emails" id="multiple-emails"></textarea>
        <br /><br />
        <button id="submit">Submit</button>
    </body>
</html>

更新了JSFiddle的示例:http://jsfiddle.net/wwwescape/sdhjpave/