unobtrusive jQuery validation on elements created

2019-02-18 17:13发布

I have a register form created by mvc3 scaffolding.

e.g.

<div class="editor-label">
    @Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Email)
    @Html.ValidationMessageFor(model => model.Email)
</div>

and so on.

I have a dropdownlist where the user can select if hes a person or a company. If person is selected the page loads with the person's properties, like birthdate, but if he/she selects the option 'company', I switch out a part of the form (with jquery .detach() .attach()) to a hidden div outside the form (so the values aren't posted on submit)

This works fine with my custom validation and viewmodels, the only problem is that there is no jquery validation for the elements freshly switched in.

I would like to use unobtrusive jquery validation, but how do I attach the handlers manually to the new form elements (or reparse the whole dom for validation)?

edit: after checking this blogpost: http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/

i have tried to update my code. i have included the javascript described there, and tried to reparse the newly inserted part of the form. when it did not make any difference I switched to .remove() and .html() my code and insert the bare html, but it did not help in any way. heres my script:

    <script>
        $(document).ready(function () {
            var secretholder = $('#secret_from_holder');
            var visibleholder = $('#type_data_holder');
            var select = $('select#TypeValueID');
            select.change(function () {
                var value = $('select#TypeValueID option:selected').val();
                switch (value) {
                    case '1':
                        var tohide = visibleholder.html();
                        visibleholder.children().remove();
                        var toshow = secretholder.html();
                        secretholder.children().remove();

                        secretholder.append(tohide);
                        visibleholder.append(toshow);

                        $.validator.unobtrusive.parseDynamicContent('div.firm');
                        break;
                    case '2':
                        var tohide = visibleholder.html();
                        visibleholder.children().remove();
                        var toshow = secretholder.html();
                        secretholder.children().remove();

                        secretholder.append(tohide);
                        visibleholder.append(toshow);

                        $.validator.unobtrusive.parseDynamicContent('div.person');
                        break;
                }
            });
        });
    </script>

heres my hidden part outside the form which i switch in:

    <div id="secret_from_holder" style="display: none">
    @if (Model.TypeValueID == Constants.Crm.Customer.Types.FIRM_VALUE_ID)
    {
        <div class="person">
            <div class="editor-label">
                @Html.LabelFor(model => model.Person.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Person.Name)
                @Html.ValidationMessageFor(model => model.Person.Name)
            </div>
            <div class="clear"></div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Person.BirthDate)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Person.BirthDate)
                @Html.ValidationMessageFor(model => model.Person.BirthDate)
            </div>
            <div class="clear"></div>
        </div>
    }
    else
    { 
        <div class="firm">
            <div class="editor-label">
                @Html.LabelFor(model => model.Firm.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Firm.Name)
                @Html.ValidationMessageFor(model => model.Firm.Name)
            </div>
            <div class="clear"></div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Firm.BankAccountNumber)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Firm.BankAccountNumber)
                @Html.ValidationMessageFor(model => model.Firm.BankAccountNumber)
            </div>
            <div class="clear"></div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Firm.Tax)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Firm.Tax)
                @Html.ValidationMessageFor(model => model.Firm.Tax)
            </div>
            <div class="clear"></div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Firm.EuTax)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Firm.EuTax)
                @Html.ValidationMessageFor(model => model.Firm.EuTax)
            </div>
            <div class="clear"></div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Firm.TradeNumber)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Firm.TradeNumber)
                @Html.ValidationMessageFor(model => model.Firm.TradeNumber)
            </div>
            <div class="clear"></div>
        </div>                   
    }
    </div>

I'm really stuck here, please help.

the part automatically parsed (on pageload) always validates (even if switched out and back again), but the part I try to parse manually never validates

2条回答
别忘想泡老子
2楼-- · 2019-02-18 17:28

I also had a similar scenario where I was loading content dynamically with Ajax using a Partial View. I was able to get my code working through a two step process.

  1. When the content is loaded to the DOM, I did the following:

    $.ajax({
       type: "Get",
       url: SomeURL,
       data: { TransactionId: recordId },
       success: function (data) {
          $('#SomeDiv').html(data);
          $.validator.unobtrusive.parse('#SomeDiv');              
          ShowModal();
       }
    });
    
  2. When submitting the form, I did the following:

    var form = $('#SomeDiv').find('form');
    if ($(form).valid()) {
       // call ajax post
    }
    

And that seemed to trigger unobtrusive validation. Hope someone gets something out of this.

查看更多
劫难
3楼-- · 2019-02-18 17:35

You need to parse the newly added contents in order to register it with client validation. And here's another blog post which discusses those issues. And yet another one.

查看更多
登录 后发表回答