Adding jQuery validator rules to dynamically created elements in ASP
Asked Answered
R

3

28

I've got some dynamically inserted form fields on a page in an MVC3 project. Normally we would add the jQuery validation server-side, but in this case we can't (multiple fields in the UI generate the value for one hidden field - and this is what is submitted. We can't validate against a hidden field, so we must instead add UI-only validation for the fields the user can see)

Once the fields are dynamically added to the page, I run the following code over the container:

$container.find(".date").rules("add", {
    required: true,
    messages: {
        required: "The date is required"
    }
});

But it doesn't work! Oddly enough, disabling the above code, creating the dynamic elements, then running the code in the browser JS console works, but only the default validation message shows.

I'm at a loss. Any ideas?

I am using jQuery Validation 1.9.0 & the unobtrusive plugin

Rondarondeau answered 21/2, 2012 at 23:31 Comment(0)
M
8

Now that I understand what's going on with the Unobtrusive plugin side of things (which I understand is related to ASP.NET somehow), here's what you need to do:

After you add your new element, call $.validator.unobtrusive.parseElement(newElement) and it will get added to the form. As your answer suggested, you need to set the data-val and data-val-required attributes in the new form element.

So you end up with this:

//create new form element
$('form fieldset').append('<br>New Field: '+
     '<input type="text" data-val="true" data-val-required="A date is required." name="newField">'+
     ' * Also required');

//add new rules to it
$.validator.unobtrusive
  .parseElement($('form').find('input[name="newField"]').get(0));

Shown here: http://jsfiddle.net/ryleyb/LNjtd/2/

Maryrosemarys answered 22/2, 2012 at 22:28 Comment(1)
Ah, good! I might make a custom method to do this and add the data attributes on the selected field all at once.Rondarondeau
R
65

As it turns out, this can be done mostly in HTML by adding a few attributes to each form element:

  • A name attribute
  • data-val="true"
  • data-val-required="message"

Like so:

<input type='text' name="date" data-val="true" data-val-required="A date is required." />

Then the form just needs to be re-parsed via JS:

//Remove current form validation information
$("form")
    .removeData("validator")
    .removeData("unobtrusiveValidation");

//Parse the form again
$.validator
    .unobtrusive
    .parse("form");
Rondarondeau answered 22/2, 2012 at 16:44 Comment(4)
5.5 years later, still works like a champ when injecting new partial views into an editor interface.Hallow
Shouldn't the last line be $.validator.unobtrusive.parse($("form")); ?Manufactory
@Manufactory no, there's no need to do that, the parse function expects a CSS selector string to be passed in there, but there's also no harm in passing in a jQuery object either. It's not not required.Rondarondeau
So here I am 7 years later and happy that people still find this useful... but also kinda sad that people still have to use jQuery validation at all :(Rondarondeau
M
8

Now that I understand what's going on with the Unobtrusive plugin side of things (which I understand is related to ASP.NET somehow), here's what you need to do:

After you add your new element, call $.validator.unobtrusive.parseElement(newElement) and it will get added to the form. As your answer suggested, you need to set the data-val and data-val-required attributes in the new form element.

So you end up with this:

//create new form element
$('form fieldset').append('<br>New Field: '+
     '<input type="text" data-val="true" data-val-required="A date is required." name="newField">'+
     ' * Also required');

//add new rules to it
$.validator.unobtrusive
  .parseElement($('form').find('input[name="newField"]').get(0));

Shown here: http://jsfiddle.net/ryleyb/LNjtd/2/

Maryrosemarys answered 22/2, 2012 at 22:28 Comment(1)
Ah, good! I might make a custom method to do this and add the data attributes on the selected field all at once.Rondarondeau
M
1

I think you had something more simple wrong - like your find('.date') wasn't actually finding anything. Because otherwise, your code looks quite reasonable to me. Here is an example of it working as you expected: http://jsfiddle.net/ryleyb/LNjtd/

I was able to validate the code correctly with this:

$('form fieldset')
    .append('<br>New Field: <input type="text" name="newField"> * Also required')
    .find('input[name="newField"]').rules('add', {
      required: true,
      messages: {
        required: 'New field is required'
      }
    }
);​
Maryrosemarys answered 22/2, 2012 at 18:22 Comment(3)
True, but you didn't add a reference to the Unobtrusive Validation plugin - this seems to be where the issue is. I updated it to include this: jsfiddle.net/LNjtd/1Rondarondeau
Huh, not only that, I sent you the link to the wrong jsfiddle :)Maryrosemarys
But also, I didn't catch on that the unobtrusive plugin was related, and I know nothing about how ASP.NET generates its forms and then uses them... so yeah, you're on your own, and sounds like you found a workable solution.Maryrosemarys

© 2022 - 2024 — McMap. All rights reserved.