1

I have a MVC application with a Jquery Datatable.

The table looks like this:

<div class="widget-body no-padding">
    <table id="datatable_tabletools" class="table table-striped table-hover">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Fornavn</th>
                    <th>Etternavn</th>
                    <th>Telefon</th>
                    <th>Epost</th>
                    <th>Fylke</th>
                    <th>Handlinger</th>
                </tr>
            </thead>
            <tbody>

                @foreach (var person in Model)
                {
            <tr>
                <td><label id="Alert_Person_ID">@person.Alert_Person_ID</label></td>
                <td>
                    <span class="display-mode">
                        <label id="lblFirstName">@person.FirstName</label>
                    </span>
                    <input type="text" id="FirstName" value="@person.FirstName" class="edit-mode" />
                </td>
                <td>
                    <span class="display-mode">
                        <label id="lblLastName">@person.LastName</label>
                    </span>
                    <input type="text" id="LastName" value="@person.LastName" class="edit-mode" />
                </td>
                <td>
                    <span class="display-mode">
                        <label id="lblPhonePrimary">@person.PhonePrimary</label>
                    </span>
                    <input type="text" id="PhonePrimary" value="@person.PhonePrimary" class="edit-mode" />
                </td>
                <td>
                    <span class="display-mode">
                        <label id="lblEmailPrimary">@person.EmailPrimary</label>
                    </span>
                    <input type="text" id="EmailPrimary" value="@person.EmailPrimary" class="edit-mode" />
                </td>
                <td width="100px">
                    <span class="display-mode">
                        <label id="lblCounty">@person.County</label>
                    </span>
                    <input type="text" id="County" value="@person.County" class="edit-mode" />
                </td>
                <td width="100">
                    <button class="more-details display-mode btn btn-xs btn-default"><i class="fa fa-search"></i></button>
                    <button class="edit-user display-mode btn btn-xs btn-default"><i class="fa fa-pencil"></i></button>
                    <button class="delete-user display-mode btn btn-xs btn-default"><i class="fa fa-trash-o"></i></button>
                    <button class="save-user edit-mode btn btn-xs btn-default"><i class="fa fa-save"></i></button>
                    <button class="cancel-user edit-mode btn btn-xs btn-default"><i class="fa fa-times"></i></button>
            </tr>
                }
            </tbody>
        </table>
</div>

And I have alot of different JS methods to new, update and delete functions to add data. The Datatables scripts looks like this:

$('#datatable_tabletools').dataTable({

                //datatable_tabletools_filter
                // Tabletools options: 
                //   https://datatables.net/extensions/tabletools/button_options
                "sDom": "<'dt-toolbar'<'col-xs-6'f><'col-xs-6'T>r>t<'dt-toolbar-footer'<'col-xs-6'i><'col-xs-6'p>>",
                "fnDrawCallback": function () {
                    if (newrow == false) {
                        $('.edit-mode').hide();
                    }
                },
                "oTableTools": {

                    "aButtons": [
                        {
                            "sExtends": "collection",
                            "sButtonText": "Eksporter <span class=\"caret\" />",
                            "aButtons": ["copy","csv", "xls", "pdf", "print"]
                        }
                    ],
                    "sSwfPath": "../../Scripts/plugin/datatables/swf/copy_csv_xls_pdf.swf"
                }
            });

So the question is how do i add Jquery validation to this??

F.ex I have a button to add a new row which I append to the toolbar.

 $("#datatable_tabletools_filter").prepend("<button id='new_p' class='btn btn-default' style='float:left;margin-right:10px;'><i class='fa fa-plus'></i> Ny Person</button>");

And this call this method to add the datafields to the table:

$(document).on("click", "#new_p", function (e) {
    if (newrow == true) {
        return;
    }
    newrow = true;
    var dTable = $('#datatable_tabletools').DataTable();
    dTable.row.add([
            "<label id='Alert_Person_ID'></label>",
            "<span class='display-mode'><label id='lblFirstName'></label></span><input type='text' id='FirstName' class='edit-mode' />",
            "<span class='display-mode'><label id='lblLastName'></label></span><input type='text' id='LastName' class='edit-mode' />",
            "<span class='display-mode'><label id='lblPhonePrimary'></label></span><input type='text' id='PhonePrimary' class='edit-mode' />",
            "<span class='display-mode'><label id='lblEmailPrimary'></label></span><input type='text' id='EmailPrimary' class='edit-mode' />",
            "<span class='display-mode'><label id='lblCounty'></label></span><input type='text' id='County' class='edit-mode' />",
            "</button><button class='new-user edit-mode btn btn-xs btn-default'><i class='fa fa-save'></i></button><button class='abort-user edit-mode btn btn-xs btn-default'><i class='fa fa-times'></i></button>"
    ]).draw();
});

and the save-user button function looks like this:

    $(document).on("click", ".save-user", function (e) {
        var tr = $(this).parents('tr:first');
        var FirstName = tr.find("#FirstName").val();
        var LastName = tr.find("#LastName").val();
        var PhonePrimary = tr.find("#PhonePrimary").val();
        var EmailPrimary = tr.find("#EmailPrimary").val();
        var County = tr.find("#County").val();
        var Alert_Person_ID = tr.find("#Alert_Person_ID").html();
        var AlertPerson =
        {
            "Alert_Person_ID": Alert_Person_ID,
            "FirstName": FirstName,
            "LastName": LastName,
            "PhonePrimary": PhonePrimary,
            "EmailPrimary": EmailPrimary,
            "County": County
        };
        $.ajax({
            url: '/AlertPerson/UpdatePerson/',
            data: JSON.stringify(AlertPerson),
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                    tr.find("#lblFirstName").text(FirstName);
                    tr.find("#lblLastName").text(LastName);
                    tr.find("#lblPhonePrimary").text(PhonePrimary);
                    tr.find("#lblEmailPrimary").text(EmailPrimary);
                    tr.find("#lblCounty").text(County);
                    tr.find('.edit-mode, .display-mode').toggle();
                    noty({
                        text: data[1],
                        layout: "topCenter",
                        type: "success",
                        timeout: 2000
                    });

            },
            error: function(data){
                tr.find('.edit-mode, .display-mode').toggle();
                noty({
                    text: data[3] + "br/>" + data[4],
                    layout: "topCenter",
                    type: "warning",
                    timeout: 2000
                });                   
            }
        })
    });

I know its a ton of code :O But is it an easy way to add JQuery validation like this (under) to the table? For each updated row and new row added?

$(function() {
                // Validation
                $("#ID").validate({
                    // Rules for form validation
                    rules : {
                        FirstName : {
                            required : true
                        },
                        LastName : {
                            required : true
                        }
                    },

                    // Messages for form validation
                    messages : {
                        FirstName : {
                            required : 'Please enter First Name'
                        },
                        LastName : {
                            required : 'Please enter Last Name'
                        }
                    },

                    errorPlacement : function(error, element) {
                        error.insertAfter(element.parent());
                    }
                });
            });
stibay
  • 1,200
  • 6
  • 23
  • 44
  • You cannot use jQuery Validation on any of this if there are no `
    ` containers on each row.
    – Sparky Jun 19 '14 at 14:35
  • Hmm ok, so I have to wrap each now row () added with
    ? Does it need a unique form id aswell then?
    – stibay Jun 20 '14 at 07:28
  • Of course. Not only does the plugin need to keep track of each form, but repeating the same `id` on a page is invalid HTML. – Sparky Jun 20 '14 at 14:08

1 Answers1

1

I would rather have added this as a comment but do not have enough reputation. This follows on the suggestion made in comments to wrap each row inside a <form> element with its own unique id.

You don't need to wrap each row in its own <form> - you can wrap the entire <table> in a <form>. Then to add jQuery unobtrusive validation to each <input> simply add the necessary attributes. E.g.:

<input type='text' data-val='true' data-val-required='Required'>

will first enable validation, and then mark this input as required with a validation message of "Required" if a value is not provided. If you want to know the markup generated by MVC, do a test page using a model in which model properties have been decorated with the data attributes you're interested in, e.g. regular expression validation etc. Some more examples to get you going:

Regular expression validation

<input type='text' id='newsletter-mobile' name='newsletter-mobile' data-val='true' data-val-regex='Not a valid mobile' data-val-regex-pattern='(^\+([^0-9]*?(\d)){9,15}$)|(^[^0-9]*?0[678]([^0-9]*?\d){8}$)' />

Max length

<input type="email" id="emailaddress" name="emailaddress" data-val="true" data-val-required="Required field" data-val-length="Email must be a string with a maximum length of 60." data-val-length-max="60" />

Two fields must match - plus illustrates how to display validation message

<label for="password_273">Password <span>(Required)</span></label>
<input type="password" id="password_273" name="password_273" data-val="true" data-val-required="Required field" data-val-length="Password must be between 6 and 30 characters." data-val-length-max="30" data-val-length-min="6" />
<div><span class="field-validation-valid" data-valmsg-for="password_273" data-valmsg-replace="true"></span></div>
<label for="password2_273">Verify Password <span>(Required)</span></label><input type="password" id="password2_273" name="password2_273" data-val="true" data-val-required="Required field" data-val-equalto-other="password_273" data-val-equalto="Values must match!" />
<div><span class="field-validation-valid" data-valmsg-for="password2_273" data-valmsg-replace="true"></span></div>

On your Save button you should first call the jQuery validation functions against the form before submitting the data via Ajax or otherwise, e.g.:

var $frm = $('#form-id');
$frm.validate();
if (!$frm.valid())
  return;
//now you can save your data - but validate on the server again!

Further notes which might be useful:

  1. If you don't see any visual feedback on failed validation, be sure to define a style for the class input.input-validation-error - jQuery validation simply adds this class to elements that fail validation, it is up to you to make them stand out.
  2. If you find that validation doesn't work at all, it might be because jQuery validation does not detect dynamically added input elements, e.g. loaded by AJAX. To enable validation on this inputs, you need to implement the little plugin suggested in an answer to another question.
Community
  • 1
  • 1