0

アイテムを DOM に追加する ajax 呼び出しの後にトリガーされる jQuery 検証を持つコードをいくつか見つけました。検証は機能していますが、メッセージがありません。フィールドだけが強調表示されます。私はこれを機能させるためにしばらく遊んでいますが、これまでのところ運がありません。任意のアイデア、考えをいただければ幸いです。

 $('#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."
);
4

1 に答える 1

1

自分で答えを見つけるとは思っていませんでしたが、見つけました。最初に、レンダリングされたHTMLのリクエストで @Sparky に応答したことをお詫びする必要があります。「ページソースの表示」を行いましたが、サーバーが配信した後に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>

@Html.ValidationMessageFor の横に新しいスパン タグが追加されていることに注意してください。

次に、javascript の 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);

レンダリングされていない不足している検証スパンを手動で追加していることに注意してください。検証時に検証メッセージが表示されるようになりました。わーい。ただし、これが最善の修正であるかどうかはわかりません。ハックのように見えてにおいがしますが、動作しました。私はそれがより良い方法でできると確信しています。インタラクションとフィードバックをありがとうございました。

于 2013-04-19T16:51:52.073 に答える