123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- import '../jquery-form/jquery.form.min';
- let formCallbacks = {
- before: [], success: [], error: []
- };
- class Form {
- constructor(options) {
- let _this = this;
- _this.options = $.extend({
- // 表单的 jquery 对象或者css选择器
- form: null,
- // 开启表单验证
- validate: false,
- // 确认弹窗
- confirm: {title: null, content: null},
- // 是否使用Toastr展示字段验证错误信息
- validationErrorToastr: false,
- // 表单错误信息class
- errorClass: 'has-error',
- // 表单错误信息容器选择器
- errorContainerSelector: '.with-errors',
- // 表单组css选择器
- groupSelector: '.form-group,.form-label-group,.form-field',
- // tab表单css选择器
- tabSelector: '.tab-pane',
- // 错误信息模板
- errorTemplate: '<label class="control-label" for="inputError"><i class="feather icon-x-circle"></i> {message}</label><br/>',
- // 是否允许跳转
- redirect: true,
- // 自动移除表单错误信息
- autoRemoveError: true,
- // 表单提交之前事件监听,返回false可以中止表单继续提交
- before: function () {},
- // 表单提交之后事件监听,返回false可以中止后续逻辑
- after: function () {},
- // 成功事件,返回false可以中止后续逻辑
- success: function () {},
- // 失败事件,返回false可以中止后续逻辑
- error: function () {},
- }, options);
- _this.originalValues = {};
- _this.$form = $(_this.options.form).first();
- _this._errColumns = {};
- _this.init();
- }
- init() {
- let _this = this;
- let confirm = _this.options.confirm;
- if (! confirm.title) {
- return _this.submit();
- }
- Dcat.confirm(confirm.title, confirm.content, function () {
- _this.submit();
- });
- }
- submit() {
- let _this = this,
- $form = _this.$form,
- options = _this.options,
- $submitButton = $form.find('[type="submit"],.submit');
- // 移除所有错误信息
- _this.removeErrors();
- $form.ajaxSubmit({
- beforeSubmit: function (fields, form, _opt) {
- if (options.before(fields, form, _opt, _this) === false) {
- return false;
- }
- // 触发全局事件
- if (fire(formCallbacks.before, fields, form, _opt, _this) === false) {
- return false;
- }
- // 开启表单验证
- if (options.validate) {
- $form.validator('validate');
- if ($form.find('.' + options.errorClass).length > 0) {
- return false;
- }
- }
- $submitButton.buttonLoading();
- },
- success: function (response) {
- setTimeout(function () {
- $submitButton.buttonLoading(false);
- }, 700);
- if (options.after(true, response, _this) === false) {
- return;
- }
- if (options.success(response, _this) === false) {
- return;
- }
- if (fire(formCallbacks.success, response, _this) === false) {
- return;
- }
- if (response.redirect === false || ! options.redirect) {
- if (response.data && response.data.then) {
- delete response.data['then']['redirect'];
- delete response.data['then']['location'];
- delete response.data['then']['refresh'];
- }
- }
- Dcat.handleJsonResponse(response);
- },
- error: function (response) {
- $submitButton.buttonLoading(false);
- if (options.after(false, response, _this) === false) {
- return;
- }
- if (options.error(response, _this) === false) {
- return;
- }
- if (fire(formCallbacks.error, response, _this) === false) {
- return;
- }
- try {
- var error = JSON.parse(response.responseText),
- key;
- if (response.status != 422 || ! error || ! Dcat.helpers.isset(error, 'errors')) {
- return Dcat.error(response.status + ' ' + response.statusText);
- }
- error = error.errors;
- for (key in error) {
- // 显示错误信息
- _this._errColumns[key] = _this.showError($form, key, error[key]);
- }
- } catch (e) {
- return Dcat.error(response.status + ' ' + response.statusText);
- }
- }
- });
- }
- // 显示错误信息
- showError($form, column, errors) {
- let _this = this,
- $field = _this.queryFieldByName($form, column),
- $group = $field.closest(_this.options.groupSelector),
- render = function (msg) {
- $group.addClass(_this.options.errorClass);
- if (typeof msg === 'string') {
- msg = [msg];
- }
- for (let j in msg) {
- $group.find(_this.options.errorContainerSelector).first().append(
- _this.options.errorTemplate.replace('{message}', msg[j])
- );
- }
- if (_this.options.validationErrorToastr) {
- Dcat.error(msg.join('<br/>'));
- }
- };
- queryTabTitleError(_this, $field).removeClass('d-none');
- // 保存字段原始数据
- _this.originalValues[column] = _this.getFieldValue($field);
- if (! $field) {
- if (Dcat.helpers.len(errors) && errors.length) {
- Dcat.error(errors.join(" \n "));
- }
- return;
- }
- render(errors);
- if (_this.options.autoRemoveError) {
- removeErrorWhenValChanged(_this, $field, column);
- }
- return $field;
- }
- // 获取字段值
- getFieldValue($field) {
- let vals = [],
- type = $field.attr('type'),
- checker = type === 'checkbox' || type === 'radio',
- i;
- for (i = 0; i < $field.length; i++) {
- if (checker) {
- vals.push($($field[i]).prop('checked'));
- continue;
- }
- vals.push($($field[i]).val());
- }
- return vals;
- }
- // 判断值是否改变
- isValueChanged($field, column) {
- return ! Dcat.helpers.equal(this.originalValues[column], this.getFieldValue($field));
- }
- // 获取字段jq对象
- queryFieldByName($form, column) {
- if (column.indexOf('.') !== -1) {
- column = column.split('.');
- let first = column.shift(),
- i,
- sub = '';
- for (i in column) {
- sub += '[' + column[i] + ']';
- }
- column = first + sub;
- }
- var $c = $form.find('[name="' + column + '"]');
- if (!$c.length) $c = $form.find('[name="' + column + '[]"]');
- if (!$c.length) {
- $c = $form.find('[name="' + column.replace(/start$/, '') + '"]');
- }
- if (!$c.length) {
- $c = $form.find('[name="' + column.replace(/end$/, '') + '"]');
- }
- if (!$c.length) {
- $c = $form.find('[name="' + column.replace(/start\]$/, ']') + '"]');
- }
- if (!$c.length) {
- $c = $form.find('[name="' + column.replace(/end\]$/, ']') + '"]');
- }
- return $c;
- }
- // 移除给定字段的错误信息
- removeError($field, column) {
- let options = this.options,
- parent = $field.parents(options.groupSelector),
- errorClass = this.errorClass;
- parent.removeClass(errorClass);
- parent.find(options.errorContainerSelector).html('');
- // tab页下没有错误信息了,隐藏title的错误图标
- let tab;
- if (! queryTabByField(this, $field).find('.'+errorClass).length) {
- tab = queryTabTitleError(this, $field);
- if (! tab.hasClass('d-none')) {
- tab.addClass('d-none');
- }
- }
- delete this._errColumns[column];
- }
- // 删除所有错误信息
- removeErrors() {
- let _this = this,
- column,
- tab;
- // 移除所有字段的错误信息
- _this.$form.find(_this.options.errorContainerSelector).each(function (_, $err) {
- $($err).parents(_this.options.groupSelector).removeClass(_this.options.errorClass);
- $($err).html('');
- });
- // 移除tab表单tab标题错误信息
- for (column in _this._errColumns) {
- tab = queryTabTitleError(_this._errColumns[column]);
- if (! tab.hasClass('d-none')) {
- tab.addClass('d-none');
- }
- }
- // 重置
- _this._errColumns = {};
- }
- }
- // 监听表单提交事件
- Form.submitting = function (callback) {
- typeof callback == 'function' && (formCallbacks.before.push(callback));
- return this
- };
- // 监听表单提交完毕事件
- Form.submitted = function (success, error) {
- typeof success == 'function' && (formCallbacks.success.push(success));
- typeof error == 'function' && (formCallbacks.error.push(error));
- return this
- };
- // 当字段值变化时移除错误信息
- function removeErrorWhenValChanged(form, $field, column) {
- let remove = function () {
- form.removeError($field, column)
- };
- $field.one('change', remove);
- $field.off('blur', remove).on('blur', function () {
- if (form.isValueChanged($field, column)) {
- remove();
- }
- });
- // 表单值发生变化就移除错误信息
- let interval = function () {
- setTimeout(function () {
- if (! $field.length) {
- return;
- }
- if (form.isValueChanged($field, column)) {
- return remove();
- }
- interval();
- }, 500);
- };
- interval();
- }
- function getTabId(form, $field) {
- return $field.parents(form.options.tabSelector).attr('id');
- }
- function queryTabByField(form, $field)
- {
- let tabId = getTabId(form, $field);
- if (! tabId) {
- return $('<none></none>');
- }
- return $(`a[href="#${tabId}"]`);
- }
- function queryTabTitleError(form, $field) {
- return queryTabByField(form, $field).find('.has-tab-error');
- }
- // 触发钩子事件
- function fire(callbacks) {
- let i, j,
- result,
- args = arguments,
- argsArr = [];
- delete args[0];
- args = args || [];
- for (j in args) {
- argsArr.push(args[j]);
- }
- for (i in callbacks) {
- result = callbacks[i].apply(callbacks[i], argsArr);
- if (result === false) {
- return result; // 返回 false 会代码阻止继续执行
- }
- }
- }
- // 开启form表单模式
- $.fn.form = function (options) {
- let $this = $(this);
- options = $.extend(options, {
- form: $this,
- });
- $this.on('submit', function () {
- return false;
- });
- $this.find('[type="submit"],.submit').click(function (e) {
- Dcat.Form(options);
- return false;
- });
- };
- export default Form
|