/**
* Layui 文本输入工具组件
*
* @author iTanken
* @since 20200310
*/
layui.define(['jquery'], function (exports) {
var $ = layui.$, baseClassName = 'layext-text-tool', extClassName = 'layext-textool-pane',
style, alignRight = true, alignClass, nodes = [], tools = {
"hide": null, "count": null, "copy": null, "reset": null, "clear": null,
hideIndex: -1, countIndex: -1, copyIndex: -1, resetIndex: -1, clearIndex: -1,
hideName: "hide", countName: "count", copyName: "copy", resetName: "reset", clearName: "clear",
hideClass: "layext-textool-minmax", countClass: "layext-textool-count", maxClass: "layext-textool-max",
copyClass: "layext-textool-copy", resetClass: "layext-textool-reset", clearClass: "layext-textool-clear",
copyTextId: baseClassName + '-copy-text', lengthClass: 'layext-textool-length',
lengthOverClass: baseClassName + '-length-over', laytips: 'layext-textool-laytips'
}, defaultOptions = {
// 根据元素 id 值单独渲染,为空默认根据 class='layext-text-tool' 批量渲染
eleId: null,
// 批量设置输入框最大长度,可结合 eleId 单独设置最大长度
maxlength: -1,
// 初始化回调,无参
initEnd: $.noop,
// 显示回调,参数为当前输入框和工具条面板的 jQuery 对象
showEnd: $.noop,
// 隐藏回调,参数为当前输入框和工具条面板的 jQuery 对象
hideEnd: $.noop,
// 初始化展开,默认展开,否则收起
initShow: true,
// 工具条是否位于输入框内部,默认位于外部
inner: false,
// 工具条对齐方向,默认右对齐,可选左对齐 'left'
align: 'right',
// 启用指定工具模块,默认依次为字数统计、复制内容、重置内容、清空内容,按数组顺序显示
tools: ['count', 'copy', 'reset', 'clear'],
// 工具按钮提示类型,默认为 'title' 属性,可选 'laytips',使用 layer 组件的吸附提示, 其他值不显示提示
tipType: 'title',
// 吸附提示背景颜色
tipColor: '#01AAED',
// 工具条字体颜色
color: '#666666',
// 工具条背景颜色
bgColor: '#FFFFFF',
// 工具条边框颜色
borderColor: '#E6E6E6',
// 工具条附加样式类名
className: '',
// z-index
zIndex: 19891014
}, Class = function (custom) {
var _this = this;
_this.tipsAttr = null;
_this.selector = null;
_this.init(_this, custom || {});
};
/** 初始化 */
Class.prototype.init = function (_this, custom) {
_this.options = $.extend({}, defaultOptions, custom);
_this.selector = $.trim(_this.options.eleId) === '' ? '.' + baseClassName : '#' + _this.options.eleId;
_this.initStyle(_this);
_this.initPrototype();
$(_this.selector).each(function (i, n) {
var $this = $(this), maxlength = _this.options.maxlength;
!isNaN(maxlength) && maxlength > -1 && $this.attr('maxlength', maxlength);
_this.addTextool(_this, $this);
});
_this.initTips(_this);
typeof _this.options.initEnd === 'function' && _this.options.initEnd();
};
/** 初始化扩展样式 */
Class.prototype.initStyle = function (_this) {
_this.options.zIndex = isNaN(_this.options.zIndex) ? 0 : _this.options.zIndex || 0;
style = [''].join('');
$('head link:last')[0] && $('head link:last').after(style) || $('head').append(style);
};
/** 初始化默认方法,处理 JS 兼容问题 */
Class.prototype.initPrototype = function () {
// 获取数组元素下标
!Array.prototype.indexOf && (Array.prototype.indexOf = function (array, value) {
array = array || [];
for (var i = array.length; i--;) {
if (array[i] == value) {
return i;
}
}
return -1;
});
};
/** 添加文本工具 */
Class.prototype.addTextool = function (_this, $target) {
var $extPane = $target.next('.' + extClassName);
// 若已存在,则移除元素,支持重复渲染
$extPane && $extPane.length && $extPane.remove();
// 添加元素
$target.after(_this.getToolsNode(_this, $target));
$extPane = $target.next('.' + extClassName);
_this.setEvent(_this, $target, $extPane);
$extPane.fadeIn(200, function() {
!_this.options.initShow && $extPane.find('.' + tools.hideClass).trigger('click');
});
};
/** 复制文本 */
Class.prototype.copyText = function (_this, $target) {
if (!$target) {
return false;
}
!$('#' + tools.copyTextId).length && $('body').append('');
var $copy = $('#' + tools.copyTextId), value = $target.val();
$copy.val(value === '' ? ' ' : value).select();
document.execCommand('copy');
_this.showTip(_this, $target, '已复制!');
};
/** 设置内容长度 */
Class.prototype.setValLength = function (_this, $target) {
var $length = $target.next('.' + extClassName).find('.' + tools.countClass);
$length.text($target.val().length);
if ($target.val().length > $target.attr('maxlength')) {
$length.addClass(tools.lengthOverClass);
} else if ($length.hasClass(tools.lengthOverClass)) {
$length.removeClass(tools.lengthOverClass);
}
}
/** 设置工具条事件 */
Class.prototype.setEvent = function (_this, $target, $extPane) {
_this.setValLength(_this, $target);
var initValue = $target.val();
// 文本工具条按钮点击事件
$extPane.on('click', 'a', function (e) {
var $this = $(this), $icon = $this.children('i.layui-icon');
if ($this.hasClass(tools.hideClass)) {
// 收起展开按钮事件
$this.nextAll().toggle('fast');
$this.prevAll().toggle('fast');
if ($icon.hasClass('layui-icon-more')) {
$icon.removeClass('layui-icon-more').addClass('layui-icon-more-vertical');
$this.attr(_this.tipsAttr, '展开');
typeof _this.options.hideEnd === 'function' && _this.options.hideEnd($target, $extPane);
} else {
$icon.removeClass('layui-icon-more-vertical').addClass('layui-icon-more');
$this.attr(_this.tipsAttr, '收起');
typeof _this.options.showEnd === 'function' && _this.options.showEnd($target, $extPane);
}
_this.tipsAttr === tools.laytips && _this.showTip(_this, $this, $this.attr(_this.tipsAttr));
}
if ($this.hasClass(tools.copyClass)) {
// 复制按钮事件
_this.copyText(_this, $target);
}
if ($this.hasClass(tools.resetClass)) {
// 重置按钮事件
$target.val(initValue);
_this.setValLength(_this, $target);
}
if ($this.hasClass(tools.clearClass)) {
// 清空按钮事件
$target.val('');
_this.setValLength(_this, $target);
}
layui.stope(e);
return false;
});
// 字数统计事件
$target.on('keyup input', function (e) {
_this.setValLength(_this, $target);
layui.stope(e);
return false;
});
};
/** 获取工具条节点 */
Class.prototype.getToolsNode = function (_this, $target) {
if (!$target) return false;
// 总是显示收起展开按钮
tools.hide = [''].join('');
// 至少显示一个工具模块
_this.options.tools = _this.options.tools || [tools.countName];
// 字数统计
tools.countIndex = _this.options.tools.indexOf(tools.countName);
if (tools.countIndex > -1) {
var maxlength = $target.attr('maxlength') || -1;
tools.count = ['0',
(maxlength < 0 ? '' : ['/', maxlength, ''].join('')), ''].join('');
}
// 复制内容
tools.copyIndex = _this.options.tools.indexOf(tools.copyName);
if (tools.copyIndex > -1) {
tools.copy = [''].join('');
}
// 重置内容
tools.resetIndex = _this.options.tools.indexOf(tools.resetName);
if (tools.resetIndex > -1) {
tools.reset = [''].join('');
}
// 清空内容
tools.clearIndex = _this.options.tools.indexOf(tools.clearName);
if (tools.clearIndex > -1) {
tools.clear = [''].join('');
}
if (_this.options.align === 'left') {
// 居左对齐
alignRight = false;
alignClass = extClassName + '-l';
} else {
// 居右对其
alignRight = true;
alignClass = extClassName + '-r';
}
// 处理工具条节点
nodes = [''];
!alignRight && nodes.push(tools.hide);
for (var i = 0; i < _this.options.tools.length; i++) {
nodes.push(tools[_this.options.tools[i]] || '');
}
alignRight && nodes.push(tools.hide);
nodes.push('');
return nodes.join('');
};
/** 获取提示信息属性 */
Class.prototype.getTips = function (_this, msg) {
switch (_this.options.tipType) {
case 'title':
_this.tipsAttr = 'title';
break;
case 'laytips':
_this.tipsAttr = tools.laytips;
break;
default:
return '';
}
return [' ', _this.tipsAttr, '=', msg, ' '].join('');
};
/** 初始化吸附提示 */
Class.prototype.initTips = function (_this) {
$('[' + tools.laytips + ']').each(function (i, n) {
var $target = $(n);
if ($.trim($target.attr(_this.tipsAttr)) !== '') {
$target.hover(function () {
_this.showTip(_this, $target, $target.attr(_this.tipsAttr));
}, _this.hideTip);
}
});
};
/** 显示吸附提示 */
Class.prototype.showTip = function (_this, $target, msg) {
_this.hideTip();
layui.layer.tips(msg, $target, { tips: [1, _this.options.tipColor || '#01AAED'], time: 2e3, anim: 5, zIndex: (_this.options.zIndex || 0) + 2 });
};
/** 隐藏吸附提示 */
Class.prototype.hideTip = function () {
layui.layer.closeAll('tips');
};
exports('textool', {
/** 初始化入口方法 */
init: function (custom) {
return new Class(custom);
}
});
});