最近kk在作一個小型的功能業務平臺,但因爲客戶對瀏覽器兼容性的要求比較強(兼容IE低版本),從技術選型上也須要配合後臺研發進行。因此最後採用了一套偏後端人員開發的方案:javascript
與此同時,還包括有脫離項目頁面的:html
雖然說這些技術棧確實是kk初學前端時就接觸過的,但layui着實在開發過程當中坑了kk一把,因此在這裏想作個總結。前端
不過這個項目也不是那麼沒突破,藉此機會,kk確實仍是接觸了一把郵件信的編寫,屬於HTML基礎上的一次突破,也算是一次很好的經驗借鑑。java
事不宜遲,我們開始。ajax
var Feng = {
initValidator: function (formId, fields) {
$('#' + formId).bootstrapValidator({
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: fields,
live: 'enabled',
message: '該字段不能爲空'
});
}
};
複製代碼
該方法封裝在了工具類Feng裏,可供業務頁面全局調用。json
//設置validator校驗規則
var validateFields = {
time: {
trigger:"change input click", //監聽change動做
validators: {
notEmpty: {
message: '執行時間不能爲空'
}
}
},
caption: {
validators: {
notEmpty: {
message: '任務名稱不能爲空'
}
}
}
};
//業務頁面內初始化就調用Feng工具類
$(function () {
Feng.initValidator("taskInfoForm", validateFields);
});
//點擊提交觸發表單校驗,驗證數據是否爲空
UserInfoDlg.validate = function () {
$('#userInfoForm').data('bootstrapValidator').validate();//手動對錶單進行校檢
$('#taskInfoForm').data('bootstrapValidator').validate();//手動對錶單進行校檢
return $('#userInfoForm').data('bootstrapValidator').isValid() && $('#taskInfoForm').data('bootstrapValidator').isValid();
};
複製代碼
(function () {
var $ax = function (url, success, error) {
this.url = url;
this.type = "post";
this.data = {};
this.dataType = "json";
this.async = false;
this.success = success;
this.error = error;
};
$ax.prototype = {
start: function () {
var _this = this;
if (this.url.indexOf("?") == -1) {
this.url = this.url + "?jstime=" + new Date().getTime();
} else {
this.url = this.url + "&jstime=" + new Date().getTime();
}
jQuery.ajax({
url: this.url,
type: this.type,
dataType: this.dataType,
async: this.async,
data: this.data,
success: function (e) {
_this.success(e);
},
error: function (data) {
_this.error(data);
}
});
},
set: function (key, value) {
if (typeof key == "object") {
for (var i in key) {
if (typeof i == "function")
continue;
this.data[i] = key[i];
}
} else {
this.data[key] = (typeof value == "undefined") ? $("#" + key).val() : value;
}
return this;
},
setData: function (data) {
this.data = data;
return this;
},
clear: function () {
this.data = {};
return this;
}
};
window.$ax = $ax;
}());
複製代碼
業務頁面調用$ax:bootstrap
//提交信息
var ajax = new $ax(Feng.ctxPath + "/task/add", function (data) {//傳入ajax成功(success)後的callback方法
Feng.success("添加成功!");
if (window.parent.MgrUser != undefined) {
window.parent.MgrUser.table.refresh();
UserInfoDlg.close();
}
window.location.reload();
}, function (data) {//傳入ajax失敗(error)後的callback方法
Feng.error("添加失敗!" + data.responseJSON.message + "!");
});
ajax.set(this.userInfoData);//設置提交的表單信息,$ax對象根據輸入data的類型放進this.data中
ajax.start();//發出ajax請求
複製代碼
該方法根據輸入的表單名name,或是class,判斷該表單輸入哪一種類型(radio、checkbox、日曆、普通輸入框),進行不一樣方式的取值和輕量校驗。後端
/** * 設置對話框中的數據 * * @param key 數據的名稱 * @param val 數據的具體值 */
UserInfoDlg.set = function (key, value) {
if (typeof value == "undefined") {
if (key == 'time') {
var value = $("#" + key).val();
var startTime = value.substring(0, value.indexOf("-")).replace(/(\w*)年(.*)月(.*)日(.*)/g, "$1-$2-$3").replace(/\s*/g, "");
var endTime = value.substring(value.indexOf("-") + 1).replace(/(\w*)年(.*)月(.*)日(.*)/g, "$1-$2-$3").replace(/\s*/g, "");
console.log(startTime);
console.log(endTime);
this.userInfoData['startTime'] = startTime;
this.userInfoData['endTime'] = endTime;
return this;
}
if (typeof $("#" + key).val() == "undefined") {
var str = "";
var ids = "";
$("input[name='" + key + "']:checkbox").each(function () {
if (true == $(this).is(':checked')) {
str += $(this).val() + ",";
}
});
if (str && key != 'time') {
if (str.substr(str.length - 1) == ',') {
ids = str.substr(0, str.length - 1);
}
} else {
$("input[name='" + key + "']:radio").each(function () {
if (true == $(this).is(':checked')) {
ids = $(this).val()
}
});
}
this.userInfoData[key] = ids;
} else {
this.userInfoData[key] = $("#" + key).val();
}
}
return this;
};
複製代碼
業務頁面調用: 使用JQ鏈式調用,將表單全部項目的name推入便可瀏覽器
/** * 收集數據 */
UserInfoDlg.collectData = function () {
this.set('orgName').set('orgCode').set('orgContactPerson').set('orgContactMobile').set('caption')
.set('url').set('time').set('period').set('importance').set('smsList').set('emailList').set('depth');
};
複製代碼
如上圖爲一個添加了Boostrap Validator表單驗證的雙日曆(layui.laydate)輸入框,表單提交前須要對其輸入的內容進行非空校驗。
框架
其結構組成代碼以下:
<!-- 傳入jQuery文件-->
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<!--引入BoostrapValidator-->
<!--引入laydate -->
<div class="form-horizontal">
<div class="row form-row">
<div class="col-sm-12 form-group">
<div class="form-group" style="">
<label class="col-sm-2 control-label">
<span style="color:red;">*</span>執行時間:
</label>
<div class="col-sm-5">
<input class="form-control" placeholder="請選擇開始日期 ~ 結束日期" id="time" name="time" value="" type="text">
</div>
</div>
</div>
</div>
</div>
複製代碼
laydate組件配置代碼:
laydate.render({
elem: '#time'
, range: true //或 range: '~' 來自定義分割字符
, format: 'yyyy年MM月dd日' //可任意組合
, done: function (value, date) {
$("#time").change();
setTimeout(function () {
$('#taskInfoForm')
.data('bootstrapValidator')
.updateStatus('time','NOT_VALIDATED', null)
.validateField('time');
}, 200)
}
});
//直接監聽日曆輸入框的blur事件
$("#time").blur(function () {
setTimeout(function () {
$('#taskInfoForm').data('bootstrapValidator')
.updateStatus('time', 'NOT_VALIDATED', null)
.validateField('time');
}, 200)
});
複製代碼
Boostrap Validator對第三方js輸入表單的信息,沒法自動觸發校驗。
實如今業務場景中,就是當laydate雙日曆選定日期事後,點擊提交觸發校驗,仍然視爲輸入框爲空。
第一步,在日曆輸入框所對應的校驗規則validatorField裏添加:
trigger:"change input click",
複製代碼
即input的這些事件皆可自動觸發validate()。
done: function (value, date) {
$("#time").change();
$('#taskInfoForm')
.data('bootstrapValidator')
.updateStatus('time','NOT_VALIDATED', null)
.validateField('time');
}
複製代碼
第二步:在laydate完成done事件後觸發input的change事件並手動觸發校驗一次。
結果:能夠實現日曆值變化時候的表單從新校驗。
這下新問題出現了:
在輸入框從空值到有值的過程當中,仍然沒法觸發校驗
kk探究了下各路大神的文章,發現其問題根本在於:
laydate 加載日期賦值給 input 在 bootstrapValidator 驗證以後,因此在點擊時間插件以後進行二次特定字段驗證便可 取自文章:bootstrapValidator 驗證框架與 layui 時間插件兼容
1.完善laydate的done回調事件,對validate二次校驗設置時間延遲(200ms基本不影響體驗)
done: function (value, date) {
$("#time").change();
setTimeout(function () {
$('#taskInfoForm')
.data('bootstrapValidator')
.updateStatus('time','NOT_VALIDATED', null)
.validateField('time');
}, 200)
}
複製代碼
2.附加的,也能夠完善日曆輸入框自己的blur事件,將validate綁定在blur事件上
$("#time").blur(function () {
setTimeout(function () {
$('#taskInfoForm').data('bootstrapValidator')
.updateStatus('time', 'NOT_VALIDATED', null)
.validateField('time');
}, 200)
});
複製代碼
結果:可完整解決當前問題,輸入日曆可正常觸發二次校驗。
laytpl與layui.element不可共用
kk想嘗試在頁面中引用laytpl的麪包屑功能,須要導入element的功能組件。
最終採用了手動重構功能邏輯的方法。
如上內容屬於kk我的意見,若有更好的解決方案,或內容有錯誤遺漏,歡迎指正!