views:

7018

answers:

8

I've got a form with a bunch of textboxes that are disabled by default, then enabled by use of a checkbox next to each one.

When enabled, the values in these textboxes are required to be a valid number, but when disabled they don't need a value (obviously). I'm using the jQuery Validation plugin to do this validation, but it doesn't seem to be doing what I expect.

When I click the checkbox and disable the textbox, I still get the invalid field error despite the depends clause I've added to the rules (see code below). Oddly, what actually happens is that the error message shows for a split second then goes away.

Here is a sample of the list of checkboxes & textboxes:

<ul id="ItemList">
<li>
 <label for="OneSelected">One</label><input id="OneSelected" name="OneSelected" type="checkbox" value="true" />
 <input name="OneSelected" type="hidden" value="false" />
 <input disabled="disabled" id="OneValue" name="OneValue" type="text" />
</li>
<li>
 <label for="TwoSelected">Two</label><input id="TwoSelected" name="TwoSelected" type="checkbox" value="true" />
 <input name="TwoSelected" type="hidden" value="false" />
 <input disabled="disabled" id="TwoValue" name="TwoValue" type="text" />
</li>
</ul>

And here is the jQuery code I'm using

//Wire up the click event on the checkbox
jQuery('#ItemList :checkbox').click(function(event) {
 var textBox = jQuery(this).siblings(':text');
 textBox.valid();
 if (!jQuery(this).attr("checked")) {
  textBox.attr('disabled', 'disabled');
  textBox.val('');
 } else {
  textBox.removeAttr('disabled');
  textBox[0].focus();
 }
});

//Add the rules to each textbox
jQuery('#ItemList :text').each(function(e) {
 jQuery(this).rules('add', {
  required: {
   depends: function(element) {
    return jQuery(element).siblings(':checkbox').attr('checked');
   }
  },
  number: {
   depends: function(element) {
    return jQuery(element).siblings(':checkbox').attr('checked');
   }
  }
 });
});

Ignore the hidden field in each li it's there because I'm using asp.net MVC's Html.Checkbox method.

A: 

I don't know if this is what you were going for... but wouldn't changing .required to .wasReq (as a placeholder to differentiate this from one which maybe wouldn't be required) on checking the box do the same thing? If it's not checked, the field isn't required--you could also removeClass(number) to eliminate the error there.

To the best of my knowledge, even if a field is disabled, rules applied to it are still, well, applied. Alternatively, you could always try this...

// Removes all values from disabled fields upon submit
$(form).submit(function() {
   $(input[type=text][disabled=disabled]).val();
});
A: 

I havent tried the validator plugin, but the fact that the message shows for a splitsecond sounds to me like a double bind, how do you call your binders? If you bind in a function try unbinding just before you start, like so:

$('#ItemList :checkbox').unbind("click");
...Rest of code here...
Kristoffer S Hansen
A: 

Shouldn't validate the field after disabling/enabling?

jQuery('#ItemList :checkbox').click(function(event) {
        var textBox = jQuery(this).siblings(':text');

        if (!jQuery(this).attr("checked")) {
                textBox.attr('disabled', 'disabled');
                textBox.val('');
        } else {
                textBox.removeAttr('disabled');
                textBox[0].focus();
        }
        textBox.valid();    
});
Daniel Moura
+5  A: 

Using the "ignore" option (http://docs.jquery.com/Plugins/Validation/validate#toptions) might be the easiest way for you to deal with this. Depends on what else you have on the form. For i.e. you wouldn't filter on disabled items if you had other controls that were disabled but you still needed to validate for some reason. However, if that route doesn't work, using an additional class to filter on (adding and removing with your checkboxes) should get you to where you want to go, but easier.

I.e.

        $('form').validate({
            ignore: ":disabled",
            ...
        });
Ted
Nice and simple - this solved it for me. Thanks!
Luke Sampson
didn't work for me.
drudru
@drudru: you'll want to verify that your selector is correct. Of course, ":disabled" specifies that all disabled selectors should be ignored. Alternatively, ignore: ".ignoreMe" will ignore all elements with the class of "ignoreMe".
Ted
+3  A: 

Usually when doing this, I skip 'depends' and just use the required jQuery Validate rule and let it handle the checking based on the given selector, as opposed to splitting the logic between the validate rules and the checkbox click handler. I put together a quick demo of how I accomplish this, using your markup.

Really, it boils down to required:'#OneSelected:checked'. This makes the field in question required only if the expression is true. In the demo, if you submit the page right away, it works, but as you check boxes, the form is unable to submit until the checked fields are filled with some input. You could still put a .valid() call in the checkbox click handler if you want the entire form to validate upon click.

(Also, I shortened up your checkbox toggling a bit, making use of jQuery's wonderful chaining feature, though your "caching" to textBox is just as effective.)

Collin Allen
+1 for the elegant solution, one problem with it: if you uncheck a checkbox after trying to submit - the error message doesn't go away.solved it by removing the error message when disabling the field, will write it in a separate answer because the formatting in the comments is crap
Avi Pinto
A: 

Depends parameter is not working correctly, I suppose documentation is out of date. I managed to get this working like this:

required : function(){ return $("#register").hasClass("open")}
Jacek
A: 

I had the exact same problem.

I solved this by having the radio-button change event handler call valid() on the entire form.

Worked perfect. The other solutions above didn't work for me.

drudru
A: 

following @Collin Allen answer:
The problem is that if you uncheck a checkbox when it's error message is visible - the error message doesn't go away.

solved it by removing the error message when disabling the field.

Take Collin's demo and make the following changes to the enable/disable process:

jQuery('#ItemList :checkbox').click(function()
{
  var jqTxb = $(this).siblings(':text')
  if ($(this).attr('checked'))
  {     
    jqTxb.removeAttr('disabled').focus();
  }
  else
  {
    jqTxb.attr('disabled', 'disabled').val('');
    var obj = getErrorMsgObj(jqTxb, "");
    jqTxb.closest("form").validate().showErrors(obj);
  }
});
function getErrorMsgObj(jqField, msg)
{
   var obj = {};
var nameOfField = jqField.attr("name");
obj[nameOfField] = msg;
return obj;
}

(sorry for the indentation, the editor gave me pain)

You can see i guts remove the error message from the field when disabling it

And if you are worrying about $("form").validate(), Dont! it doesn't revalidate the form it just returns the Api obkect of the jQuery validation

Avi Pinto