516 lines
28 KiB
JavaScript
516 lines
28 KiB
JavaScript
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
|
|
|
|
var Controller = {
|
|
index: function () {
|
|
Table.api.init({
|
|
extend: {
|
|
index_url: 'split.link/index' + location.search,
|
|
add_url: 'split.link/add',
|
|
edit_url: 'split.link/edit',
|
|
del_url: 'split.link/del',
|
|
multi_url: 'split.link/multi',
|
|
table: 'split_link',
|
|
}
|
|
});
|
|
|
|
var table = $("#table");
|
|
|
|
table.bootstrapTable({
|
|
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
|
pk: 'id',
|
|
sortName: 'id',
|
|
sortOrder: 'desc',
|
|
fixedColumns: true,
|
|
fixedRightNumber: 1,
|
|
columns: [
|
|
[
|
|
{checkbox: true},
|
|
{field: 'countries_text', title: __('Countries'), operate: false, formatter: Table.api.formatter.content},
|
|
{
|
|
field: 'link_code',
|
|
title: __('Link_code'),
|
|
operate: 'LIKE',
|
|
formatter: Controller.api.formatter.linkCode
|
|
},
|
|
{field: 'description', title: __('Description'), operate: 'LIKE', class: 'autocontent', formatter: Table.api.formatter.content},
|
|
{
|
|
field: 'auto_reply_text',
|
|
title: __('Reply statements column'),
|
|
operate: false,
|
|
class: 'autocontent',
|
|
hover: true,
|
|
formatter: Controller.api.formatter.autoReplyText
|
|
},
|
|
{field: 'ip_protect', title: __('Ip_protect'), searchList: Config.ipProtectList, formatter: Table.api.formatter.status},
|
|
{field: 'random_shuffle', title: __('Random_shuffle'), searchList: Config.randomShuffleList, formatter: Table.api.formatter.status},
|
|
{field: 'status', title: __('Status'), searchList: Config.statusList, formatter: Table.api.formatter.status},
|
|
{field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false, formatter: Table.api.formatter.datetime, sortable: true},
|
|
{
|
|
field: 'operate',
|
|
title: __('Operate'),
|
|
table: table,
|
|
events: Table.api.events.operate,
|
|
buttons: [
|
|
{
|
|
name: 'autoreply',
|
|
text: __('Auto reply'),
|
|
title: __('Auto reply'),
|
|
icon: 'fa fa-commenting-o',
|
|
classname: 'btn btn-warning btn-xs btn-split-autoreply',
|
|
url: 'javascript:;'
|
|
}
|
|
],
|
|
formatter: Table.api.formatter.operate
|
|
}
|
|
]
|
|
]
|
|
});
|
|
|
|
table.on('click', '.btn-copy-split-link', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var linkCode = $.trim($(this).data('link-code') || '');
|
|
if (!linkCode) {
|
|
return false;
|
|
}
|
|
Controller.api.openCopyModal(linkCode);
|
|
});
|
|
|
|
table.on('click', '.btn-copy-link-code-inline', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var linkCode = $.trim($(this).data('link-code') || '');
|
|
if (linkCode) {
|
|
Controller.api.copyText(linkCode);
|
|
}
|
|
});
|
|
|
|
table.on('click', '.btn-split-autoreply', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
e.stopImmediatePropagation();
|
|
var rowIndex = $(this).data('row-index');
|
|
var row = Table.api.getrowbyindex(table, rowIndex);
|
|
if (!row || !row.id) {
|
|
return false;
|
|
}
|
|
Controller.api.openAutoReplyModal(row);
|
|
});
|
|
|
|
Table.api.bindevent(table);
|
|
},
|
|
add: function () {
|
|
Controller.api.bindevent();
|
|
Controller.api.bindLinkCodeInput();
|
|
},
|
|
edit: function () {
|
|
Controller.api.bindevent();
|
|
},
|
|
api: {
|
|
/** 弹窗样式(仅注入一次) */
|
|
modalStyleInjected: false,
|
|
injectModalStyles: function () {
|
|
if (Controller.api.modalStyleInjected) {
|
|
return;
|
|
}
|
|
Controller.api.modalStyleInjected = true;
|
|
var css = [
|
|
'.split-link-copy-modal{padding:16px 20px;box-sizing:border-box;}',
|
|
'.split-link-copy-modal .form-group{margin-bottom:16px;}',
|
|
'.split-link-copy-modal .control-label{display:block;font-weight:600;color:#444;margin-bottom:8px;}',
|
|
'.split-link-copy-modal .split-link-code-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;}',
|
|
'.split-link-copy-modal .split-link-code-value{font-size:18px;font-weight:600;color:#337ab7;text-decoration:underline;word-break:break-all;}',
|
|
'.split-link-copy-modal .split-domain-tabs{margin-bottom:0;border-bottom:1px solid #ddd;}',
|
|
'.split-link-copy-modal .split-domain-tab-box{border:1px solid #ddd;border-top:none;border-radius:0 0 4px 4px;background:#fafafa;overflow:hidden;}',
|
|
'.split-link-copy-modal .split-domain-tab-box .tab-pane{max-height:280px;overflow-y:auto;overflow-x:hidden;padding:10px 12px;margin:0;}',
|
|
'.split-link-copy-modal .split-domain-list{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:stretch;}',
|
|
'.split-link-copy-modal .split-domain-item{border:1px solid #e8e8e8;border-radius:4px;background:#fff;transition:border-color .2s,box-shadow .2s;height:100%;min-width:0;}',
|
|
'.split-link-copy-modal .split-domain-item:hover{border-color:#b8d4f0;}',
|
|
'.split-link-copy-modal .split-domain-item.is-checked{border-color:#337ab7;box-shadow:0 0 0 1px rgba(51,122,183,.15);}',
|
|
'.split-link-copy-modal .split-domain-item-label{display:flex;align-items:flex-start;gap:8px;margin:0;padding:8px 10px;cursor:pointer;font-weight:normal;width:100%;height:100%;box-sizing:border-box;}',
|
|
'.split-link-copy-modal .split-domain-item-label input[type=radio]{margin:3px 0 0;flex-shrink:0;}',
|
|
'.split-link-copy-modal .split-domain-item-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px;}',
|
|
'.split-link-copy-modal .split-domain-name{font-size:13px;font-weight:600;color:#333;word-break:break-all;line-height:1.4;}',
|
|
'.split-link-copy-modal .split-domain-status{display:flex;flex-direction:column;align-items:flex-start;gap:4px;}',
|
|
'.split-link-copy-modal .split-domain-status .label{font-size:10px;font-weight:normal;padding:2px 6px;line-height:1.3;white-space:nowrap;margin:0;display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;}',
|
|
'.split-link-copy-modal .split-domain-empty{margin:0;padding:20px 12px;color:#999;text-align:center;line-height:1.6;grid-column:1/-1;}',
|
|
'.split-link-copy-modal .split-tip-box{margin:12px 0;padding:10px 12px;background:#f8f9fa;border-left:3px solid #337ab7;border-radius:0 4px 4px 0;line-height:1.6;color:#666;}',
|
|
'.split-link-copy-modal .split-generated-url{font-size:12px;}',
|
|
'.split-link-copy-modal .split-modal-footer{margin-top:16px;padding-top:12px;border-top:1px solid #eee;}'
|
|
].join('');
|
|
$('<style id="split-link-copy-modal-style" type="text/css"></style>').text(css).appendTo('head');
|
|
},
|
|
formatter: {
|
|
/**
|
|
* 回复语:单元格内省略,悬停显示完整内容
|
|
*/
|
|
autoReplyText: function (value, row, index) {
|
|
value = value == null ? '' : value.toString();
|
|
if (value === '') {
|
|
return '<span class="text-muted">-</span>';
|
|
}
|
|
var safe = Fast.api.escape(value);
|
|
return "<div class='autocontent-item autocontent-hover' style='white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:100%;display:block;' title='"
|
|
+ safe + "'>" + safe + "</div>";
|
|
},
|
|
/**
|
|
* 分流链接列:链接样式 + COPY 图标,点击链接打开弹窗
|
|
*/
|
|
linkCode: function (value) {
|
|
value = value == null ? '' : value.toString();
|
|
if (value === '') {
|
|
return '-';
|
|
}
|
|
var safe = Fast.api.escape(value);
|
|
return '<span class="split-link-code-cell">'
|
|
+ '<a href="javascript:;" class="btn-copy-split-link split-link-code-link" data-link-code="' + safe + '" style="font-weight:600;color:#337ab7;text-decoration:underline;">' + safe + '</a>'
|
|
+ ' <a href="javascript:;" class="btn-copy-link-code-inline text-primary" data-link-code="' + safe + '" title="' + __('Copy') + '"><i class="fa fa-copy"></i></a>'
|
|
+ '</span>';
|
|
}
|
|
},
|
|
openCopyModal: function (linkCode) {
|
|
Controller.api.loadCopyModalData(function (data) {
|
|
Controller.api.renderCopyModal(linkCode, data);
|
|
});
|
|
},
|
|
/**
|
|
* 打开自动回复弹窗
|
|
*
|
|
* @param {object} row 列表行数据
|
|
*/
|
|
openAutoReplyModal: function (row) {
|
|
Fast.api.ajax({
|
|
url: 'split.link/autoreply/ids/' + row.id,
|
|
type: 'get'
|
|
}, function (data, ret) {
|
|
var info = ret.data || data || {};
|
|
Controller.api.renderAutoReplyModal(row.id, info);
|
|
return false;
|
|
});
|
|
},
|
|
renderAutoReplyModal: function (linkId, info) {
|
|
var linkCode = Fast.api.escape(info.link_code || '');
|
|
var autoReply = info.auto_reply || '';
|
|
var html = [
|
|
'<div class="split-auto-reply-modal" style="padding:16px 20px;">',
|
|
' <div class="form-group">',
|
|
' <label class="control-label">' + __('Link_code') + '</label>',
|
|
' <p class="form-control-static" style="font-size:16px;font-weight:600;color:#337ab7;margin:0;">' + linkCode + '</p>',
|
|
' </div>',
|
|
' <div class="form-group" style="margin-bottom:0;">',
|
|
' <label class="control-label" for="split-auto-reply-text">' + __('Reply statements') + '</label>',
|
|
' <p class="help-block" style="margin-top:0;">' + __('Reply statements tip') + '</p>',
|
|
' <textarea id="split-auto-reply-text" class="form-control" rows="10" placeholder="">' + Fast.api.escape(autoReply) + '</textarea>',
|
|
' </div>',
|
|
'</div>'
|
|
].join('');
|
|
|
|
Layer.open({
|
|
type: 1,
|
|
title: __('Auto reply'),
|
|
area: ['520px', 'auto'],
|
|
shadeClose: false,
|
|
content: html,
|
|
btn: [__('OK'), __('Close')],
|
|
yes: function (index, layero) {
|
|
var text = layero.find('#split-auto-reply-text').val();
|
|
Fast.api.ajax({
|
|
url: 'split.link/autoreply/ids/' + linkId,
|
|
type: 'post',
|
|
data: {auto_reply: text}
|
|
}, function () {
|
|
Layer.close(index);
|
|
Toastr.success(__('Auto reply saved'));
|
|
});
|
|
return false;
|
|
}
|
|
});
|
|
},
|
|
loadCopyModalData: function (callback) {
|
|
Fast.api.ajax({
|
|
url: 'split.link/copyinfo',
|
|
type: 'get'
|
|
}, function (data, ret) {
|
|
callback(ret.data || data || {});
|
|
return false;
|
|
});
|
|
},
|
|
renderCopyModal: function (linkCode, data) {
|
|
Controller.api.injectModalStyles();
|
|
|
|
var platformDomains = $.isArray(data.platform_domains) ? data.platform_domains : [];
|
|
if (!platformDomains.length && data.platform_domain) {
|
|
var rawSingle = $.trim(data.platform_domain);
|
|
platformDomains = rawSingle.split(/[\r\n,]+/).map(function (d) {
|
|
return $.trim(d);
|
|
}).filter(function (d) {
|
|
return d.length > 0;
|
|
});
|
|
}
|
|
var myDomains = $.isArray(data.my_domains) ? data.my_domains : [];
|
|
var domainIndexUrl = data.domain_index_url || 'domain/index';
|
|
var configIndexUrl = data.config_index_url || 'general/config/index';
|
|
var defaultType = platformDomains.length ? 'platform' : 'my';
|
|
var defaultDomain = platformDomains.length ? platformDomains[0] : (myDomains.length ? myDomains[0].domain : '');
|
|
var activeTab = defaultType === 'platform' ? 'platform' : 'my';
|
|
|
|
var platformHtml = '';
|
|
if (platformDomains.length) {
|
|
var platformItems = [];
|
|
$.each(platformDomains, function (i, domain) {
|
|
platformItems.push(Controller.api.buildDomainRadio({
|
|
domain: domain,
|
|
type: 'platform',
|
|
checked: defaultType === 'platform' && domain === defaultDomain,
|
|
showStatus: false
|
|
}));
|
|
});
|
|
platformHtml = '<div class="split-domain-list">' + platformItems.join('') + '</div>';
|
|
} else {
|
|
platformHtml = '<p class="split-domain-empty">'
|
|
+ __('Split platform domain empty')
|
|
+ ' <a href="javascript:;" class="btn-goto-config">' + __('Go system config') + '</a>'
|
|
+ '</p>';
|
|
}
|
|
|
|
var myDomainsHtml = '';
|
|
if (myDomains.length) {
|
|
var items = [];
|
|
$.each(myDomains, function (i, item) {
|
|
items.push(Controller.api.buildDomainRadio({
|
|
domain: item.domain,
|
|
type: 'my',
|
|
checked: defaultType === 'my' && item.domain === defaultDomain,
|
|
nsText: item.ns_status_text || '',
|
|
dnsText: item.dns_status_text || '',
|
|
nsStatus: item.ns_status || '',
|
|
dnsStatus: item.dns_status || '',
|
|
showStatus: true
|
|
}));
|
|
});
|
|
myDomainsHtml = '<div class="split-domain-list">' + items.join('') + '</div>';
|
|
} else {
|
|
myDomainsHtml = '<p class="split-domain-empty">' + __('Split my domain empty') + '</p>';
|
|
}
|
|
|
|
var initialUrl = Controller.api.buildSplitUrl(defaultDomain, linkCode);
|
|
var safeLinkCode = Fast.api.escape(linkCode);
|
|
var html = [
|
|
'<div class="split-link-copy-modal">',
|
|
' <div class="form-group">',
|
|
' <label class="control-label">' + __('Link_code') + '</label>',
|
|
' <div class="split-link-code-row">',
|
|
' <a href="javascript:;" class="split-link-code-value" data-link-code="' + safeLinkCode + '">' + safeLinkCode + '</a>',
|
|
' <button type="button" class="btn btn-default btn-sm btn-copy-link-code" data-link-code="' + safeLinkCode + '" title="' + __('Copy') + '"><i class="fa fa-copy"></i></button>',
|
|
' <button type="button" class="btn btn-default btn-sm btn-manage-domain">' + __('Manage my domains') + '</button>',
|
|
' </div>',
|
|
' </div>',
|
|
' <div class="form-group">',
|
|
' <label class="control-label">' + __('Select main domain') + '</label>',
|
|
' <ul class="nav nav-tabs split-domain-tabs" role="tablist">',
|
|
' <li role="presentation"' + (activeTab === 'platform' ? ' class="active"' : '') + '>',
|
|
' <a href="#split-tab-platform" role="tab" data-toggle="tab">' + __('Platform assigned domain') + '</a>',
|
|
' </li>',
|
|
' <li role="presentation"' + (activeTab === 'my' ? ' class="active"' : '') + '>',
|
|
' <a href="#split-tab-my" role="tab" data-toggle="tab">' + __('My domains') + '</a>',
|
|
' </li>',
|
|
' </ul>',
|
|
' <div class="tab-content split-domain-tab-box">',
|
|
' <div role="tabpanel" class="tab-pane' + (activeTab === 'platform' ? ' active' : '') + '" id="split-tab-platform">' + platformHtml + '</div>',
|
|
' <div role="tabpanel" class="tab-pane' + (activeTab === 'my' ? ' active' : '') + '" id="split-tab-my">' + myDomainsHtml + '</div>',
|
|
' </div>',
|
|
' </div>',
|
|
' <div class="split-tip-box">',
|
|
__('Split domain prefix tip'),
|
|
' <button type="button" class="btn btn-xs btn-primary btn-go-add-domain">' + __('Go add domain') + '</button>',
|
|
' </div>',
|
|
' <div class="form-group" style="margin-bottom:0;">',
|
|
' <label class="control-label">' + __('Generated result') + '</label>',
|
|
' <div class="input-group">',
|
|
' <input type="text" class="form-control split-generated-url" readonly value="' + Fast.api.escape(initialUrl) + '">',
|
|
' <span class="input-group-btn">',
|
|
' <button type="button" class="btn btn-default btn-copy-generated-url"><i class="fa fa-copy"></i> ' + __('Copy') + '</button>',
|
|
' </span>',
|
|
' </div>',
|
|
' </div>',
|
|
' <div class="text-center split-modal-footer">',
|
|
' <button type="button" class="btn btn-success btn-open-test"' + (initialUrl ? '' : ' disabled') + '>' + __('Open test') + '</button>',
|
|
' <button type="button" class="btn btn-default btn-close-copy-modal">' + __('Close') + '</button>',
|
|
' </div>',
|
|
'</div>'
|
|
].join('');
|
|
|
|
Layer.open({
|
|
type: 1,
|
|
title: __('Copy split link'),
|
|
area: ['780px', 'auto'],
|
|
maxmin: false,
|
|
resize: false,
|
|
shadeClose: true,
|
|
content: html,
|
|
success: function (layero, index) {
|
|
var $box = layero.find('.split-link-copy-modal');
|
|
|
|
var refreshGeneratedUrl = function () {
|
|
var $checked = $box.find('input[name="split_main_domain"]:checked');
|
|
var domain = $.trim($checked.val() || '');
|
|
var url = Controller.api.buildSplitUrl(domain, linkCode);
|
|
$box.find('.split-generated-url').val(url);
|
|
$box.find('.btn-open-test').prop('disabled', url === '');
|
|
$box.find('.split-domain-item').removeClass('is-checked');
|
|
$checked.closest('.split-domain-item').addClass('is-checked');
|
|
};
|
|
|
|
var ensureTabSelection = function ($pane) {
|
|
var $radios = $pane.find('input[name="split_main_domain"]');
|
|
if ($radios.length && !$radios.filter(':checked').length) {
|
|
$radios.first().prop('checked', true);
|
|
}
|
|
};
|
|
|
|
$box.on('change', 'input[name="split_main_domain"]', refreshGeneratedUrl);
|
|
|
|
$box.on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
|
|
var target = $(e.target).attr('href');
|
|
if (target) {
|
|
ensureTabSelection($box.find(target));
|
|
refreshGeneratedUrl();
|
|
}
|
|
});
|
|
|
|
$box.on('click', '.btn-copy-link-code', function (e) {
|
|
e.preventDefault();
|
|
Controller.api.copyText(linkCode);
|
|
});
|
|
|
|
$box.on('click', '.btn-manage-domain, .btn-go-add-domain', function (e) {
|
|
e.preventDefault();
|
|
Layer.close(index);
|
|
Backend.api.addtabs(Fast.api.fixurl(domainIndexUrl), __('Manage my domains'), 'fa fa-globe');
|
|
});
|
|
|
|
$box.on('click', '.btn-goto-config', function (e) {
|
|
e.preventDefault();
|
|
Layer.close(index);
|
|
Backend.api.addtabs(Fast.api.fixurl(configIndexUrl), __('System config'), 'fa fa-cogs');
|
|
});
|
|
|
|
$box.on('click', '.btn-copy-generated-url', function (e) {
|
|
e.preventDefault();
|
|
var url = $.trim($box.find('.split-generated-url').val());
|
|
if (!url) {
|
|
Toastr.error(__('Split url empty'));
|
|
return;
|
|
}
|
|
Controller.api.copyText(url);
|
|
});
|
|
|
|
$box.on('click', '.btn-open-test', function (e) {
|
|
e.preventDefault();
|
|
var url = $.trim($box.find('.split-generated-url').val());
|
|
if (url) {
|
|
window.open(url, '_blank');
|
|
}
|
|
});
|
|
|
|
$box.on('click', '.btn-close-copy-modal', function (e) {
|
|
e.preventDefault();
|
|
Layer.close(index);
|
|
});
|
|
|
|
ensureTabSelection($box.find('.tab-pane.active'));
|
|
refreshGeneratedUrl();
|
|
}
|
|
});
|
|
},
|
|
buildDomainRadio: function (options) {
|
|
var domain = Fast.api.escape(options.domain || '');
|
|
var type = options.type || 'my';
|
|
var checked = options.checked ? ' checked' : '';
|
|
var checkedClass = options.checked ? ' is-checked' : '';
|
|
var statusHtml = '';
|
|
if (options.showStatus) {
|
|
statusHtml = '<span class="split-domain-status">'
|
|
+ '<span class="label ' + Controller.api.statusLabelClass(options.nsStatus) + '">NS:' + Fast.api.escape(options.nsText || '-') + '</span>'
|
|
+ '<span class="label ' + Controller.api.statusLabelClass(options.dnsStatus, true) + '">DNS:' + Fast.api.escape(options.dnsText || '-') + '</span>'
|
|
+ '</span>';
|
|
}
|
|
return '<div class="split-domain-item' + checkedClass + '">'
|
|
+ '<label class="split-domain-item-label">'
|
|
+ '<input type="radio" name="split_main_domain" value="' + domain + '" data-type="' + type + '"' + checked + '>'
|
|
+ '<span class="split-domain-item-body">'
|
|
+ '<span class="split-domain-name">' + domain + '</span>'
|
|
+ statusHtml
|
|
+ '</span>'
|
|
+ '</label>'
|
|
+ '</div>';
|
|
},
|
|
statusLabelClass: function (status, isDns) {
|
|
if (isDns) {
|
|
if (status === 'created') {
|
|
return 'label-success';
|
|
}
|
|
if (status === 'failed') {
|
|
return 'label-danger';
|
|
}
|
|
return 'label-warning';
|
|
}
|
|
if (status === 'verified') {
|
|
return 'label-success';
|
|
}
|
|
if (status === 'failed') {
|
|
return 'label-danger';
|
|
}
|
|
return 'label-warning';
|
|
},
|
|
buildSplitUrl: function (domain, linkCode) {
|
|
domain = $.trim(domain || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
linkCode = $.trim(linkCode || '');
|
|
if (!domain || !linkCode) {
|
|
return '';
|
|
}
|
|
return 'https://' + domain + '/s/' + linkCode;
|
|
},
|
|
copyText: function (text) {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
navigator.clipboard.writeText(text).then(function () {
|
|
Toastr.success(__('Copy success'));
|
|
}).catch(function () {
|
|
Controller.api.copyTextFallback(text);
|
|
});
|
|
return;
|
|
}
|
|
Controller.api.copyTextFallback(text);
|
|
},
|
|
copyTextFallback: function (text) {
|
|
var $temp = $('<textarea>').css({position: 'fixed', left: '-9999px', top: '0'}).val(text);
|
|
$('body').append($temp);
|
|
$temp[0].select();
|
|
try {
|
|
document.execCommand('copy');
|
|
Toastr.success(__('Copy success'));
|
|
} catch (e) {
|
|
Toastr.error(__('Copy failed'));
|
|
}
|
|
$temp.remove();
|
|
},
|
|
bindLinkCodeInput: function () {
|
|
var $input = $('#c-link_code');
|
|
if (!$input.length || $input.prop('readonly')) {
|
|
return;
|
|
}
|
|
$input.on('input', function () {
|
|
var val = $(this).val().replace(/[^a-zA-Z]/g, '').toLowerCase().slice(0, 9);
|
|
if ($(this).val() !== val) {
|
|
$(this).val(val);
|
|
}
|
|
});
|
|
},
|
|
bindevent: function () {
|
|
Form.api.bindevent($("form[role=form]"));
|
|
}
|
|
}
|
|
};
|
|
return Controller;
|
|
});
|