46

I have used this jquery validation plugin for the following form.

<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>

<script>
    $(document).ready(function(){
        $("#commentForm").validate();
    });

    function addInput() {
        var obj = document.getElementById("list").cloneNode(true);
        document.getElementById('parent').appendChild(obj);
    }
</script>

<form id="commentForm" method="get" action="">
    <p id="parent">
        <input id="list"  class="required" />
    </p>

    <input class="submit" type="submit" value="Submit"/>
    <input type="button" value="add" onClick="addInput()" />
</form>

When the add button is clicked a new input is dynamically added. However when the form is submitted only the first input field is validated. How can i validate dynamically added inputs? Thank you...

Sparky
  • 98,165
  • 25
  • 199
  • 285
Rav
  • 1,163
  • 4
  • 16
  • 18

10 Answers10

56

You should have 'name' attribute for your inputs. You need to add the rules dynamically, one option is to add them when the form submits.

And here is my solution that I've tested and it works:

<script type="text/javascript">
   $(document).ready(function() {
        var numberIncr = 1; // used to increment the name for the inputs

        function addInput() {
            $('#inputs').append($('<input class="comment" name="name'+numberIncr+'" />'));
            numberIncr++;
        }

        $('form.commentForm').on('submit', function(event) {

            // adding rules for inputs with class 'comment'
            $('input.comment').each(function() {
                $(this).rules("add", 
                    {
                        required: true
                    })
            });            

            // prevent default submit action         
            event.preventDefault();

            // test if form is valid 
            if($('form.commentForm').validate().form()) {
                console.log("validates");
            } else {
                console.log("does not validate");
            }
        })

        // set handler for addInput button click
        $("#addInput").on('click', addInput);

        // initialize the validator
        $('form.commentForm').validate();

   });


</script>

And the html form part:

<form class="commentForm" method="get" action="">
    <div>

        <p id="inputs">    
            <input class="comment" name="name0" />
        </p>

    <input class="submit" type="submit" value="Submit" />
    <input type="button" value="add" id="addInput" />

    </div>
</form>

Good luck! Please approve answer if it suits you!

Angel
  • 1,180
  • 9
  • 13
  • 3
    Thank you so much for your effort @Angel. It worked like magic. Awesome work :) – Rav Jul 18 '12 at 11:43
  • 2
    FWIW, you could just call validate once on document.ready, and then do your rules adding within the `addInput` function. If you want to show that validation is succeeding/failing, attach handlers to `submitHandler` and `invalidHandler`. – Ryley Jul 18 '12 at 15:27
  • 1
    Yes, that might work, you need to add the rule for the last added input, like $('input.comment:last').rules('add', {}); But I find it more straight forward to have all the validation parts in the same place. – Angel Jul 19 '12 at 07:11
  • +1 for the answer for dynamic fields. I did it up front with addInput, to get the immediate blur validation, rather than waiting for submit. – goodeye May 20 '13 at 23:13
  • Huge gotcha that about drove me crazy... dynamic fields must have the `name` attribute or validation won't work. Thanks, @Angel, for your answer. – Alex Apr 18 '17 at 13:01
  • `required="true"` is what I am looking for, it solved the dynamic field disappearing on client side validation. How to show a custom message for each dynamic field? – Pranesh Janarthanan Aug 30 '17 at 11:22
  • Needs to include calling the function below created by @RitchieD whenever the form is not valid. See my comment on his post for a bit more info on my usage. https://stackoverflow.com/questions/11536271/validate-dynamically-added-input-fields#answer-33527919 – plaidcorp Nov 17 '17 at 15:50
  • thank you. rules(add) is the best solution so far https://jqueryvalidation.org/rules/ – Chuyi Huang Aug 02 '18 at 07:51
  • can anyone know after validation how to access post data in the process.php page? – user9437856 May 12 '20 at 19:20
  • I had case where there were multiple dynamic table rows with duplicate fields. Your tip worked for me too. – Arfeen Feb 07 '21 at 18:28
50

Reset form validation after adding new fields.

function resetFormValidator(formId) {
    $(formId).removeData('validator');
    $(formId).removeData('unobtrusiveValidation');
    $.validator.unobtrusive.parse(formId);
}
RitchieD
  • 1,831
  • 22
  • 21
  • 6
    This solution is much better – Daniel Santos Aug 14 '16 at 15:05
  • 1
    from where this function needs to be called ? in on submit of the form, or the javascript method which adds new field ? – Happy Coder Jan 04 '17 at 12:53
  • 17
    when I am using this I am getting this error :`Uncaught TypeError: Cannot read property 'parse' of undefined` – Happy Coder Jan 04 '17 at 12:59
  • You would normally call this function in the add new field function after the field has been added. This way it will find the new field. Not sure about the error. Something missing somewhere.... – RitchieD Jan 04 '17 at 13:34
  • Thank you SO MUCH! I have been looking all over, and thought I could get away with just parsing the form again, but obviousley I need to remove the validator first! Thank you once again! – user2687506 Jan 26 '17 at 13:13
  • Allows the validation plugin to use data attributes present in the control for list of validations to be performed on that control. Thanks... – David Chelliah May 29 '17 at 12:43
  • LIFE SAVER! Validate was only looking at the dynamic fields after the first click. Now with this function being called whenever the form is not valid, it is reset so new dynamically added fields will be recognized. Thank you so much for this post! – plaidcorp Nov 17 '17 at 15:47
  • @theordinarygeek, You would normally call this function in the add new field function after the field has been added. – RitchieD Aug 24 '18 at 15:04
  • @TheOrdinaryGeek, unfortunately I can't see the issue. Something else missing like jquery validation. Or different versions? Sorry I can't be of more help. But for sure this methods works, I use it a lot. – RitchieD Aug 30 '18 at 12:42
  • 1
    @HappyCoder add this script https://cdnjs.com/libraries/jquery-validation-unobtrusive – ubugnu Mar 20 '19 at 10:17
  • if using dynamically generated HTML fields, this is the solution. - for that sir you get an up vote :) – JGilmartin Oct 22 '19 at 16:29
  • can any one share the demo? – user9437856 May 12 '20 at 19:23
6

You need to re-parse the form after adding dynamic content in order to validate the content

$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));
Yogesh Maurya
  • 61
  • 1
  • 2
  • 4
4

The one mahesh posted is not working because the attribute name is missing:

So instead of

<input id="list" class="required"  />

You can use:

<input id="list" name="list" class="required"  />

Modified version

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
Albert
  • 59
  • 4
4

jquery validation plugin version work fine v1.15.0 but v1.17.0 not work for me.

$(document).find('#add_patient_form').validate({
          ignore: [],
          rules:{
            'email[]':
            {
              required:true,
            },               
          },
          messages:{
            'email[]':
            {
              'required':'Required'
            },            
          },    
        });
Shiva Manhar
  • 673
  • 8
  • 19
2

In regards to @RitchieD response, here is a jQuery plugin version to make things easier if you are using jQuery.

(function ($) {

    $.fn.initValidation = function () {

        $(this).removeData("validator");
        $(this).removeData("unobtrusiveValidation");
        $.validator.unobtrusive.parse(this);

        return this;
    };

}(jQuery));

This can be used like this:

$("#SomeForm").initValidation();
JoshdeVries
  • 887
  • 7
  • 9
1

In case you have a form you can add a class name as such:

<form id="my-form">
  <input class="js-input" type="text" name="samplename" />
  <input class="js-input" type="text" name="samplename" />
  <input class="submit" type="submit" value="Submit" />
</form>

you can then use the addClassRules method of validator to add your rules like this and this will apply to all the dynamically added inputs:

$(document).ready(function() {
  $.validator.addClassRules('js-input', {
    required: true,
  });
  //validate the form
  $('#my-form').validate();
});
sstauross
  • 2,602
  • 2
  • 30
  • 50
1
$('#form-btn').click(function () {
//set global rules & messages array to use in validator
   var rules = {};
   var messages = {};
//get input, select, textarea of form
   $('#formId').find('input, select, textarea').each(function () {
      var name = $(this).attr('name');
      rules[name] = {};
      messages[name] = {};

      rules[name] = {required: true}; // set required true against every name
//apply more rules, you can also apply custom rules & messages
      if (name === "email") {
         rules[name].email = true;
         //messages[name].email = "Please provide valid email";
      }
      else if(name==='url'){
        rules[name].required = false; // url filed is not required
//add other rules & messages
      }
   });
//submit form and use above created global rules & messages array
   $('#formId').submit(function (e) {
            e.preventDefault();
        }).validate({
            rules: rules,
            messages: messages,
            submitHandler: function (form) {
            console.log("validation success");
            }
        });
});
Zia
  • 213
  • 1
  • 8
  • 1
    This worked for me. I like this approach because instead of re initializing the form validator he just waits till the user tries to submit then adds the rules in the each() and initializes the form validator with all the dynamically generated rules. – Too lanky May 12 '20 at 17:31
0

Try using input arrays:

<form action="try.php" method="post">
    <div id="events_wrapper">
        <div id="sub_events">
            <input type="text" name="firstname[]" />                                       
        </div>
    </div>
    <input type="button" id="add_another_event" name="add_another_event" value="Add Another" />
    <input type="submit" name="submit" value="submit" />
</form>

and add this script and jQuery, using foreach() to retrieve the data being $_POST'ed:

<script>                                                                                    
    $(document).ready(function(){
        $("#add_another_event").click(function(){
        var $address = $('#sub_events');
        var num = $('.clonedAddress').length; // there are 5 children inside each address so the prevCloned address * 5 + original
        var newNum = num + 1;
        var newElem = $address.clone().attr('id', 'address' + newNum).addClass('clonedAddress');

        //set all div id's and the input id's
        newElem.children('div').each (function (i) {
            this.id = 'input' + (newNum*5 + i);
        });

        newElem.find('input').each (function () {
            this.id = this.id + newNum;
            this.name = this.name + newNum;
        });

        if (num > 0) {
            $('.clonedAddress:last').after(newElem);
        } else {
            $address.after(newElem);
        }

        $('#btnDel').removeAttr('disabled');
        });

        $("#remove").click(function(){

        });

    });
</script>
Brad Koch
  • 19,267
  • 19
  • 110
  • 137
leonardeveloper
  • 1,813
  • 1
  • 34
  • 58
0
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery-validation@1.17.0/dist/jquery.validate.js"></script>

<script>
    $(document).ready(function(){
        $("#commentForm").validate();
    });

    function addInput() {

        var indexVal = $("#index").val();
        var index = parseInt(indexVal) + 1
        var obj = '<input id="list'+index+'" name=list['+index+']  class="required" />'
        $("#parent").append(obj);

        $("#list"+index).rules("add", "required");
        $("#index").val(index)
    }
</script>

<form id="commentForm" method="get" action="">
    <input type="hidden" name="index" name="list[1]" id="index" value="1">
    <p id="parent">
        <input id="list1"  class="required" />
    </p>
    <input class="submit" type="submit" value="Submit"/>
    <input type="button" value="add" onClick="addInput()" />
</form>