Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Validator, make either field required

I am trying to make sure the user enters 1 of 2 fields, either "ExactOrderSize" or "approxOrderSize".

<p>Exact size of your order (# of items)</p>
<input id="ExactOrderSize" type="text" name="ExactOrderSize">

<p>Approximate size of your order</p>
<select id="approxOrderSize"  name="approxOrderSize" >
    <option value="" selected="selected"></option>
    <option value="0">0-35</option>
    <option value="35">35-50</option>
    <option value="50">50-100</option>
</select>

To do this, I am using help from jQuery Validator. Everything works well with it, except for this custom validation rule, which seems to do nothing.

$('#quoteform').validate({
  rules: {
    FirstName: {
      required: true
    },
    LastName: {
      required: true
    },
    approxOrderSize: {
      required: function() {
        if($('#ExactOrderSize').val()=="")
          return true;
        else
          return false;
      }
    },
    DateNeededBy: {
      required: true
    }
  }
});

My idea was to basically run a function that, if the #ExactOrderSize field wasn't filled out, made the #approxOrderSize field required. A.K.A. set required = true

What we have discovered from StackOverflow answers so far is that the problems lies in the two fields being potentially hidden. When the page first loads neither #ExactOrderSize or #approxOrderSize are initially shown.

They must click one of these two buttons to show that field: enter image description here

Depending on which button they select, a slide animation shows the appropriate field.

"Yes" --> Shows the #ExactOrderSize field

Select Yes, they do know the exact order size

"No" --> Shows the #approxOrderSize field

Select No, so they can enter in an approximate size

I though this would be a nice user interface, but apparently it is causing problems with the validation messages being able to show, which makes jQuery Validation not work.

As a solution I tried:

$('#quoteform').submit(function() {
    $('#not-exact').show();
    $('#yes-exact').show();
 });

That way all fields would be showing after the form submits.. but it still doesn't work.

P.S. Actual page is HERE if you would like to look at it.

like image 704
Zach Cook Avatar asked May 10 '15 04:05

Zach Cook


3 Answers

I am trying to make sure the user enters 1 of 2 fields

There is already a rule built into this plugin called require_from_group that does exactly this.

  1. Include the additional-methods.js file to get this rule.

  2. Add a class to both of these fields, ExactOrderSize and approxOrderSize. Something like ordersize.

  3. Declare the rule within the .validate() method like this...

    rules: {
        ExactOrderSize: {
            require_from_group: [1, '.ordersize']
        },
        approxOrderSize: {
            require_from_group: [1, '.ordersize']
        },
        // your other fields/rules
    },
    
  4. Use the groups option to ensure there's only one error message for both of these fields.

    groups: {
        ordersize: "ExactOrderSize approxOrderSize"
    },
    
  5. Use the errorPlacement option to place the error message in a position that makes more sense for these two fields.

    errorPlacement: function (error, element) {
        if ($(element).hasClass("ordersize")) {
            error.insertBefore(element.prev('p')); // custom error placement
        } else {
            error.insertAfter(element);  // default error placement
        }
    }
    
  6. NOTE: The plugin will ignore all hidden fields by default. To disable this feature, simply set the ignore option to [] and nothing will be ignored. Then you can simply show/hide the input fields based on some custom event handlers.

Working DEMO: http://jsfiddle.net/b0qe6Ljg/

like image 97
Sparky Avatar answered Nov 08 '22 14:11

Sparky


jQuery Validator rules are applied to elements with a matching name attribute, not a matching id attribute. Try this:

OrderRange: {
  required: function() {
    if($('#exactOrderSize').val()=="")
      return true;
    else
      return false;
  }
}
like image 34
Rob Johansen Avatar answered Nov 08 '22 15:11

Rob Johansen


Playing around with this in firebug a bit I think I have a solution. When the user submits the form and you do validation, before you return true or false in the validation for approxOrderSize, we should show the right field and hide the other one. Example, if the user did not enter anything into the ExactOrderSize field, when they submit the form the validator for approxOrderSize checks if ExactOrderSize has a value. If it doesn't have a value, hide that field and show approxOrderSize, then return true.

approxOrderSize: {
  required: function() {
    if($('#ExactOrderSize').val()=="")
      $("#NoExact").trigger("click");
      return true;
    else
      $("#YesExact").trigger("click");
      return false;
  }
}

At least in my experimenting, this seems to work because it shows the field that is now to be required and shows validation message for that field.

like image 1
Mike Hamilton Avatar answered Nov 08 '22 15:11

Mike Hamilton