【问题标题】:Jquery Validation on Dom not displaying messageDom上的Jquery验证不显示消息
【发布时间】:2013-04-17 20:48:08
【问题描述】:

我偶然发现了一些具有 jQuery 验证的代码,该验证是在将项目添加到 DOM 的 ajax 调用之后触发的。验证正在运行,但消息丢失。只是该字段被突出显示。我已经玩了一段时间来让它工作,但到目前为止还没有运气。任何想法,想法表示赞赏。

 $('#add-other-income-link').click(function (event) {
    event.preventDefault();
    var otherIncomesCount = $('#numberOfNewOtherIncomes').val();
    $('div[hideCorner = yep]').show();

    var url = $(this).attr('href');
    if (url) {
        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'html',
            success: function (data) {
                $('#additional-other-income').append(data);

                var count = otherIncomesCount;

                var id = 0;
                $('#additional-other-income').find('table.other-income-table').each(function (i, item) {
                    id = $(item).find('input.other-income-id');
                    var additionalIncomeTypeIdLabel = $(item).find('label.other-income-type-id-label');
                    var amountLabel = $(item).find('label.other-income-amount-label');
                    var additionalIncomeTypeIdMenu = $(item).find('select.other-income-type-id');
                    var amountTextBox = $(item).find('input.other-income-amount');

                    var idIndexer = 'OtherIncome_' + count + '__';
                    var nameIndexer = 'OtherIncome[' + count + '].';
                    var indexer = '[' + i + ']';
                    id.attr('id', idIndexer + 'Id').attr('name', nameIndexer + 'Id');
                    additionalIncomeTypeIdLabel.attr('for', idIndexer + 'AdditionalIncomeTypeId');
                    amountLabel.attr('for', idIndexer + 'Amount');
                    additionalIncomeTypeIdMenu.attr('id', idIndexer + 'AdditionalIncomeTypeId').attr('name', nameIndexer + 'AdditionalIncomeTypeId');
                    amountTextBox.attr('id', idIndexer + 'Amount').attr('name', nameIndexer + 'Amount').attr('data-val', 'true');

                    ++count;

                    addOtherIncomeValidation(item);
                });

additionalIncomeTypeIDMenu 上的 required 以及 amountTextBox 上的 requiredpositive 验证均成功,但两者的消息均未显示:

function addOtherIncomeValidation(container) {
if (container) {
    var additionalIncomeTypeIdMenu = $(container).find('select.other-income-type-id');
    var amountTextBox = $(container).find('input.other-income-amount');


    $(additionalIncomeTypeIdMenu).rules('add', {
        required: true,
        messages: {
            required: 'Please select an income type'
        }
    });

    $(amountTextBox).rules('add', {
        required: true,
        positive: true,
        messages: { positive: 'must be positive number'

        }
    });
}
}

顺便说一句,ajax 调用在这里返回了一个部分 EditorTemplate,你可以看到它使用了 ValidationMessageFor。

<div class="other-income" style="margin-bottom: 10px;">
<table class="other-income-table">
    <tr>
        <td>
            @Html.HiddenFor(x => x.Id, new { @class = "other-income-id" })
            @Html.LabelFor(x => x.AdditionalIncomeTypeId, "Type:", new { @class = "other-income-type-id-label" })
            <br />@Html.ValidationMessageFor(x => x.AdditionalIncomeTypeId)
        </td>
        <td>
            @Html.LabelFor(x => x.Amount, "Amount:", new { @class = "other-income-amount-label" })
            <br />@Html.ValidationMessageFor(x => x.Amount)
        </td>
        <td>&nbsp;&nbsp;</td>
    </tr>
    <tr>
        <td>@Html.DropDownListFor(x => x.AdditionalIncomeTypeId, new SelectList(Model.AdditionalIncomeTypes, "Value", "Text", Model.AdditionalIncomeTypeId), "--- Select One ---", new { @class = "other-income-type-id" })</td>
        <td>
            @Html.EditorFor(x => x.Amount, "Money", new { AdditionalClasses = "other-income-amount" })
        </td>
        <td>
            @{
                int? otherIncomeId = null;
                var removeOtherIncomeLinkClasses = "remove-other-income-link";
                if (Model.Id == 0)
                {
                    removeOtherIncomeLinkClasses += " new-other-income";
                }
                else
                {
                    otherIncomeId = Model.Id;
                }
            }
            @Html.ActionLink("Remove", "RemoveOtherIncome", "Applicant", new { applicationId = Model.ApplicationId, otherIncomeId = otherIncomeId }, new { @class = removeOtherIncomeLinkClasses })<img class="hide spinner" src="@Url.Content("~/Content/Images/ajax-loader_16x16.gif")" alt="Deleting..." style="margin-left: 5px;" />
        </td>
    </tr>
</table>

HTML:

       <div id="OtherIncome" class="applicant-section">

<h2 class="header2">Other Income</h2>
<div class="cornerForm">

<div class="other-income" style="margin-bottom: 10px;">
    <table class="other-income-table">
        <tr>
            <td>
                <input class="other-income-id" data-val="true" data-val-number="The field Id must be a number." id="OtherIncome_0__Id" name="OtherIncome[0].Id" type="hidden" value="385" />
                <label class="other-income-type-id-label" for="OtherIncome_0__AdditionalIncomeTypeId">Type:</label>
                <br /><span class="field-validation-valid" data-valmsg-for="OtherIncome[0].AdditionalIncomeTypeId" data-valmsg-replace="true"></span>
            </td>
            <td>
                <label class="other-income-amount-label" for="OtherIncome_0__Amount">Amount:</label>
                <br /><span class="field-validation-valid" data-valmsg-for="OtherIncome[0].Amount" data-valmsg-replace="true"></span>
            </td>
            <td>&nbsp;&nbsp;</td>
        </tr>
        <tr>
            <td><select class="other-income-type-id" data-val="true" data-val-number="The field AdditionalIncomeTypeId must be a number." id="OtherIncome_0__AdditionalIncomeTypeId" name="OtherIncome[0].AdditionalIncomeTypeId"><option value="">--- Select One ---</option>
<option value="1">Alimony</option>
<option value="2">Child Support</option>
<option value="3">Disability</option>
<option value="4">Investments</option>
<option selected="selected" value="5">Rental Income</option>
<option value="6">Retirement</option>
<option value="7">Secondary Employment</option>
<option value="8">Separate Maintenance</option>
</select></td>
            <td>


<input class="money other-income-amount" data-val="true" data-val-number="The field Amount must be a number." id="OtherIncome_0__Amount" name="OtherIncome[0].Amount" style="" type="text" value="0.00" />
            </td>
            <td>
                <a class="remove-other-income-link" href="/Applicant/RemoveOtherIncome/XNxxxxx753/385">Remove</a><img class="hide spinner" src="/Content/Images/ajax-loader_16x16.gif" alt="Deleting..." style="margin-left: 5px;" />
            </td>
        </tr>
    </table>


</div>
<div class="other-income" style="margin-bottom: 10px;">
    <table class="other-income-table">
        <tr>
            <td>
                <input class="other-income-id" data-val="true" data-val-number="The field Id must be a number." id="OtherIncome_1__Id" name="OtherIncome[1].Id" type="hidden" value="412" />
                <label class="other-income-type-id-label" for="OtherIncome_1__AdditionalIncomeTypeId">Type:</label>
                <br /><span class="field-validation-valid" data-valmsg-for="OtherIncome[1].AdditionalIncomeTypeId" data-valmsg-replace="true"></span>
            </td>
            <td>
                <label class="other-income-amount-label" for="OtherIncome_1__Amount">Amount:</label>
                <br /><span class="field-validation-valid" data-valmsg-for="OtherIncome[1].Amount" data-valmsg-replace="true"></span>
            </td>
            <td>&nbsp;&nbsp;</td>
        </tr>
        <tr>
            <td><select class="other-income-type-id" data-val="true" data-val-number="The field AdditionalIncomeTypeId must be a number." id="OtherIncome_1__AdditionalIncomeTypeId" name="OtherIncome[1].AdditionalIncomeTypeId"><option value="">--- Select One ---</option>
<option selected="selected" value="1">Alimony</option>
<option value="2">Child Support</option>
<option value="3">Disability</option>
<option value="4">Investments</option>
<option value="5">Rental Income</option>
<option value="6">Retirement</option>
<option value="7">Secondary Employment</option>
<option value="8">Separate Maintenance</option>
</select></td>
            <td>


<input class="money other-income-amount" data-val="true" data-val-number="The field Amount must be a number." id="OtherIncome_1__Amount" name="OtherIncome[1].Amount" style="" type="text" value="22.00" />
            </td>
            <td>
                <a class="remove-other-income-link" href="/Applicant/RemoveOtherIncome/XN42093753/412">Remove</a><img class="hide spinner" src="/Content/Images/ajax-loader_16x16.gif" alt="Deleting..." style="margin-left: 5px;" />
            </td>
        </tr>
    </table>


</div>

    <div id="additional-other-income"></div>

    <input id="numberOfNewOtherIncomes" name="numberOfNewOtherIncomes" type="hidden" value="0" />
    <input data-val="true" data-val-number="The field OriginalOtherIncomeTotal must be a number." id="OriginalOtherIncomeTotal" name="OriginalOtherIncomeTotal" type="hidden" value="22.0000" />
    <a class="editable-link" href="/Applicant/AddOtherIncome?appId=XNxxxxx753" id="add-other-income-link">Add Other Income</a>
</div>        </div>

验证码:

$.validator.addMethod('positive', function(value, element) {
var check = true;
if (value < 0) {
    check = false;
}
return this.optional(element) || check;
}, "Value must be a positive number."
);

【问题讨论】:

  • 两件事... 1) 这是 JavaScript,所以我们需要查看您的 rendered HTML 输出。 2) 你的.validate() 代码在哪里?
  • 添加了 HTML 和验证码。
  • 您仍然需要向我们展示validate 调用 - 它应该类似于$('#my-form-id').validate({ /* options here */ });
  • 我的理解是,当包含在表单元素中时,验证是预先连接的。至少这部分似乎是自动连接的,因为 - 我没有手动 .validate() 代码,并且验证在任何地方都没有它 - 除了在这种情况下(通过 ajax 的动态 HTML),验证消息不是显示尚未输入框红色突出显示。我正在使用插件:jquery.validate 和 jquery.validate.unobtrusive.js。我仍在搜索和审查。 -- 最后一点,我发现了 name 和 id 属性的错误(在上面的代码中修复)同样的问题。

标签: validation jquery dom jquery-validate


【解决方案1】:

我不认为我会找到自己的答案,但我找到了。首先,我必须为我对@Sparky 请求渲染 HTML 的回复道歉。我做了一个“查看页面源代码”,但不包括在服务器交付它的东西后从 ajax 调用添加的所有东西。我怀疑如果我一开始确实包含了额外的 DOM 内容,您会更快地查明问题。我的错。现在开始回答。

看起来,当以上面显示的方式将 EditorTemplate 注入 DOM 时,它不会像您在 MVC 中所期望的那样正确处理页面。 @Html.ValidationMessageFor 的代码根本不会被解析。如您所见,我对验证有点陌生,所以我不知道它为什么会这样。为了解决我的问题,我做了以下事情:

我稍微更新了我的编辑器模板,如下所示:

<div class="other-income" style="margin-bottom: 10px;">
<table class="other-income-table">
    <tr>
        <td>
            @Html.HiddenFor(x => x.Id, new { @class = "other-income-id" })
            @Html.LabelFor(x => x.AdditionalIncomeTypeId, "Type:", new { @class = "other-income-type-id-label" })
          <br />
            @Html.ValidationMessageFor(x=>x.AdditionalIncomeTypeId)
            <span id="AdditionalIncomeTypeIdValidation"></span>
        </td>
        <td>
            @Html.LabelFor(x => x.Amount, "Amount:", new { @class = "other-income-amount-label" })
            <br />
            @Html.ValidationMessageFor(x=>x.Amount)
            <span id="amountValidation"></span>
         </td>
        <td>&nbsp;&nbsp;</td>
    </tr>
    <tr>
        <td>@Html.DropDownListFor(x => x.AdditionalIncomeTypeId, new SelectList(Model.AdditionalIncomeTypes, "Value", "Text", Model.AdditionalIncomeTypeId), "--- Select One ---", new { @class = "other-income-type-id" })</td>
        <td>
            @Html.EditorFor(x => x.Amount, "Money", new { AdditionalClasses = "other-income-amount" })
        </td>
        <td>
            @{
                int? otherIncomeId = null;
                var removeOtherIncomeLinkClasses = "remove-other-income-link";
                if (Model.Id == 0)
                {
                    removeOtherIncomeLinkClasses += " new-other-income";
                }
                else
                {
                    otherIncomeId = Model.Id;
                }
            }
            @Html.ActionLink("Remove", "RemoveOtherIncome", "Applicant", new { applicationId = Model.ApplicationId, otherIncomeId = otherIncomeId }, new { @class = removeOtherIncomeLinkClasses })<img class="hide spinner" src="@Url.Content("~/Content/Images/ajax-loader_16x16.gif")" alt="Deleting..." style="margin-left: 5px;" />
        </td>
    </tr>
</table>

注意新的 span 标签,它添加在 @Html.ValidationMessageFor 旁边。

然后在我的 ajax 调用成功函数中,我做了这些更改:

  $('#add-other-income-link').click(function (event) {
        event.preventDefault();
        var count = $('#numberOfNewOtherIncomes').val();
        $('div[hideCorner = yep]').show();

        var url = $(this).attr('href');
        if (url) {
            $.ajax({
                url: url,
                type: 'GET',
                dataType: 'html',
                success: function (data) {
                    $('#additional-other-income').append(data);

                    var id = 0;
                    $('#additional-other-income').find('table.other-income-table').each(function (i, item) {
                        id = $(item).find('input.other-income-id');
                        var additionalIncomeTypeIdLabel = $(item).find('label.other-income-type-id-label');

                        var amountLabel = $(item).find('label.other-income-amount-label');
                        var additionalIncomeTypeIdMenu = $(item).find('select.other-income-type-id');
                        var amountTextBox = $(item).find('input.other-income-amount');
                        var amountValidation = $(item).find('#amountValidation');
                        var typeIdValidation = $(item).find('#AdditionalIncomeTypeIdValidation');

                        var idIndexer = 'OtherIncome_' + count + '__';
                        var nameIndexer = 'OtherIncome[' + count + '].';
                        var indexer = '[' + i + ']';
                        amountValidation.attr('class', 'field-validation-valid')
                                        .attr('data-valmsg-for', nameIndexer + 'Amount')
                                        .attr('data-valmsg-replace','true');
                        typeIdValidation.attr('class', 'field-validation-valid')
                                        .attr('data-valmsg-for', nameIndexer + 'AdditionalIncomeTypeId')
                                        .attr('data-valmsg-replace','true');
                        id.attr('id', idIndexer + 'Id').attr('name', nameIndexer + 'Id');
                        additionalIncomeTypeIdLabel.attr('for', idIndexer + 'AdditionalIncomeTypeId');
                        amountLabel.attr('for', idIndexer + 'Amount');
                        additionalIncomeTypeIdMenu.attr('id', idIndexer + 'AdditionalIncomeTypeId').attr('name', nameIndexer + 'AdditionalIncomeTypeId');
                        amountTextBox.attr('id', idIndexer + 'Amount').attr('name', nameIndexer + 'Amount').attr('data-val', 'true');


                        ++count;

                        addOtherIncomeValidation(item);

请注意,我正在手动添加未呈现的缺失验证跨度。现在验证消息显示在验证!耶。但是,我不确定这是最好的解决方法。它看起来和闻起来都像黑客,但我让它工作了。我相信它可以做得更好。再次感谢您的互动和反馈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多