简体   繁体   English

使用非侵入式验证来验证动态添加的字段集时出现问题

[英]Problem validating dynamically added fieldset using unobtrusive validation

I am currently working on a site that needs to dynamically add views/change views based on user input. 我目前在一个需要根据用户输入动态添加视图/更改视图的网站上工作。 Depending on what the user selects in a drop-down box, I render a partial view on the page. 根据用户在下拉框中选择的内容,我在页面上呈现部分视图。 For most of the views, this works; 对于大多数视图来说,这是可行的。 however, I have one partial view that has the option to generate multiple field-sets. 但是,我有一个局部视图,可以选择生成多个字段集。 Unobtrusive validation works when there is only one field-set (read: the user does not select the option to add more), but when the user generates more field-sets, validation only fires for the first set. 当只有一个字段集(阅读:用户没有选择添加更多选项的选项)时,不打扰的验证会起作用,但是当用户生成更多的字段集时,只会对第一个集合触发验证。 After looking around here for a bit, I found Xhalent's post regarding dynamic unobtrusive validation, as well as a post that gave me the logic to actually duplicate the field-set. 在这里闲逛了一会儿之后,我发现了Xhalent的有关动态无干扰验证的文章,以及使我逻辑上实际复制字段集的文章。 Unfortunately, I am pretty new (bad) at JS/jQuery, and have yet to figure out how to get the two ideas to mesh well. 不幸的是,我在JS / jQuery上还很新(不好),并且还没有弄清楚如何使这两个想法很好地融合在一起。

Here is the jQuery code I use to duplicate the form fields (I did not include the actual fields because this is really a conceptual problem, and what the fields are is irrelevant at this point. Plus I don't really understand how to format them here): 这是我用来复制表单字段的jQuery代码(我没有包括实际的字段,因为这确实是一个概念性的问题,并且此时的字段无关紧要。此外,我还不太了解如何格式化它们这里):

$(document).ready(function () {
    $("#itemCountSec1").change(function () {
        var itemCountVal = jQuery(this).val();
        $("#Section1Fields").fieldsManage(itemCountVal);

    });
});  

(NOTE: itemCountVal is a user-selected number 1-6) (注意:itemCountVal是用户选择的数字1-6)

Here is the function that I have saved in a JS file (Dupe.js): 这是我保存在JS文件(Dupe.js)中的函数:

jQuery.fn.fieldsManage = function (number) {
var ele = $(this);
var clones = ele.data("clones");
clones = clones ? clones : new Array(ele.attr("id"));
if (clones.length < number) {
    var clone;
    while (clones.length < number) {
        clone = ele.clone(true);
        var id = clones[0] + clones.length;
        clone.attr("id", id);
        $("#" + clones[clones.length - 1]).after(clone);
        $.validator.unobtrusive.parseDynamicContent(clone);
        clones.push(id);
        clone.find("input").each(function () { jQuery(this).val("") });
    }
} else {
    while (clones.length > number) {
        $("#" + clones.pop()).remove();
    }
}
ele.data("clones", clones);

} }

Here is Xhalent's modified unobtrusive JS code, which i saved in another JS file (validex.js): 这是Xhalent修改后的不干扰JS代码,我将其保存在另一个JS文件(validex.js)中:

(function ($) {
$.validator.unobtrusive.parseDynamicContent = function (selector) {
    //use the normal unobstrusive.parse method
    $jQuery.validator.unobtrusive.parse(selector);
    //get the relevant form
    var form = $(selector).first().closest('form');
    //get the collections of unobstrusive validators, and jquery validators
    //and compare the two
    var unobtrusiveValidation = form.data('unobtrusiveValidation');
    var validator = form.validate();
    $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
        if (validator.settings.rules[elname] == undefined) {
            var args = {};
            $.extend(args, elrules);
            args.messages = unobtrusiveValidation.options.messages[elname];
            //edit:use quoted strings for the name selector
            $("[name='" + elname + "']").rules("add", args);

        } else {
            $.each(elrules, function (rulename, data) {
                if (validator.settings.rules[elname][rulename] == undefined) {
                    var args = {};
                    args[rulename] = data;
                    args.messages = unobtrusiveValidation.options.messages[elname][rulename];
                    //edit:use quoted strings for the name selector
                    $("[name='" + elname + "']").rules("add", args);
                }
            });
        }
    });
} })($);  

