fastadmin/public/assets/js/require-form.js

695 lines
36 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, Upload, Validator) {
var Form = {
config: {
fieldlisttpl: '<dd class="form-inline"><input type="text" name="<%=name%>[<%=index%>][key]" class="form-control" value="<%=row.key%>" size="10" /> <input type="text" name="<%=name%>[<%=index%>][value]" class="form-control" value="<%=row.value%>" size="30" /> <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></dd>'
},
events: {
validator: function (form, success, error, submit) {
if (!form.is("form"))
return;
//绑定表单事件
form.validator($.extend({
validClass: 'has-success',
invalidClass: 'has-error',
bindClassTo: '.form-group',
formClass: 'n-yellow n-bootstrap',
msgClass: 'n-top',
theme: 'yellow_top',
stopOnError: true,
rules: {
mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"],
email: [/^[0-9A-Za-z][\.-_0-9A-Za-z]*@[0-9A-Za-z]+(\.[0-9A-Za-z]+)+$/, "请填写有效的邮箱地址"],
chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"],
money: [/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/, "请填写有效的金额"],
ip: [/^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i, '请填写有效的 IP 地址'],
// 身份证
idcard: function (element) {
var value = element.value,
isValid = true;
var cityCode = {11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江 ", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北 ", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏 ", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外 "};
/* 15位校验规则 (dddddd yymmdd xx g) g奇数为男偶数为女
* 18位校验规则 (dddddd yyyymmdd xxx p) xxx奇数为男偶数为女p校验位
校验位公式C17 = C[ MOD( ∑(Ci*Wi), 11) ]
i----表示号码字符从由至左包括校验码在内的位置序号
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
Ci 1 0 X 9 8 7 6 5 4 3 2
*/
var rFormat = /^\d{6}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$|^\d{6}\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}$/; // 格式验证
if (!rFormat.test(value) || !cityCode[value.substr(0, 2)]) {
isValid = false;
}
// 18位身份证需要验证最后一位校验位
else if (value.length === 18) {
var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
var Ci = "10X98765432"; // 校验字符
// 加权求和
var sum = 0;
for (var i = 0; i < 17; i++) {
sum += value.charAt(i) * Wi[i];
}
// 计算校验值
var C17 = Ci.charAt(sum % 11);
// 与校验位比对
if (C17 !== value.charAt(17)) {
isValid = false;
}
}
return isValid || "请填写正确的身份证号码";
},
// 银行卡(借记卡、贷记卡)
bankcard: function (element) {
var value = element.value.replace(/\s/g, ''),
isValid = true,
rFormat = /^[\d]{12,19}$/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var arr = value.split('').reverse(),
i = arr.length,
temp,
sum = 0;
while (i--) {
if (i % 2 === 0) {
sum += +arr[i];
} else {
temp = +arr[i] * 2;
sum += temp % 10;
if (temp > 9) sum += 1;
}
}
if (sum % 10 !== 0) {
isValid = false;
}
}
return isValid || "请填写有效的银行卡号";
},
// 信用卡
creditcard: function (element, params) {
var value = element.value,
validTypes = 0x0000,
types = {
mastercard: 0x0001,
visa: 0x0002,
amex: 0x0004,
dinersclub: 0x0008,
enroute: 0x0010,
discover: 0x0020,
jcb: 0x0040,
unknown: 0x0080
};
if (/[^0-9\-]+/.test(value)) {
return false;
}
value = value.replace(/\D/g, "");
if (!params) {
validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
} else {
for (var i = 0; i < parmas.length; i++) {
validTypes |= types[params[i]];
}
}
if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
return value.length === 16;
}
if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
return value.length === 16;
}
if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
return value.length === 15;
}
if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
return value.length === 14;
}
if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
return value.length === 15;
}
if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
return value.length === 16;
}
if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
return value.length === 16;
}
if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
return value.length === 15;
}
if (validTypes & 0x0080) { //unknown
return true;
}
return "请填写有效的信用卡号";
},
// 组织机构代码证
orgcode: function (element) {
var value = element.value,
isValid = true,
rFormat = /^[A-Z\d]{8}-[X\d]/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var Wi = [3, 7, 9, 10, 5, 8, 4, 2];
var Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 加权求和
var sum = 0;
for (var i = 0; i < 8; i++) {
sum += Ci.indexOf(value.charAt(i)) * Wi[i];
}
// 计算校验值: C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
var C9 = 11 - (sum % 11);
if (C9 === 10) C9 = 'X';
else if (C9 === 11) C9 = 0;
C9 = '' + C9;
// 与校验位比对
if (C9 !== value.charAt(9)) {
isValid = false;
}
}
return isValid || "请填写正确的组织机构代码";
},
// 营业执照号
bizcode: function (element) {
var value = element.value,
isValid = true,
rFormat = /^[1-6]\d{14}$/;
// 共15位6位首次登记机关代码 + 8位顺序码 + 校验位
if (!rFormat.test(value)) {
isValid = false;
} else {
var s = [],
p = [10];
for (var i = 0; i < 15; i++) {
s[i] = (p[i] % 11) + (+value.charAt(i));
p[i + 1] = (s[i] % 10 || 10) * 2;
}
if (1 !== s[14] % 10) {
isValid = false;
}
}
return isValid || "请填写正确的营业执照号";
},
// 统一社会信用代码
unicode: function (element) {
var value = element.value.replace(/^\s*|\s*$/g, ''),
isValid = true,
rFormat = /^[1-9A-GV][1239][1-9]\d{5}[A-Z\d]{8}[X\d][Y\d]/;
if (!rFormat.test(value)) {
isValid = false;
} else {
var code, Wi, Ci, sum, C9, C18;
// 计算组织机构代码校验位C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
code = value.slice(9, 17);
Wi = [3, 7, 9, 10, 5, 8, 4, 2];
Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 加权求和
sum = 0;
for (var i = 0; i < Wi.length; i++) {
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
}
C9 = 11 - (sum % 11);
if (C9 === 10) C9 = 'X';
else if (C9 === 11) C9 = 0;
C9 = '' + C9;
// 与校验位比对
if (C9 !== code.charAt(9)) {
isValid = false;
}
if (isValid) {
// 计算最后校验位C18 = 31 - MOD ( ∑(Ci*Wi), 31 )
code = value.slice(0, 17);
Wi = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
Ci = "0123456789ABCDEFGHJKLMNPQRTUWXY";
// 加权求和
sum = 0;
for (var i = 0; i < Wi.length; i++) {
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
}
C18 = 31 - (sum % 31);
if (C18 === 30) C18 = 'Y';
else if (C18 === 31) C18 = 0;
C18 = '' + C18;
// 与校验位比对
if (C18 !== code.charAt(18)) {
isValid = false;
}
}
}
return isValid || "请填写正确的统一社会信用代码";
}
},
display: function (elem) {
return $(elem).closest('.form-group').find(".control-label").text().replace(/\:/, '');
},
dataFilter: function (data) {
if (data.code === 1) {
return "";
} else {
return data.msg;
}
},
target: function (input) {
var target = $(input).data("target");
if (target && $(target).size() > 0) {
return $(target);
}
var $formitem = $(input).closest('.form-group'),
$msgbox = $formitem.find('span.msg-box');
if (!$msgbox.length) {
return [];
}
return $msgbox;
},
valid: function (ret) {
var that = this, submitBtn = $(".layer-footer [type=submit]", form);
that.holdSubmit();
$(".layer-footer [type=submit]", form).addClass("disabled");
//验证通过提交表单
Form.api.submit($(ret), function (data, ret) {
that.holdSubmit(false);
submitBtn.removeClass("disabled");
if (false === $(this).triggerHandler("success.form", [data, ret])) {
return false;
}
if (typeof success === 'function') {
if (false === success.call($(this), data, ret)) {
return false;
}
}
//提示及关闭当前窗口
var msg = ret.hasOwnProperty("msg") && ret.msg !== "" ? ret.msg : __('Operation completed');
parent.Toastr.success(msg);
parent.$(".btn-refresh").trigger("click");
var index = parent.Layer.getFrameIndex(window.name);
parent.Layer.close(index);
return false;
}, function (data, ret) {
that.holdSubmit(false);
if (false === $(this).triggerHandler("error.form", [data, ret])) {
return false;
}
submitBtn.removeClass("disabled");
if (typeof error === 'function') {
if (false === error.call($(this), data, ret)) {
return false;
}
}
}, submit);
return false;
}
}, form.data("validator-options") || {}));
//移除提交按钮的disabled类
$(".layer-footer [type=submit],.fixed-footer [type=submit],.normal-footer [type=submit]", form).removeClass("disabled");
},
selectpicker: function (form) {
//绑定select元素事件
if ($(".selectpicker", form).size() > 0) {
require(['bootstrap-select', 'bootstrap-select-lang'], function () {
$('.selectpicker', form).selectpicker();
});
}
},
selectpage: function (form) {
//绑定selectpage元素事件
if ($(".selectpage", form).size() > 0) {
require(['selectpage'], function () {
$('.selectpage', form).selectPage({
eAjaxSuccess: function (data) {
data.list = typeof data.rows !== 'undefined' ? data.rows : (typeof data.list !== 'undefined' ? data.list : []);
data.totalRow = typeof data.total !== 'undefined' ? data.total : (typeof data.totalRow !== 'undefined' ? data.totalRow : data.list.length);
return data;
}
});
});
//给隐藏的元素添加上validate验证触发事件
$(document).on("change", ".sp_hidden", function () {
$(this).trigger("validate");
});
$(document).on("change", ".sp_input", function () {
$(this).closest(".sp_container").find(".sp_hidden").trigger("change");
});
$(form).on("reset", function () {
setTimeout(function () {
$('.selectpage', form).selectPageClear();
}, 1);
});
}
},
cxselect: function (form) {
//绑定cxselect元素事件
if ($("[data-toggle='cxselect']", form).size() > 0) {
require(['cxselect'], function () {
$.cxSelect.defaults.jsonName = 'name';
$.cxSelect.defaults.jsonValue = 'value';
$.cxSelect.defaults.jsonSpace = 'data';
$("[data-toggle='cxselect']", form).cxSelect();
});
}
},
citypicker: function (form) {
//绑定城市远程插件
if ($("[data-toggle='city-picker']", form).size() > 0) {
require(['citypicker'], function () {
});
}
},
datetimepicker: function (form) {
//绑定日期时间元素事件
if ($(".datetimepicker", form).size() > 0) {
require(['bootstrap-datetimepicker'], function () {
var options = {
format: 'YYYY-MM-DD HH:mm:ss',
icons: {
time: 'fa fa-clock-o',
date: 'fa fa-calendar',
up: 'fa fa-chevron-up',
down: 'fa fa-chevron-down',
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-history',
clear: 'fa fa-trash',
close: 'fa fa-remove'
},
showTodayButton: true,
showClose: true
};
$('.datetimepicker', form).parent().css('position', 'relative');
$('.datetimepicker', form).datetimepicker(options);
});
}
},
daterangepicker: function (form) {
//绑定日期时间元素事件
if ($(".datetimerange", form).size() > 0) {
require(['bootstrap-daterangepicker'], function () {
var ranges = {};
ranges[__('Today')] = [Moment().startOf('day'), Moment().endOf('day')];
ranges[__('Yesterday')] = [Moment().subtract(1, 'days').startOf('day'), Moment().subtract(1, 'days').endOf('day')];
ranges[__('Last 7 Days')] = [Moment().subtract(6, 'days').startOf('day'), Moment().endOf('day')];
ranges[__('Last 30 Days')] = [Moment().subtract(29, 'days').startOf('day'), Moment().endOf('day')];
ranges[__('This Month')] = [Moment().startOf('month'), Moment().endOf('month')];
ranges[__('Last Month')] = [Moment().subtract(1, 'month').startOf('month'), Moment().subtract(1, 'month').endOf('month')];
var options = {
timePicker: false,
autoUpdateInput: false,
timePickerSeconds: true,
timePicker24Hour: true,
autoApply: true,
locale: {
format: 'YYYY-MM-DD HH:mm:ss',
customRangeLabel: __("Custom Range"),
applyLabel: __("Apply"),
cancelLabel: __("Clear"),
},
ranges: ranges,
};
var origincallback = function (start, end) {
$(this.element).val(start.format(options.locale.format) + " - " + end.format(options.locale.format));
$(this.element).trigger('blur');
};
$(".datetimerange", form).each(function () {
var callback = typeof $(this).data('callback') == 'function' ? $(this).data('callback') : origincallback;
$(this).on('apply.daterangepicker', function (ev, picker) {
callback.call(picker, picker.startDate, picker.endDate);
});
$(this).on('cancel.daterangepicker', function (ev, picker) {
$(this).val('').trigger('blur');
});
$(this).daterangepicker($.extend({}, options, $(this).data()), callback);
});
});
}
},
plupload: function (form) {
//绑定plupload上传元素事件
if ($(".plupload", form).size() > 0) {
Upload.api.plupload($(".plupload", form));
}
},
faselect: function (form) {
//绑定fachoose选择附件事件
if ($(".fachoose", form).size() > 0) {
$(".fachoose", form).on('click', function () {
var that = this;
var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
parent.Fast.api.open("general/attachment/select?element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype, __('Choose'), {
callback: function (data) {
var button = $("#" + $(that).attr("id"));
var maxcount = $(button).data("maxcount");
var input_id = $(button).data("input-id") ? $(button).data("input-id") : "";
maxcount = typeof maxcount !== "undefined" ? maxcount : 0;
if (input_id && data.multiple) {
var urlArr = [];
var inputObj = $("#" + input_id);
var value = $.trim(inputObj.val());
if (value !== "") {
urlArr.push(inputObj.val());
}
urlArr.push(data.url)
var result = urlArr.join(",");
if (maxcount > 0) {
var nums = value === '' ? 0 : value.split(/\,/).length;
var files = data.url !== "" ? data.url.split(/\,/) : [];
var remains = maxcount - nums;
if (files.length > remains) {
Toastr.error(__('You can choose up to %d file%s', remains));
return false;
}
}
inputObj.val(result).trigger("change");
} else {
$("#" + input_id).val(data.url).trigger("change");
}
}
});
return false;
});
}
},
fieldlist: function (form) {
//绑定fieldlist
if ($(".fieldlist", form).size() > 0) {
require(['dragsort', 'template'], function (undefined, Template) {
//刷新隐藏textarea的值
var refresh = function (name) {
var data = {};
var textarea = $("textarea[name='" + name + "']", form);
var container = textarea.closest("dl");
var template = container.data("template");
console.log(name, container);
$.each($("input,select", container).serializeArray(), function (i, j) {
var reg = /\[(\w+)\]\[(\w+)\]$/g;
var match = reg.exec(j.name);
if (!match)
return true;
match[1] = "x" + parseInt(match[1]);
if (typeof data[match[1]] == 'undefined') {
data[match[1]] = {};
}
data[match[1]][match[2]] = j.value;
});
var result = template ? [] : {};
$.each(data, function (i, j) {
if (j) {
if (!template) {
if (j.key != '') {
result[j.key] = j.value;
}
} else {
result.push(j);
}
}
});
textarea.val(JSON.stringify(result));
};
//监听文本框改变事件
$(document).on('change keyup', ".fieldlist input,.fieldlist textarea,.fieldlist select", function () {
refresh($(this).closest("dl").data("name"));
});
//追加控制
$(".fieldlist", form).on("click", ".btn-append,.append", function (e, row) {
var container = $(this).closest("dl");
var index = container.data("index");
var name = container.data("name");
var template = container.data("template");
var data = container.data();
index = index ? parseInt(index) : 0;
container.data("index", index + 1);
var row = row ? row : {};
var vars = {index: index, name: name, data: data, row: row};
var html = template ? Template(template, vars) : Template.render(Form.config.fieldlisttpl, vars);
$(html).insertBefore($(this).closest("dd"));
$(this).trigger("fa.event.appendfieldlist", $(this).closest("dd").prev());
});
//移除控制
$(".fieldlist", form).on("click", "dd .btn-remove", function () {
var container = $(this).closest("dl");
$(this).closest("dd").remove();
refresh(container.data("name"));
});
//拖拽排序
$("dl.fieldlist", form).dragsort({
itemSelector: 'dd',
dragSelector: ".btn-dragsort",
dragEnd: function () {
refresh($(this).closest("dl").data("name"));
},
placeHolderTemplate: "<dd></dd>"
});
//渲染数据
$(".fieldlist", form).each(function () {
var container = this;
var textarea = $("textarea[name='" + $(this).data("name") + "']", form);
if (textarea.val() == '') {
return true;
}
var template = $(this).data("template");
var json = {};
try {
json = JSON.parse(textarea.val());
} catch (e) {
}
$.each(json, function (i, j) {
$(".btn-append,.append", container).trigger('click', template ? j : {
key: i,
value: j
});
});
});
});
}
},
bindevent: function (form) {
},
slider: function (form) {
if ($(".slider", form).size() > 0) {
require(['bootstrap-slider'], function () {
$('.slider').removeClass('hidden').css('width', function (index, value) {
return $(this).parents('.form-control').width();
}).slider().on('slide', function (ev) {
var data = $(this).data();
if (typeof data.unit !== 'undefined') {
$(this).parents('.form-control').siblings('.value').text(ev.value + data.unit);
}
});
});
}
}
},
api: {
submit: function (form, success, error, submit) {
if (form.size() === 0)
return Toastr.error("表单未初始化完成,无法提交");
if (typeof submit === 'function') {
if (false === submit.call(form)) {
return false;
}
}
var type = form.attr("method").toUpperCase();
type = type && (type === 'GET' || type === 'POST') ? type : 'GET';
url = form.attr("action");
url = url ? url : location.href;
//修复当存在多选项元素时提交的BUG
var params = {};
var multipleList = $("[name$='[]']", form);
if (multipleList.size() > 0) {
var postFields = form.serializeArray().map(function (obj) {
return $(obj).prop("name");
});
$.each(multipleList, function (i, j) {
if (postFields.indexOf($(this).prop("name")) < 0) {
params[$(this).prop("name")] = '';
}
});
}
//调用Ajax请求方法
Fast.api.ajax({
type: type,
url: url,
data: form.serialize() + (Object.keys(params).length > 0 ? '&' + $.param(params) : ''),
dataType: 'json',
complete: function (xhr) {
var token = xhr.getResponseHeader('__token__');
if (token) {
$("input[name='__token__']", form).val(token);
}
}
}, function (data, ret) {
$('.form-group', form).removeClass('has-feedback has-success has-error');
if (data && typeof data === 'object') {
//刷新客户端token
if (typeof data.token !== 'undefined') {
$("input[name='__token__']", form).val(data.token);
}
//调用客户端事件
if (typeof data.callback !== 'undefined' && typeof data.callback === 'function') {
data.callback.call(form, data);
}
}
if (typeof success === 'function') {
if (false === success.call(form, data, ret)) {
return false;
}
}
}, function (data, ret) {
if (data && typeof data === 'object' && typeof data.token !== 'undefined') {
$("input[name='__token__']", form).val(data.token);
}
if (typeof error === 'function') {
if (false === error.call(form, data, ret)) {
return false;
}
}
});
return false;
},
bindevent: function (form, success, error, submit) {
form = typeof form === 'object' ? form : $(form);
var events = Form.events;
events.bindevent(form);
events.validator(form, success, error, submit);
events.selectpicker(form);
events.daterangepicker(form);
events.selectpage(form);
events.cxselect(form);
events.citypicker(form);
events.datetimepicker(form);
events.plupload(form);
events.faselect(form);
events.fieldlist(form);
events.slider(form);
},
custom: {}
},
};
return Form;
});