jqueryvalidationasp.net-mvc-5begincollectionitem

Validation not working when using dynamically created PartialViews mvc5


I have a View in which Items ( modelview) created/deleted dynamically using BeginCollectionItem and partialview. The dynamically created view's validation is not firing. Code: MainView :

 @model EnquiryVM
    @using (Html.BeginForm()) 
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">

            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <div class="form-group">
                @Html.LabelFor(model => model.EnquiryNumber, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-3">
                    @Html.EditorFor(model => model.EnquiryNumber, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.EnquiryNumber, "", new { @class = "text-danger" })
                </div>
            </div>



            <div class="form-group">
                @Html.LabelFor(model => model.DivisionID, "Division", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-3">
                    @Html.DropDownListFor(u => u.DivisionID, (IEnumerable<SelectListItem>)Model.Divisions, "--Select--") 
                    @Html.ValidationMessageFor(model => model.DivisionID, "", new { @class = "text-danger" })
                </div>
            </div>



            <div id="LineItems">
                @using (Html.BeginForm())
                {
                    <div id="editorRowsLineitems">
                        @foreach (var item in Model.LineItems)
                        {
                            @Html.Partial("_CreateEnquiryItem", item)
                        }
                    </div>
                    @Html.ActionLink("Add Items", "CreateLineItem", null, new { id = "addItem", @class = "button" });
                }
            </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
        </div>
    }


    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript">
        $(function () {
            $('#addItem').on('click', function () {
                $.ajax({
                    url: '@Url.Action("CreateLineItem")',
                        cache: false,
                        success: function (html) { $("#editorRowsLineitems").append(html); }
                    });
                    return false;
                });
            $('#editorRowsLineitems').on('click', '.deleteRow', function () {
                    $(this).closest('.editorRow').remove();
                });
            $('form').data('validator', null);
            $.validator.unobtrusive.parse($('form'));
        });


    </script>
    }

PartialView :

@model EnquiryLineItemVM

<div class="editorRow">
    @using (Html.BeginCollectionItem("ItemList"))
    {
        <table class="table">

            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <tr>
                <td>
                    @Html.EditorFor(model => model.ItemDesc)
                    @Html.ValidationMessageFor(model => model.ItemDesc, "", new { @class = "text-danger" })
                </td>
                <td>
                    @Html.EditorFor(model => model.Quantity)
                    @Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
                </td>

                <td>
                    @Html.DropDownListFor(model => model.ManufacturerId, Model.ManufacturerList, "--Please Select--")
                    @Html.ValidationMessageFor(model => model.ManufacturerId, "", new { @class = "text-danger" })
                </td>
                <td>

                    <a href="#" class="deleteRow">Delete</a>
                </td>
            </tr>
        </table>

    }
    </div>

ViewModel:

 public class EnquiryLineItemVM
    {
        public int ID { get; set; }
        [Required]
        public string ItemDesc { get; set; }
       [Required]
        public int Quantity { get; set; }

    }

Similar question which uses validation in such scenario is here SO1 But didn't work . I have referenced unobtrusive and Jquery validations in the view. Please help. Thanks for reading .


Solution

  • Jquery validation doesn't work when you dynamically add to the DOM because it adds attributes used in validation. The workaround is to call it again after you load:

    $('#addItem').on('click', function () {
        $.ajax({
            url: '@Url.Action("CreateLineItem")',
                cache: false,
                success: function (html) { 
                               $("#editorRowsLineitems").append(html); 
                               // clear and add validation attributes
                               $("form").removeData("validator");
                               $("form").removeData("unobtrusiveValidation");
                               $.validator.unobtrusive.parse("form");
                          }
            });
            return false;
        });
    

    See here