枚舉對象的使用:
. 代碼如下:
//各種驗證方式支持的標簽類型
sustainType: function (elem, setting) {
var srcTag = elem.tagName;
var stype = elem.type;
switch (setting.validatetype) {
case _validTypeEnum.InitValidator:
return true;
case _validTypeEnum.InputValidator:
if (srcTag == _validTagEnum.INPUT || srcTag == _validTagEnum.TEXTAREA || srcTag == _validTagEnum.SELECT) {
return true;
} else {
return false;
}
case _validTypeEnum.CompareValidator:
if (srcTag == _validTagEnum.INPUT || srcTag == _validTagEnum.TEXTAREA) {
if (stype == _validTagTypeEnum.checkbox || stype == _validTagTypeEnum.radio) {
return false;
} else {
return true;
}
}
return false;
case _validTypeEnum.AjaxValidator:
if (stype == _validTagTypeEnum.text || stype == _validTagTypeEnum.textarea || stype == _validTagTypeEnum.file || stype == _validTagTypeEnum.password || stype == _validTagTypeEnum.select_one) {
return true;
} else {
return false;
}
case _validTypeEnum.RegexValidator:
if (srcTag == _validTagEnum.INPUT || srcTag == _validTagEnum.TEXTAREA) {
if (stype == _validTagTypeEnum.checkbox || stype == _validTagTypeEnum.radio) {
return false;
} else {
return true;
}
}
return false;
case _validTypeEnum.FunctionValidator:
return true;
}
}
. 代碼如下:
//獲取指定字符串的長度
getLength: function (jqObj) {
var elem = _GetDomObj(jqObj);
var sType = elem.type;
var len = 0;
switch (sType) {
case _validTagTypeEnum.text:
case _validTagTypeEnum.hidden:
case _validTagTypeEnum.password:
case _validTagTypeEnum.textarea:
case _validTagTypeEnum.file:
var val = jqObj.val();
var initConfig = $.formValidator.getInitConfig(elem.settings[0].validatorgroup);
len = initConfig.wideword ? String.getCharLength(val) : val.length;
break;
case _validTagTypeEnum.checkbox:
case _validTagTypeEnum.radio:
len = $("input[type='" + sType + "'][name='" + jqObj.attr("name") + "']:checked").length;
break;
case _validTagTypeEnum.select_one:
case _validTagTypeEnum.select_multiple:
len = jqObj.children(":selected").length;
break;
}
return len;
}
2. 將原版本中各方法之間傳遞驗證標簽的Id,改為傳遞驗證標簽的對象,這樣就避免了在各個方法內需要再根據id獲得驗證標簽的對象,提高了代碼執行速度和性能。
3. 原版本中對驗證成功、錯誤等提示樣式在插件中把樣式名給限定死了,如錯誤的提示樣式名為:onError,這樣在使用此插件時就會讓美工需要關心插件中各提示樣式的名稱,並且還要避免出現樣式重復或沖突的情況,如此使用讓人很不爽。真正好的插件,應該是讓js和(需要用戶自己設置的)樣式完全分離——這類似於編程裡的'松耦合',但這樣才能讓js和樣式無不依賴,更好的適應用戶的需求! 於是,我將插件中各提示樣式(作為方法的參數對象的屬性)讓用戶可以自己配置,主要代碼如下:
. 代碼如下:
//提示樣式枚舉
var _tipCssEnum =
{
//(ajax)加載處理
loadCss: "loadCss",
//獲得焦點時的樣式
focusCss: "focusCss",
//提示[用於 為空提示] ---如果此項未設置,則使用errorCss
noticeCss: "noticeCss",
//失敗or錯誤[用於格式錯誤,正則表達式驗證]---必須設置
errorCss: "errorCss",
//成功---必須設置
successCss: "successCss",
//默認狀態 ---必須設置
defaultCss: "defaultCss"
};
initConfig: function (controlOptions) {
var settings =
{
debug: false,//是否是調試模式
validatorgroup: "1",//驗證組
alertmessage: false,//是否直接彈出驗證提示
validobjectids: "",//驗證對象集合
focusvalid: false,
onsuccess: function () { return true; }, //驗證成功後的處理方法,返回true|false(可追加表單驗證或阻止表單提交等)
onerror: function () { },
filterInputStrFun: function (str) { return FilterInputOper.FilterInputStr(str); }, //過慮輸入字符串的方法[可設置]
isformpost: false, //是否是表單提交(默認:false——非表單提交,一般為ajax提交,true——表單提交)
submitonce: false,//是否驗證通過後,表單立刻提交
submitbutton: null,//提交按鈕id或對象
getformdata: null, //function (formdata) { } (驗證通過後)獲得輸入的表單值——只有isformpost=false時,此方法才會被調用
//驗證提示顯示設置(default:默認根據設置)
tipshow: "default",
formid: "", //驗證表單的id或對象
tidymode: false, //精簡模式
errorfocus: true,
wideword: true,
//驗證提示樣式設置(全局)
tipcss:
{
//(ajax)加載處理
loadCss: "",
//獲得焦點時的樣式
focusCss: "",
//提示
noticeCss: "",
//成功
successCss: "",
//失敗
errorCss: "",
//默認狀態
defaultCss: ""
}
};
controlOptions = controlOptions || {};
controlOptions.tipcss = controlOptions.tipcss || {};
//合並整個配置(深度拷貝)
$.extend(true, settings, controlOptions);
if (!settings.isformpost) {
if (!settings.submitbutton) {
alert("submitbutton不能為空!");
return;
}
_GetJqObj(settings.submitbutton).click(function () {
var pageIsValid = $.formValidator.pageIsValid(settings.validatorgroup);
if (pageIsValid && _IsFunction(settings.getformdata)) {
var formData = _GetFormData(settings.filterInputStrFun);
settings.getformdata(formData);
}
});
}
settings.tipshow = settings.tipshow || "default";
//如果是精簡模式,發生錯誤的時候,第一個錯誤的控件就不獲得焦點
if (settings.tidymode) {
settings.errorfocus = false;
}
if (settings.formid) {
_GetNodeById(settings.formid).submit(function () {
//如果不是表單提交,則阻止表單提交
return settings.isformpost ? $.formValidator.pageIsValid(settings.validatorgroup) : false;
});
}
if (_jQuery_formValidator_initConfig_Array == null) {
_jQuery_formValidator_initConfig_Array = new Array();
}
_jQuery_formValidator_initConfig_Array.push(settings);
}
//設置提示信息
setTipState: function (elem, showCssEnum, showmsg) {
var setting0 = elem.settings[0];
var initConfig = $.formValidator.getInitConfig(setting0.validatorgroup);
if (initConfig.alertmessage && showmsg) {
alert(showmsg);
return
}
var jq_tipObj = setting0.tipJqObj;
var tip_IsNull = Object.isNull(jq_tipObj);
if (!tip_IsNull) {
showmsg = showmsg || "";
if (initConfig.tidymode) {
//保存提示信息
elem.Tooltip = showmsg;
if (showCssEnum != _tipCssEnum.errorCss && showCssEnum != _tipCssEnum.noticeCss)
jq_tipObj.hide();
}
jq_tipObj.removeClass();
//設置提示樣式
var showClass = setting0.tipcss[showCssEnum];
//如果 noticeCss未設置,則使用 errorCss
if (String.isNullOrEmpty(showClass) && showCssEnum == _tipCssEnum.noticeCss) {
showCssEnum = _tipCssEnum.errorCss;
showClass = setting0.tipcss[showCssEnum];
}
if (!String.isNullOrEmpty(showClass)) {
//保存 當前提示標簽 顯示的樣式(枚舉值)
elem.showcssenum = showCssEnum;
jq_tipObj.addClass(showClass);
}
jq_tipObj.html(showmsg);
}
}
4.在initConfig配置對象中增加了一些屬性,以滿足更多的需求,增強功能和易用性,如:
filterInputStrFun: function (str) { return FilterInputOper.FilterInputStr(str); }, //過慮輸入字符串的方法[可設置] ——以滿足對輸入字符串過慮的需求
isformpost: false, //是否是表單提交(默認:false——非表單提交,一般為ajax提交,true——表單提交) ——以滿足ajax提交和表單提交的需求
getformdata: null, //function (formdata) { } (驗證通過後)獲得輸入的表單值——只有isformpost=false時,此方法才會被調用
tipshow: "default",//驗證提示顯示設置(default:默認根據設置) ——設置驗證提示標簽對象查找方式,根據Id 或 自定義jQuery查找(find)方法。
插件的使用如下:
. 代碼如下:
<div class="jy_fctopbox01">
<div class="jy_fctopbox02">
<div class="left">
您好,歡迎來到山水檀溪! <a href="/lpzx/LoginOut.aspx">
退出</a>
</div>
<div class="right">
<a href="http://xyfc.s187.com/Block_index.aspx?blockId=3" id="a_Into_House" target="_blank">進入樓盤首頁</a></div>
</div>
</div>
<div class="jy_fcadmincenter">
<div class="jy_fcadminheader">
<div class="left">
<img src="http://img1.s187.com/Channels/House/xyfc.s187.com/BlockLogo/3/Block_Logo_3.png" id="BlockLogo" width="200" height="120" />
</div>
<div class="right">
<img src="http://img1.s187.com/Channels/House/xyfc.s187.com/BlockPropaganda/3/Block_XC_3.png" id="BlockXcImg" width="732" height="120" /></div>
</div>
<div id="jy_fcmenu">
<div class="jy_fcmenu">
<ul>
<li class='hover'>
<a href='/lpzx/BlockManager/BlockInfomation/Block_Detail.aspx'>
樓盤管理
</a></li>
<li >
<a href='/lpzx/PurchaseIntention/PurchaseIntention_List.aspx'>
購房意向
</a></li>
<li >
<a href='/lpzx/UsersProposal/BlockProposal.aspx'>
用戶建議
</a></li>
<li >
<a href='/lpzx/PasswordCenter/ModifyPassword.aspx'>
修改密碼
</a></li>
<li >
<a href='/lpzx/BlockManager/BlockDomainSet/SetBlockDominName.aspx'>
域名設置
</a></li>
<li >
<a href='/lpzx/UsersQuestion/QAList.aspx'>
在線問答
</a></li>
</ul>
</div>
</div>
<div id="Page_Content" class="jy_fcadmincent">
<div class="jy_fcadminleft">
<div class="ul1">
<ul>
<li><a href='/lpzx/BlockManager/BlockInfomation/Block_Detail.aspx' >
樓盤信息
</a></li>
<li><a href='/lpzx/BlockManager/BuildingInfomation/Building_List.aspx' class='hover'>
棟號信息
</a></li>
<li><a href='/lpzx/BlockManager/LayoutInfomation/Layout_List.aspx' >
戶型信息
</a></li>
<li><a href='/lpzx/BlockManager/RoomInfomation/Room_List.aspx' >
套房信息
</a></li>
<li><a href='/lpzx/BlockManager/CustomerService/Customer_List.aspx' >
客服管理
</a></li>
<li><a href='/lpzx/BlockManager/BlockNews/BlockNews_List.aspx' >
樓盤動態
</a></li>
<li><a href='/lpzx/BlockManager/BlockProgress/BlockProgress_List.aspx' >
樓盤進度
</a></li>
<li><a href='/lpzx/BlockManager/SalesLicense/LicenseManager.aspx' >
預售許可證
</a></li>
<li><a href='/lpzx/BlockManager/Gallery/Block_Gallery.aspx' >
樓盤圖庫
</a></li>
</ul>
</div>
</div>
<div class="jy_fcadminright" id="stepDiv1">
<div class="jy_fcadmintil02">
添加棟號 >> <span>第一步</span></div>
<div class="jy_fcadmintil01">
<img src="http://images.cnblogs.com/tje_03.png" width="533" height="26" alt="" /></div>
<div class="jy_fcadminme">
<div class="right01">
<div class="jy_fcscrtbox03">
<label>
樓盤名稱:
</label>
<span class="s2">
山水檀溪
</span>
</div>
<div class="jy_fcscrtbox03">
<label>
<font color="#ff0000">* </font>棟號:
</label>
<span class="s1">
<input type="text" maxlength="10" class="jy_fcadmin02" id="txtBuildingName" />
</span>
<div class="uuu1">
<p id="tipBuildingName" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
<font color="#ff0000">* </font>狀態:
</label>
<div class="jy_fcscrtboxs1">
<input name="rd_SaleState" type="radio" value="1" />
待售
<input name="rd_SaleState" type="radio" value="2" />
期房
<input name="rd_SaleState" type="radio" value="3" />
現房
<input name="rd_SaleState" type="radio" value="4" />
尾房
<input name="rd_SaleState" type="radio" value="5" />
售完
</div>
<div class="uuu2">
<p id="tipSaleState" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
<font color="#ff0000">*</font> 用途:
</label>
<div class="jy_fcscrtboxs1">
<div class="jy_fcmu">
<ul>
<li>
<input type="checkbox" name="ckUsage" value="1" />普通住宅</li>
<li>
<input type="checkbox" name="ckUsage" value="2" />單身公寓</li>
<li>
<input type="checkbox" name="ckUsage" value="3" />復式</li>
<li>
<input type="checkbox" name="ckUsage" value="4" />別墅</li>
<li>
<input type="checkbox" name="ckUsage" value="5" />廠房</li>
<li>
<input type="checkbox" name="ckUsage" value="6" />寫字樓</li>
<li>
<input type="checkbox" name="ckUsage" value="7" />商鋪</li>
<li>
<input type="checkbox" name="ckUsage" value="8" />經濟適用房</li>
</ul>
</div>
</div>
<div class="uuu2">
<p id="tipUsage" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
預售許可證:
</label>
<div class="jy_fcscrtboxs1 zoon" style="display:none">
<select id="selLicense" class="jy_fcadmin02">
</select></div>
<div class="jy_fcscrtboxs5"><p class="c1"><a href="javascript:;" id="lookSelLicenseA">[查看內容]</a></p><p class="c1"><ins style="color: black;" id="License_empty_Ins">無</ins></p><p class="c1"><a href="javascript:;" onclick="PreSellLicensePopUp.Open();return false;"
title="如不存在此建築物的預售許可證,可點擊添加!">添加</a></p>
</div>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
地理位置:
</label>
<div class="jy_fcscrtboxs5"><p class="c1"><a href="javascript:;" id="markMapA">地圖標注</a></p><p class="c1"><ins></ins></p><p class="c1"></p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
<font color="#ff0000">*</font> 層數:
</label>
<span class="s1">
<input maxlength="3" type="text" class="jy_fcadmin02" id="txtfloornum" />
</span>
<div class="uuu1">
<p id="tipfloornum" class="box001" style="display:none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
樓層說明:
</label>
<span class="s2">
<textarea id="txtBlockNote" cols="80" rows="5" class="jy_fcadmin07"></textarea>
</span>
</div>
<div class="jy_fcscrtbox03">
<label>
公攤比率:
</label>
<div class="jy_fcscrtboxs1">
<input maxlength="10" type="text" class="jy_fcadmin02" id="txtShareBili" />
</div>
<div class="uuu2">
<p id="tipShareBili" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
位置說明:
</label>
<span class="s2">
<textarea id="txtPostionDesc" cols="80" rows="5" class="jy_fcadmin07"></textarea>
</span>
</div>
<div class="jy_fcscrtbox03">
<p class="c2">
<input id="btnSubmit_Step1" type="button" class="jy_fcadminbottom02" value="下一步" /> <input
id="btnCancel_Step1" type="button" class="jy_fcadminbottom02" value="取 消" />
</p>
</div>
</div>
</div>
<div class="jy_fcadminright" id="stepDiv2" style="display: none;">
<div class="jy_fcadmintil02">
添加棟號 >> <span>第二步</span></div>
<div class="jy_fcadmintil01">
<img src="http://images.cnblogs.com/tj_03.png" width="533" height="26" /></div>
<div class="jy_fcadminme">
<div class="right01">
<div class="jy_fcscrtbox03">
<label>
占地面積:
</label>
<div class="jy_fcscrtboxs1">
<input type="text" maxlength="6" class="jy_fcadmin02" id="txtCoveredArea" />
(單位:平方米)</div>
<div class="uuu2">
<p id="tipCoveredArea" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
建築面積:
</label>
<div class="jy_fcscrtboxs1">
<input type="text" maxlength="6" class="jy_fcadmin02" id="txtBuildingArea" />
(單位:平方米)</div>
<div class="uuu1">
<p id="tipBuildingArea" class="box001" style="display: none;">
</p>
</div>
</div>
<div class="jy_fcscrtbox03">
<label>
電梯型號:
</label>
<span class="s2">
<input type="text" maxlength="10" class="jy_fcadmin02" id="txtElevator" />
例:東芝</span>
</div>
<div class="jy_fcscrtbox03">
<label>
外牆裝修:
</label>
<span class="s2">
<input type="text" maxlength="10" class="jy_fcadmin02" id="txtOutSideDecorate" />
<kbd>例:高級面磚和塗料結合</kbd></span>
</div>
<div class="jy_fcscrtbox03">
<label>
內牆裝修:
</label>
<span class="s2">
<input type="text" maxlength="10" class="jy_fcadmin02" id="txtInSideDecorate" />
例:125/250厚加氣混凝土砌塊</span>
</div>
<div class="jy_fcscrtbox03">
<label>
基礎:
</label>
<span class="s2">
<input type="text" maxlength="15" class="jy_fcadmin02" id="txtBasicFacility" />
例:管樁基礎</span>
</div>
<div class="jy_fcscrtbox03">
<label>
主體結構:
</label>
<span class="s2">
<input type="text" maxlength="25" class="jy_fcadmin02" id="txtSubjectStruts" />
例:框架剪力牆結構</span>
</div>
<div class="jy_fcscrtbox03">
<p class="c2">
<input id="btnPre_Step2" type="button" class="jy_fcadminbottom02" value="上一步" /> <input type="button" id="btnSubmit_Step2" class="jy_fcadminbottom02" value="下一步" />
</p>
</div>
</div>
</div>
</div>
<div class="jy_fcadminright" id="stepDiv3" style="display: none;">
<div class="jy_fcadmintil02">
添加棟號 >> <span>第三步</span></div>
<div class="jy_fcadmintil01">
<img src="http://images.cnblogs.com/tjs_03.png" width="533" height="26" /></div>
<div class="jy_fcadminme">
<div class="jy_fcadmintable02">
<table width="100%" border="0" cellspacing="0">
<tr>
<td height="39" align="right" width="20%">
棟號圖片:
</td>
<td align="left" width="20%">
<span class="s1">(最多1張)</span><a id="a_uploadBuilding" href="javascript:;"><img id="img_uploadBuilding" src="http://images.cnblogs.com/aw_07.png" width="80" height="25" align="absmiddle" alt="" /></a>
</td>
<td align="left" width="60%">
<div class="jy_fcscrtbox03">
<p id="tip_buildingFile" class="box004">
</p>
</div>
</td>
</tr>
</table>
<div id="div_BuildingContainer" class="jy_fcadminimg02">
<div style="float: left; width: 340px; height: 380px;">
<div id="ShowBuildingFlv">
</div>
</div>
</div>
<div class="jy_fcgybox005">
<input id="btnPre_Step3" type="button" class="jy_fcadminbottom02" value="上一步" /> <input type="button" id="btnSubmit_Step3" class="jy_fcadminbottom02" value="完 成" />
</div>
</div>
</div>
</div>
</div>
<div id="Page_Bottom" class="jy_fcadminbottom">
<img src="/lpzx/images/fckj_27.png" width="950" height="6" alt="" />
</div>
</div>
<br />
<p id="showMes_P"></p>
<script src="js/formValidator.js" type="text/javascript"></script>
<script src="js/formValidatorRegex.js" type="text/javascript"></script>
<script type="text/javascript">
function GetInitConfigOptions(validatorgroup, onsuccess, submitbutton, getformdata) {
return {
validatorgroup: validatorgroup,
formid: "form1",
onerror: function (msg) { alert("onerror is " + msg) },
onsuccess: onsuccess,
submitbutton: submitbutton,
tipcss: {
//(ajax)加載處理
loadCss: "",
//獲得焦點時的樣式
focusCss: "",
//提示
noticeCss: "box001",
//成功
successCss: "box002",
//失敗
errorCss: "box003",
//默認狀態
defaultCss: "box004"
},
getformdata: getformdata
};
}
//顯示指定的(步)容器
function _ShowStepContainer(showNum) {
for (var i = 1; i <= 3; i++) {
$("div#stepDiv" + i).css("display", (i == showNum ? "block" : "none"));
}
}
$(document).ready(function () {
$("p").show();
$.formValidator.initConfig(
GetInitConfigOptions(1, function () {
_ShowStepContainer(2);
}, "btnSubmit_Step1")
);
$("#txtBuildingName").formValidator(
{
validatorgroup: "1",
tipid: "tipBuildingName",
onshow: "請輸入棟號",
onfocus: "棟號不能為空",
oncorrect: "",
tipcss: //此對象中的屬性繼承(extend)其對應的initConfig.tipcss的屬性
{
//失敗
//errorCss: "onNotice"
}
})
.inputValidator({ min: 2, max: 10, onerror: "你輸入的棟號(長度錯誤),請確認" });
$("#txtfloornum").formValidator({ tipid: "tipfloornum", onshow: "請輸入層數", onfocus: false, oncorrect: "層數輸入正確" }).inputValidator({ min: 1, max: 30, type: "value", empty: { leftempty: false, rightempty: false, emptyerror: "層數兩邊不能有空符號" }, onerror: "層數不能為空,值介於1-30之間" })
.regexValidator({ regexp: RegexEnum.integer_Z, onerror: "你輸入的層數格式不正確,必須為數字" });
$('input[name="rd_SaleState"]:radio').formValidator({ tipid: "tipSaleState", onshow: "請選擇售樓狀態", onfocus: "棟號的售樓狀態", oncorrect: "" }).inputValidator({ min: 1, onerror: "售樓狀態必選!" });
$('input[name="ckUsage"]:checkbox').formValidator({ tipid: "tipUsage", forcevalid: true, onshow: "請選擇用途", onfocus: false, oncorrect: "用途已選擇" }).inputValidator({ min: 1, onerror: "請選擇用途,必填" });
$("#txtShareBili").formValidator({ tipid: "tipShareBili", onshow: "請輸入公攤比率", oncorrect: "" }).inputValidator({ min: 1, onerror: "公攤比率不能為空" }).regexValidator({ regexp: RegexEnum.decmal_Z, onerror: "你輸入的公攤比率格式不正確,必須為數字" });
$.formValidator.initConfig(
GetInitConfigOptions(2, function () {
_ShowStepContainer(3);
}, "btnSubmit_Step2")
);
$("#txtCoveredArea").formValidator({ validatorgroup: "2", tipid: "tipCoveredArea", onshow: "請輸入占地面積", onfocus: false, oncorrect: "占地面積輸入正確" }).inputValidator({ min: 1, onerror: "占地面積不能為空" })
.regexValidator({ regexp: RegexEnum.integer_Z, onerror: "你輸入的占地面積格式不正確,必須為數字" });
$("#txtBuildingArea").formValidator({ validatorgroup: "2", tipid: "tipBuildingArea", onshow: "請輸入建築面積", onfocus: false, oncorrect: "建築面積輸入正確" }).inputValidator({ min: 1, onerror: "建築面積不能為空" })
.regexValidator({ regexp: RegexEnum.integer_Z, onerror: "你輸入的建築面積格式不正確,必須為數字" });
$.formValidator.initConfig(
GetInitConfigOptions(3, function () {
alert("驗證通過"); return true;
}, "btnSubmit_Step3", function (formdata) {
alert("要提交的表單值:"+$.param(formdata));
for (var key in formdata) {
$("#showMes_P").html($("#showMes_P").html() + "<br/>key:" + key + " | val:" + formdata[key]);
}
})
);
});
</script>
上面就是我對此插件主要改進的介紹,插件整體還是保持原版本的結構和思想,所做的無非是讓插件可讀性和易用性等更好,今天分享出來,也是希望有更多的朋友能幫忙測試看看,提些自己的意見或想法,讓這個表單驗證插件formValidator能更好用(不斷的改進才能做到更好,改進離不開大家的建議)!
補充:需要解決改進的功能——驗證可支持自由組合,如:電話和手機 只用驗證其中的一個通過即可. 這個我自己嘗試實現過,但效果不理想,沒有想到一個比較好的解決方法,希望大家能幫忙考慮下!
插件和Demo下載:FromVaild