You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

478 lines
22 KiB

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.

layui.define(['laypage', 'form'], function (exports) {
"use strict";
// 定义 IconPicker 构造函数
var IconPicker = function () {
// 设置版本号为1.1
this.v = '1.1';
}, _MOD = 'iconPickerFa',
// 使用 _this 存储当前的 this 上下文
_this = this,
// 引入 jQuery
$ = layui.jquery,
// 引入 laypage 模块
laypage = layui.laypage,
// 引入 form 模块
form = layui.form,
// 定义 BODY 选择器
BODY = 'body',
// 定义提示信息
TIPS = '请选择图标';
})
IconPicker.prototype.render = function (options) {
// 渲染图标选择器的方法
var opts = options,
// DOM选择器
elem = opts.elem,
// 数据类型fontClass/unicode
url = opts.url,
// 是否分页true/false
page = opts.page == null ? true : opts.page,
// 每页显示数量
limit = opts.limit == null ? 12 : opts.limit,
// 是否开启搜索true/false
search = opts.search == null ? true : opts.search,
// 每个图标格子的宽度:'43px'或'20%'
cellWidth = opts.cellWidth,
// 点击图标后的回调函数
click = opts.click,
// 渲染成功后的回调函数
success = opts.success,
// 存储图标数据的json对象
data = {},
// 唯一标识符,基于当前时间戳生成
tmp = new Date().getTime(),
// 初始化时input的值
ORIGINAL_ELEM_VALUE = $(elem).val(),
// 下拉标题的类名
TITLE = 'layui-select-title',
// 下拉标题的唯一ID
TITLE_ID = 'layui-select-title-' + tmp,
// 图标选择器主体的唯一ID
ICON_BODY = 'layui-iconpicker-' + tmp,
// 图标选择器内容区域的唯一ID
PICKER_BODY = 'layui-iconpicker-body-' + tmp,
// 图标选择器分页区域的唯一ID
PAGE_ID = 'layui-iconpicker-page-' + tmp,
// 图标列表容器的类名
LIST_BOX = 'layui-iconpicker-list-box',
// 表单项选中状态的类名
selected = 'layui-form-selected',
// 表单项未选中状态的类名
unselect = 'layui-unselect';
var a = {
// 初始化函数,设置基本数据并绑定事件
init: function () {
// 从指定URL获取数据
data = common.getData(url);
// 隐藏元素、创建选择框、创建主体内容、切换选择状态
a.hideElem().createSelect().createBody().toggleSelect();
// 防止默认事件和监听输入事件
a.preventEvent().inputListen();
// 加载CSS样式
common.loadCss();
// 如果成功回调函数存在,则调用成功处理函数
if (success) {
success(this.successHandle());
}
// 返回当前对象以支持链式调用
return a;
},
// 处理成功后的数据返回
successHandle: function () {
// 创建一个包含选项、数据、ID和元素的对象
var d = {
options: opts,
data: data,
id: tmp,
elem: $('#' + ICON_BODY)
};
// 返回创建的对象
return d;
},
hideElem: function () {
// 隐藏指定的元素
$(elem).hide();
// 返回变量 a
return a;
},
createSelect: function () {
// 定义一个变量oriIcon并赋值为包含图标类名的HTML字符串
var oriIcon = '<i class="fa">';
// 如果ORIGINAL_ELEM_VALUE为空字符串
if (ORIGINAL_ELEM_VALUE === '') {
// 将ORIGINAL_ELEM_VALUE设置为默认图标类名'fa-adjust'
ORIGINAL_ELEM_VALUE = 'fa-adjust';
}
createSelect: 该方法用于创建一个选择元素主要用于图标选择功能
// 创建原始图标的HTML字符串使用ORIGINAL_ELEM_VALUE作为图标类名
oriIcon = '<i class="fa ' + ORIGINAL_ELEM_VALUE + '">';
// 关闭原始图标的HTML标签
oriIcon += '</i>';
// 创建选择器HTML字符串包含标题和图标选择区域
var selectHtml = '<div class="layui-iconpicker layui-unselect layui-form-select" id="' + ICON_BODY + '">' +
'<div class="' + TITLE + '" id="' + TITLE_ID + '">' +
'<div class="layui-iconpicker-item">' +
'<span class="layui-iconpicker-icon layui-unselect">' +
// 插入原始图标HTML
oriIcon +
'</span>' +
// 添加一个用于显示边缘效果的图标
'<i class="layui-edge"></i>' +
'</div>' +
'</div>' +
'<div class="layui-anim layui-anim-upbit" style="">' +
// 占位符内容,可能是将来要替换的内容
'123' +
'</div>';
// 在目标元素之后插入生成的选择器HTML
$(elem).after(selectHtml);
// 返回变量a假设是函数的返回值
return a;
toggleSelect: function () {
// 切换图标的选中状态
var item = '#' + TITLE_ID + ' .layui-iconpicker-item,#' + TITLE_ID + ' .layui-iconpicker-item .layui-edge';
a.event('click', item, function (e) {
// 获取图标元素
var $icon = $('#' + ICON_BODY);
if ($icon.hasClass(selected)) {
// 如果图标已经被选中,则取消选中状态
$icon.removeClass(selected).addClass(unselect);
} else {
// 隐藏其他picker
$('.layui-form-select').removeClass(selected);
// 显示当前picker并设置为选中状态
$icon.addClass(selected).removeClass(unselect);
}
// 阻止事件冒泡
e.stopPropagation();
});
}
return a;
},
createBody: function () {
// 初始化搜索框的 HTML 内容为空字符串
var searchHtml = '';
// 如果 search 为真,则创建搜索框的 HTML 结构
if (search) {
searchHtml = '<div class="layui-iconpicker-search">' +
'<input class="layui-input">' +
'<i class="layui-icon">&#xe615;</i>' +
'</div>';
}
}
// 组合dom
// 创建包含图标选择器主体的HTML字符串并设置其ID为PICKER_BODY
var bodyHtml = '<div class="layui-iconpicker-body" id="' + PICKER_BODY + '">' +
// 添加搜索框的HTML内容
searchHtml +
// 添加一个空的列表容器,用于显示图标列表
'<div class="' + LIST_BOX + '"></div> ' +
'</div>';
// 在指定的ICON_BODY元素中找到第一个带有layui-anim类的元素并将其HTML内容替换为bodyHtml
$('#' + ICON_BODY).find('.layui-anim').eq(0).html(bodyHtml);
// 调用a对象的search方法创建图标列表检查图标状态并进行分页处理
a.search().createList().check().page();
// 返回对象a
return a;
createList: function (text) {
// 创建列表的函数,根据传入的文本过滤图标数据
var d = data, // 获取全局数据
l = d.length, // 获取数据长度
pageHtml = '', // 初始化分页HTML字符串
listHtml = $('<div class="layui-iconpicker-list">'); // 创建一个包含类名'layui-iconpicker-list'的div元素
// 计算分页数据
var _limit = limit, // 每页显示数量
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1), // 计算总页数如果整除则直接除否则加1取整
_id = PAGE_ID; // 获取当前页面ID
// 图标列表
var icons = [];
for (var i = 0; i < l; i++) {
var obj = d[i];
// 判断是否模糊查询如果text存在且obj中不包含text则跳过当前循环
if (text && obj.indexOf(text) === -1) {
continue;
}
// 初始化样式字符串为空
var style = '';
// 如果自定义格子宽度不为空
if (cellWidth !== null) {
// 将自定义的格子宽度添加到样式字符串中
style += ' style="width:' + cellWidth + '"';
}
// 创建一个包含图标的HTML字符串
var icon = '<div class="layui-iconpicker-icon-item" title="' + obj + '" ' + style + '>';
// 在div中添加一个i元素并设置其class为FontAwesome图标类名
icon += '<i class="fa ' + obj + '"></i>';
// 关闭div标签
icon += '</div>';
// 将生成的图标HTML字符串添加到icons数组中
icons.push(icon);
// 查询出图标后再分页
// 获取图标数组的长度
l = icons.length;
// 计算总页数如果图标总数不能被每页限制数量整除则总页数加1
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1);
// 循环遍历每一页
for (var i = 0; i < _pages; i++) {
// 创建一个新的div元素用于存放当前页的图标并设置其class和id
var lm = $('<div class="layui-iconpicker-icon-limit" id="layui-iconpicker-icon-limit-' + tmp + (i + 1) + '">');
// 循环遍历当前页的所有图标
for (var j = i * _limit; j < (i + 1) * _limit && j < l; j++) {
// 将当前图标添加到当前页的div中
lm.append(icons[j]);
}
// 将当前页的div添加到列表的HTML中
listHtml.append(lm);
}
// 根据图标的数量和每页显示的限制,将图标分页并添加到列表中
// 无数据
if (l === 0) {
listHtml.append('<p class="layui-iconpicker-tips">无数据</p>');
}
// 判断是否分页
// 检查是否存在分页参数
if (page) {
// 为图标选择器主体添加分页样式类
$('#' + PICKER_BODY).addClass('layui-iconpicker-body-page');
// 生成分页HTML结构
pageHtml = '<div class="layui-iconpicker-page" id="' + PAGE_ID + '">' +
'<div class="layui-iconpicker-page-count">' +
'<span id="' + PAGE_ID + '-current">1</span>/' +
'<span id="' + PAGE_ID + '-pages">' + _pages + '</span>' +
' (<span id="' + PAGE_ID + '-length">' + l + '</span>)' +
'</div>' +
'<div class="layui-iconpicker-page-operate">' +
'<i class="layui-icon" id="' + PAGE_ID + '-prev" data-index="0" prev>&#xe603;</i> ' +
'<i class="layui-icon" id="' + PAGE_ID + '-next" data-index="2" next>&#xe602;</i> ' +
'</div>' +
'</div>';
}
// 清空并更新列表和分页的HTML内容
$('#' + ICON_BODY).find('.layui-anim').find('.' + LIST_BOX).html('').append(listHtml).append(pageHtml);
return a;
},
preventEvent: function () {
// 定义需要绑定事件的元素选择器
var item = '#' + ICON_BODY + ' .layui-anim';
// 为元素绑定点击事件,阻止事件冒泡
a.event('click', item, function (e) {
e.stopPropagation();
});
return a;
},
// 分页功能
page: function () {
// 获取分页操作图标的选择器
var icon = '#' + PAGE_ID + ' .layui-iconpicker-page-operate .layui-icon';
// 解除之前绑定的点击事件
$(icon).unbind('click');
// 为分页操作图标绑定点击事件
a.event('click', icon, function (e) {
// 获取当前点击的元素
var elem = e.currentTarget,
// 获取总页数
total = parseInt($('#' + PAGE_ID + '-pages').html()),
// 判断是否为上一页按钮
isPrev = $(elem).attr('prev') !== undefined,
// 获取按钮上的页码索引
index = parseInt($(elem).attr('data-index')),
// 获取当前显示页码的元素
$cur = $('#' + PAGE_ID + '-current'),
// 获取当前显示的页码
current = parseInt($cur.html());
// 分页数据
if (isPrev && current > 1) {
// 如果点击的是上一页且当前页码大于1则将当前页码减1
current = current - 1;
// 更新上一页图标的data-index属性为新的当前页码
$(icon + '[prev]').attr('data-index', current);
} else if (!isPrev && current < total) {
// 如果点击的是下一页且当前页码小于总页数则将当前页码加1
current = current + 1;
// 更新下一页图标的data-index属性为新的当前页码
$(icon + '[next]').attr('data-index', current);
}
// 更新当前页码显示
$cur.html(current);
// 图标数据
// 隐藏所有图标限制元素
$('#' + ICON_BODY + ' .layui-iconpicker-icon-limit').hide();
// 显示对应页码的图标限制元素
$('#layui-iconpicker-icon-limit-' + tmp + current).show();
// 阻止事件冒泡
e.stopPropagation();
});
return a;
},
search: function () {
// 为图标搜索输入框绑定输入事件监听器
var item = '#' + PICKER_BODY + ' .layui-iconpicker-search .layui-input';
a.event('input propertychange', item, function (e) {
// 获取输入框元素及其值
var elem = e.target,
t = $(elem).val();
// 根据输入值创建图标列表
a.createList(t);
});
// 返回模块对象 a
return a;
},
// 定义一个名为 check 的函数,用于处理图标选择器的点击事件
check: function () {
// 选择图标项的 CSS 选择器
var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item';
// 为图标项添加点击事件监听器
a.event('click', item, function (e) {
// 获取当前点击的图标元素和图标类名
var el = $(e.currentTarget).find('.fa'),
icon = '';
// 分割图标的 class 属性,提取图标类名
var clsArr = el.attr('class').split(/[\s\n]/),
cls = clsArr[1],
icon = cls;
// 更新标题区域显示的图标
$('#' + TITLE_ID).find('.layui-iconpicker-item .fa').html('').attr('class', clsArr.join(' '));
// 移除所有图标的选中状态并设置当前图标的选中状态
$('#' + ICON_BODY).removeClass(selected).addClass(unselect);
// 设置输入框的值为当前图标的类名
$(elem).val(icon).attr('value', icon);
// 回调函数,如果存在则执行
if (click) {
click({
icon: icon
});
}
});
// 返回对象 a
return a;
},
// 监听原始input数值改变
inputListen: function () {
// 获取元素并转换为jQuery对象
var el = $(elem);
// 为元素绑定'change'事件监听器
a.event('change', elem, function () {
// 获取元素的当前值
var value = el.val();
})
// 返回对象a
return a;
},
// 绑定事件到指定元素
event: function (evt, el, fn) {
// 使用jQuery在BODY元素上绑定事件处理函数
$(BODY).on(evt, el, fn);
}
var common = {
// 加载CSS样式函数
loadCss: function () {
var css = '.layui-iconpicker {max-width: 280px;}.layui-iconpicker .layui-anim{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box;}.layui-iconpicker-item{border:1px solid #e6e6e6;width:90px;height:38px;border-radius:4px;cursor:pointer;position:relative;}.layui-iconpicker-icon{border-right:1px solid #e6e6e6;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;width:60px;height
// 获取数据的函数
getData: function (url) {
// 初始化图标列表数组
var iconlist = [];
// 发起同步的AJAX请求以获取数据
$.ajax({
url: url,
type: 'get',
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
async: false,
// 请求成功时的回调函数
success: function (ret) {
// 正则表达式用于匹配图标名称
var exp = /fa-var-(.*):/ig;
var result;
// 遍历匹配结果并将图标名称添加到列表中
while ((result = exp.exec(ret)) != null) {
iconlist.push('fa-' + result[1]);
}
},
// 请求失败时的回调函数
error: function (xhr, textstatus, thrown) {
layer.msg('fa图标接口有误');
}
});
// 返回获取到的图标列表
return iconlist;
}
};
a.init();
return new IconPicker();
};
IconPicker.prototype.checkIcon = function (filter, iconName) {
// 根据过滤器找到对应的元素获取其下一个元素中的图标项并设置当前图标名为c
var el = $('*[lay-filter=' + filter + ']'),
p = el.next().find('.layui-iconpicker-item .fa'),
c = iconName;
// 检查图标名是否包含'#xe'如果包含则直接设置图标内容否则设置图标类名为c
if (c.indexOf('#xe') > 0) {
p.html(c);
} else {
p.html('').attr('class', 'fa ' + c);
}
// 设置元素的value属性和实际值为当前图标名c
el.attr('value', c).val(c);
};
var iconPicker = new IconPicker();
// 导出iconPicker模块
exports(_MOD, iconPicker);
});