jquery form validation require one of a group of inputs AND require that input is an integer

input, javascript, jquery, validation

Solution

It seems I found a solution. See comments in code. Live demo.

jQuery.validator.addMethod(
    "require_from_group", function(value, element, options) {
  var numberRequired = options[0];
  var selector = options[1];
  var fields = $(selector, element.form);
  var filled_fields = fields.filter(function() {
    // it's more clear to compare with empty string
    return $(this).val() != ""; 
  });
  var empty_fields = fields.not(filled_fields);
  // we will mark only first empty field as invalid
  if (filled_fields.length < numberRequired && empty_fields[0] == element) {
    return false;
  }
  return true;
// {0} below is the 0th item in the options field
}, jQuery.format("Please fill out at least {0} of these fields."));

$(document).ready(function(){
  var container = $('#errorContainer');
  $("#FORMMM").validate(  {

    // We must to force validation of entire form because
    // when we remove value from 2-nd field 
    // the 1-st field becomes invalid.
    onfocusout: function() { $("#FORMMM").valid() },
    onkeyup: function() { $("#FORMMM").valid() },

    rules: {
      // note: you can use variable to avoid repeating 
      // of the same code
      groceries: { 
        number: true,
        require_from_group: [1, ".at_least_one"]
      },
      gas: {
        number: true,
        require_from_group: [1,".at_least_one"]
      },
      hotels: {
        number: true,
        require_from_group: [1,".at_least_one"]
      }
    },
    success: function(label) {  
      label.html(" ").addClass("checked"); 
    },
    errorContainer: container,
    errorLabelContainer: $("ol", container),
    wrapper: 'li',
    meta: "validate"
  });
});

Problem

I'm making a form that requires at least one field to be filled AND all inputs have to be either integers or decimals. I'm using jquery's validation plugin to validate. I've reworked something I found here that seems to partially do the trick. right now I have: ``` <SCRIPT> jQuery.validator.addMethod("require_from_group", function(value, element, options) { var numberRequired = options[0]; var selector = options[1]; var validOrNot = $(selector, element.form).filter(function() { // Each field is kept if it has a value return $(this).val(); // Set to true if there are enough, else to false }).length >= numberRequired; if(!$(element).data('being_validated')) { var fields = $(selector, element.form); fields.data('being_validated', true); fields.valid(); fields.data('being_validated', false); } return validOrNot; // {0} below is the 0th item in the options field }, jQuery.format("Please fill out at least {0} of these fields.")); $(document).ready(function(){ var container = $('#errorContainer'); $("#FORMMM").validate( { rules: { groceries: {digits: true,require_from_group: [1,".at_least_one"]}, gas: {digits: true,require_from_group: [1,".at_least_one"]}, hotels: {digits: true,require_from_group: [1,".at_least_one"]} }, success: function(label) { label.html(" ").addClass("checked"); }, errorContainer: container, errorLabelContainer: $("ol", container), wrapper: 'li', meta: "validate" }); }); </SCRIPT> ``` the HTML is below, in my actual form there are 15 input fields, I'm just condensing it for here: ``` <form action="results.php" target="_blank" id="FORMMM"> <div style="clear:both"> <label for="groceries">Groceries</label> <div style="float:right"> $<input name="groceries" type="text" class="at_least_one idleField"></div> </div> <div style="clear:both"> <label for="gas">Gas</label> <div style="float:right"> $<input name="gas" type="text" class="at_least_one idleField"> </div> </div> <div style="clear:both"> <label for="hotels">Hotels</label> <div style="float:right"> $<input name="hotels" type="text" class="at_least_one idleField"> </div> </div> <div id="button"> <input name="" type="submit" value="Calculate" class="calc_button" style="cursor:hand"> </div> </form> <div id="errorContainer"> <h4>errors</h4> <ol> </ol> </div> ``` Right now there are two problems with the validation. If all fields are left blank, I get 3 error messages when I only need one! Also, if I enter a letter into one of the inputs, I get the "digits only" error message for a second, but the form still submits anyways, since the 2nd test of having at least 1 field be filled makes up for not having digits. Am I doing this in a totally wrong way? None of the examples I can find here or on the jquery forums seem to fit exactly. What direction should I go to solve this?

Original source

Related problems