jQuery Validation Plugin + jQuery.validate.unobtrusive + AJAX,不透過form submit來做網頁表單驗證

表單驗證是網頁很常用的功能,通常是submit會觸發驗證流程(會把jQuery.validator.unobtrusive.parse("#form1");  會把檢核觸發寫在submit button裡)。但今天收到個需求,網頁因為某些因素不想透過submit 表單post資料到後台,想要透過ajax的方式來post資料,但validator又一定需要把要驗證的<input>包在<form>裡面的情況下(如果把<form>拿掉,就不會有驗證效果),要如何觸發表單驗證?

畫面大概上上面長的那樣,照理講應該就是把Barcode<input>跟下面的驗證碼<input>包在同一個<form裡面>,點擊放大鏡<button> submit後,就會post資料到server。但今天收到的需求是不使用submit要透過ajax來做上面的流程,且只有驗證碼欄位需要做表單驗證,測試了一下,終於找出解法。

原本表單部分的cshtml應該如下面:

@using (Html.BeginForm("Index", "Warranty", FormMethod.Post, new { id = "form1" }))
{            
            <div class="box-body form-row">
                <div class="row pccent">
                    <div class="col-xs-12 form-inline">

                        @Html.ValidationSummary(true)
                        @Html.AntiForgeryToken()

                        <div class="form-group">
                            <div class="input-group input-group-addon-ddl">
                                @{
                                    List<SelectListItem> l_ddlType = new List<SelectListItem>();
                                    l_ddlType.Add(new SelectListItem() { Text = Html.Translation("Barcode").ToString(), Value = "Barcode", Selected = true });

                                }
                                <div class="input-group-addon">
                                    @Html.DropDownList("SearchType", l_ddlType, new { @class = "form-control", style = "width:auto" })
                                </div>
                                @Html.TextBox("barcode", null, new { size = 50, @class = "form-control" })

                                <div class="input-group-btn">
                                    <button class="btn btn-primary" type="submit" name="fs" id="subbtn"><i class="fa fa-search"></i></button>
                                </div>
                            </div>

                        </div>

                    </div>
                </div>



                    <div class="row pccent form-inline">
                        <div class="flex-row">
                            <div class="col-12">
                                <input name="verifyimage_input" type="text" value="" data-val-required="Please input Verify Code!" data-val="true" class="form-control" placeholder="Verify code" />
                            </div>
                            <div class="col-12">
                                <div class="form-group form-inline">
                                    <div class="input-group-btn">
                                        <div class="input-group">
                                            <img class="pointer tableImg" id="verifyimage" style="border:1px solid #ccc;" src="@Url.Action("JPEG","VerifyImage",new {Area="Common",rdm=eRMA.Common.Utils.GetRandomString(10) })" />
                                            <div onclick="refreshverifyimage();" class="tablebackground"><span class="fas fa-sync-alt tableIcon"></span></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div>@Html.ValidationMessage("verifyimage_input")</div>
                    </div>
                </div> 
}                             

 

不想submit的話,就要把上面的程式稍作修改一下。修改的地方有下面4項:

1.把原本的form改成只包下面驗證碼的部分,這是個沒有submit功能只為了要做JQuery Validation而做的<form>表單。

2.新增加一個hidden <input>,在執行ajax時,把Barcode <input>的值裝進這個hidden <input>的value裡面

3.原本的查詢<button>要用Js加上click事件來執行AJAX

4.觸發驗證方式有兩種:
單一元素驗證可以使用$("input[name=verifyimage_input]").valid()來觸發驗證,
要一次驗證<form>表單裡所有欄位可用$('#{form id}').valid())