I know that this: 我知道这:

$.validator.unobtrusive.parseDynamicContent('form input:last');  

Or some variant of this, has to go somewhere, but I am at a loss. 或某种形式的变体,必须去某个地方,但我茫然。

The question: How can I incorporate Xhalent's fine validation method into my code that duplicates the fieldset? 问题:如何将Xhalent的精细验证方法合并到复制字段集的代码中?

EDIT: 编辑:

Here are the scripts referenced on the page (Section 1.cshtml): 以下是页面上引用的脚本(第1.cshtml节):

<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>  
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.js")" type="text/javascript"></script>  
<script src="@Url.Content("~/Scripts/Dupe.js")" type="text/javascript"></script>  

Here is the form to be duplicated: 这是要复制的表格:

@using (Html.BeginForm("Section1","P15",FormMethod.Post))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>FILL ME OUT FIRST!</legend>
    <div class="PrimaryOPSelector">
        OP Number (This is your Primary OP, or the OP that you would be changing shifts from):
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.OP_Number, new SelectList(Model.Ops, "Op_Number", "Op_Number"))
        @Html.ValidationMessageFor(model => model.OP_Number)
    </div>
<p>Please select the number of shifts you would like to have off/change with another staff member: <select id="itemCountSec1" name="itemCountSec1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select></p>
<div class="ReasonForRequest">
        Please Select The Reson For Your Request For Time Off:
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.Reason_For_Request, new SelectList(Model.ReasonsForRequest, "Reason_ID", "Reason_For_Request1"))
        @Html.ValidationMessageFor(model => model.Reason_For_Request)
    </div>
</fieldset>  
<fieldset id="Section1Fields">

       <p><strong>Shift Start Date: </strong>@Html.DropDownListFor(model => model.Month, new SelectList(Model.Months, "Month_Value", "Month_Name"))
        @Html.DropDownListFor(model => model.Day, new SelectList(Model.Days))
        @Html.DropDownListFor(model => model.Year, new SelectList(Model.Years))</p>

<p><strong>Start Time Of Shift: </strong>
@Html.DropDownListFor(model =>model.Start_Hour, new SelectList(Model.Hours)) :
@Html.DropDownListFor(model => model.Start_Min, new SelectList(Model.Minutes))
@Html.DropDownListFor(model => model.Start_Marker, new SelectList(Model.AMPM))
</p>


<p><strong>End Time Of Shift: </strong>
@Html.DropDownListFor(model => model.End_Hour, new SelectList(Model.Hours)) :  
@Html.DropDownListFor(model => model.End_Min, new SelectList(Model.Minutes))
@Html.DropDownListFor(model => model.End_Marker, new SelectList(Model.AMPM))
</p>


<p><strong>Covering Staff Employee Number: </strong>@Html.EditorFor(model => model.Covering_Staff_Employee_Num)</p>
@Html.ValidationMessageFor(model => model.Covering_Staff_Employee_Num)

<p><strong>Covering Staff Phone Number: </strong>@Html.EditorFor(model => model.Covering_Staff_Phone)</p>
@Html.ValidationMessageFor(model => model.Covering_Staff_Phone)

<p><strong>Type Of Time Off: </strong>@Html.DropDownListFor(model => model.Type_Of_Time_Off, new SelectList(Model.Types, "Type_ID", "Name"))</p>
@Html.ValidationMessageFor(model => model.Type_Of_Time_Off)

<p><strong>Number Of Hours To Be Used: </strong>@Html.EditorFor(model => model.Hrs_Used)</p>
@Html.ValidationMessageFor(model => model.Hrs_Used)
</fieldset>

<p><input type="submit" value="Submit this section" /></p>
}

Rather than using such a complicated method, instead you can use the following three lines of code in the function called after your dynamic content is loaded: 您可以在加载动态内容之后在调用的函数中使用以下三行代码,而不是使用这种复杂的方法:

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

This will clear out the previous parsed content from the page, allowing all content on the page to be parsed again, and validation to be applied to all elements. 这将从页面上清除先前已解析的内容,从而允许再次解析页面上的所有内容,并将验证应用于所有元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM