14

I've a form where you dynamically can add new rows with input elements. Before submitting my form it gets validated by using the plugin from here http://jqueryvalidation.org/. Currently the code for adding a new row with input elements looks like this:

function addTimeRow(table, stime)
{
    //var rowIdx = $('#seminarTimes tr').length - 1;

    var $id = $('<input type="hidden" name="stid[]">');
    var $dateField = $('<input type="text" name="date[]" class="input-mini">');
    var $date = $('<div class="input-append date">')
        .append($dateField)
        .append('<span class="add-on"><i class="icon-calendar">');
    var $from = $('<input type="text" name="from[]" class="input-mini"> <span>(hh:mm)</span>');
    var $to = $('<input type="text" name="to[]" class="input-mini"> <span>(hh:mm)</span>');

    if (typeof(stime) !== 'undefined')
    {
        $id.attr('value', stime.id);
        $dateField.attr('value', stime.date);
        $from.attr('value', stime.from);
        $to.attr('value', stime.to);
    }
    else
        $id.attr('value', -1);

    // Attach new input row.
    table
        .append($('<tr>')
            .append($id)
            .append($('<td>')
                .append($date))
            .append($('<td>')
                .append($from))
            .append($('<td>')
                .append($to))
            .append($('<td class="vert">')
                .append($('<button class="btn btn-mini btnDelTime"><i class="icon-trash">'))));

    // Attach rules.
    $dateField.rules('add', { required: true });
    $from.rules('add', { required: true });
    $to.rules('add', { required: true });

    // Create pickers.
    $date.datepicker({
        language: 'de',
        autoclose: true,
        todayBtn: true,
        todayHighlight: true,
    }).on('changeDate', function(e) {
        editSeminarFormValidator.element($dateField);
        $date.datepicker('hide');
    });
}

In my document ready event I initialize the JQuery validation plugin like so:

var validator = $('#editSeminarForm').validate({
    debug: true,
    errorLabelContainer: '#error-label',
    wrapper: 'li',
    messages: {
        price: 'Bitte geben Sie einen Preis ein!'
    }
});

Now my actual problem is, that none of the new input fields gets validated. I know that I'm using input arrays for easier handling the form on the server-side. Are these arrays the problem why my input fields don't get validated?

EDIT - My current solution:

var rowIdx = 0;
function addTimeRow(table, stime)
{
    var $id = $($.validator.format('<input type="hidden" id="stid{0}" name="stid[{0}]">', rowIdx));
    var $dateField = $($.validator.format('<input type="text" id="date{0}" name="date[{0}]" class="input-mini">', rowIdx));
    var $date = $('<div class="input-append date">')
        .append($dateField)
        .append('<span class="add-on"><i class="icon-calendar">');
    var $from = $($.validator.format('<input type="text" id="from{0}" name="from[{0}]" class="input-mini"> <span>(hh:mm)</span>', rowIdx));
    var $to = $($.validator.format('<input type="text" id="to{0}" name="to[{0}]" class="input-mini"> <span>(hh:mm)</span>', rowIdx));

    if (typeof(stime) !== 'undefined')
    {
        $id.attr('value', stime.id);
        $dateField.attr('value', stime.date);
        $from.attr('value', stime.from);
        $to.attr('value', stime.to);
    }
    else
        $id.attr('value', -1);

    // Attach new input row.
    table
        .append($('<tr>')
            .append($id)
            .append($('<td>')
                .append($date))
            .append($('<td>')
                .append($from))
            .append($('<td>')
                .append($to))
            .append($('<td class="vert">')
                .append($('<button class="btn btn-mini btnDelTime"><i class="icon-trash">'))));

    // Attach rules.
    $dateField.rules('add', { required: true });
    $from.rules('add', { required: true });
    $to.rules('add', { required: true });

    // Create pickers.
    $date.datepicker({
        language: 'de',
        autoclose: true,
        todayBtn: true,
        todayHighlight: true,
    }).on('changeDate', function(e) {
        editSeminarFormValidator.element($dateField);
        $date.datepicker('hide');
    });

    rowIdx++;
}

Works like a charm!

VitaminCpp
  • 314
  • 1
  • 4
  • 11

2 Answers2

18

There seems to be nothing majorly wrong with the logic you're using for adding rules to the new elements. Although, you'll need to attach the .rules() method to a jQuery object using a jQuery selector, not the element's HTML.

something like...

$('#myInputID').rules('add', {...});

or...

$('input[name="myname"]').rules('add', {...});

But the heart of your problem is in here...

var $id = $('<input type="hidden" name="stid[]">');
    var $dateField = $('<input type="text" name="date[]" class="input-mini">');
    var $date = $('<div class="input-append date">')
        .append($dateField)
        .append('<span class="add-on"><i class="icon-calendar">');
    var $from = $('<input type="text" name="from[]" class="input-mini"> <span>(hh:mm)</span>');
    var $to = $('<input type="text" name="to[]" class="input-mini"> <span>(hh:mm)</span>');

Notice the name attribute? It's going to be the same for every new row.

The problem is that the jQuery Validate plugin will not work unless each input element contains a unique name. Simply modify your code to ensure that a new name is created for each new element.


EDIT: Indexed arrays will work fine with this plugin. Just increment the index when you create the new element.

name="from[0]", name="from[1]", name="from[2]", etc.

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • Thanks! Problem solved... It seems the JQuery Validation plugin can't handle input arrays, because as you already stated it needs unique names. But it seems to be possible to attach rules as I already did **IF** you attach the rules **AFTER** you have attached an JQuery HTML element to the DOM. – VitaminCpp Aug 03 '13 at 14:49
  • 7
    It can handle input arrays providing you explicitly set the array index: ie) `name="array[0]"` – FunkyMonk91 Dec 16 '13 at 17:39
  • @FunkyMonk91, don't recall stating that it couldn't handle indexed arrays. – Sparky Dec 10 '18 at 18:30
5

It might be a duplicate of:

  1. Adding jQuery validator rules to dynamically created elements in ASP
  2. jQuery - How to dynamically add a validation rule

Long story short, you have to call

$('input').rules('add', 'required')

http://validation.bassistance.de/rules

or, updated,

http://jqueryvalidation.org/rules

As a side note: since you inject a lot of HTML from JS it might be a good idea to try a template engine.

Community
  • 1
  • 1
Ionuț Staicu
  • 21,360
  • 11
  • 51
  • 58