這樣就可以達到我們要的有form但又不用submit就可以做表單裡面所有input的驗證了

            <div class="box-body form-row">
                <div class="row pccent">
                    <div class="col-xs-12 form-inline">

                        @Html.ValidationSummary(true)
                        @Html.AntiForgeryToken()

                        <div class="form-group">
                            <div class="input-group input-group-addon-ddl">
                                @{
                                    List<SelectListItem> l_ddlType = new List<SelectListItem>();
                                    l_ddlType.Add(new SelectListItem() { Text = Html.Translation("Barcode").ToString(), Value = "Barcode", Selected = true });
                                    //l_ddlType.Add(new SelectListItem() { Text = Html.Translation("ProductName").ToString(), Value = "PartNumber" });
                                }
                                <div class="input-group-addon">
                                    @Html.DropDownList("SearchType", l_ddlType, new { @class = "form-control", style = "width:auto" })
                                </div>
                                @Html.TextBox("barcode", null, new { size = 50, @class = "form-control" })

                                <div class="input-group-btn">
                                    <button class="btn btn-primary" type="submit" name="fs" id="subbtn"><i class="fa fa-search"></i></button>
                                </div>
                            </div>

                        </div>

                    </div>
                </div>


                <form id="form1">
                    <div class="row pccent form-inline">
                        <div class="flex-row">
                            <div class="col-12">
                                <input name="verifyimage_input" type="text" value="" data-val-required="Please input Verify Code!" data-val="true" class="form-control" placeholder="Verify code" />
                                <input id="hidden_barcode" name="barcode" type="hidden">
                            </div>
                            <div class="col-12">
                                <div class="form-group form-inline">
                                    <div class="input-group-btn">
                                        <div class="input-group">
                                            <img class="pointer tableImg" id="verifyimage" style="border:1px solid #ccc;" src="@Url.Action("JPEG","VerifyImage",new {Area="Common",rdm=eRMA.Common.Utils.GetRandomString(10) })" />
                                            <div onclick="refreshverifyimage();" class="tablebackground"><span class="fas fa-sync-alt tableIcon"></span></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div>@Html.ValidationMessage("verifyimage_input")</div>
                        @*<span data-valmsg-for="verifyimage_input"></span>*@
                    </div>              
                </form>
                        


                        <div id='partial_view'></div>

                </div>

 

補充:

顯示驗證訊息的方式可用:

1.<div>@Html.ValidationMessage("{input element name}")</div≥  => 可搭配Html.ValidationSummary()做後端驗證,請參考Ref 4.

2.<span data-valmsg-for={input element name}></span>  => unobtrusive 檢核,請參考Ref 2. & 3.

 

unobtrusive 前端驗證的觸發前提:

1.必須要在網頁載入時先執行jQuery.validator.unobtrusive.parse("#form1")解析讀取元素的data-val-*標示

2.要被驗證的元素的屬性data-val必須要為true
 



重設所有欄位回驗證前狀態:

$("#{form_name}")[0].reset(); 可以把所有驗證欄位恢復到網頁剛載入時的狀態

 

網頁執行中動態設定欄位是否需要驗證:

有些驗證條件是某個條件成立時才需要進行驗證,否則不用驗證,遇到這種情形時,要重新呼叫jQuery.validator.unobtrusive.parse("#{form_name}"),來重新綁定驗證,參考js如下:

        $('#{element_id}').attr('data-val', isvalidate);
        $('#{element_id}').attr('data-val', isvalidate);
        var $form = $('#{form_id}')//表单

        //去除表单验证
        $form.removeData('validator');
        $form.removeData('unobtrusiveValidation');
        //重新绑定验证。
        $.validator.unobtrusive.parse($form[0]);

 

 

 

 

Ref:

jQuery Validation Plugin表單驗證使用介紹

使用jQuery.validate.unobtrusive.js-黑暗執行緒

謙卑式jQuery檢核範例-動態變更檢核設定-黑暗執行緒

[ASP.NET][MVC] ASP.NET MVC (5) : 資料驗證 (1) Server-side Validation | 小朱&#xAE; 的技術隨手寫 - 點部落

Validate fields using JQuery validation without any submit? - Stack Overflow

[Asp .Net MVC] MVC Client 端驗證 (Unobtrusive Validate) | Harry's Tech World - 點部落 => 什麼是Unobtrusive可以看這篇