最近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我的意见,若有更好的解决方案,或内容有错误遗漏,欢迎指正!