From bc28a96ade8c98ce78c1be03f45013bfbeec74d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=B1=E7=9C=A0=E4=BB=AA=E5=BC=8F?= <854085467@qq.com> Date: Mon, 20 Jul 2020 01:11:17 +0800 Subject: [PATCH] add iconPicker component and iconPicker document --- admin/data/menu.json | 8 + component/pear/css/pear-module/iconPicker.css | 3 + component/pear/css/pear.css | 3 +- component/pear/module/iconPicker.js | 400 ++++++++++++++++++ component/pear/pear.js | 3 +- view/document/iconPicker.html | 244 +++++++++++ view/document/popup.html | 2 +- 7 files changed, 660 insertions(+), 3 deletions(-) create mode 100644 component/pear/css/pear-module/iconPicker.css create mode 100644 component/pear/module/iconPicker.js create mode 100644 view/document/iconPicker.html diff --git a/admin/data/menu.json b/admin/data/menu.json index 7dc856b..d1ebecd 100644 --- a/admin/data/menu.json +++ b/admin/data/menu.json @@ -97,6 +97,14 @@ "type": 1, "openType": "_iframe", "href": "view/document/popup.html" + }, + { + "id": 210, + "title": "图标选择", + "icon": "layui-icon layui-icon-face-cry", + "type": 1, + "openType": "_iframe", + "href": "view/document/iconPicker.html" } ] }, diff --git a/component/pear/css/pear-module/iconPicker.css b/component/pear/css/pear-module/iconPicker.css new file mode 100644 index 0000000..4b01696 --- /dev/null +++ b/component/pear/css/pear-module/iconPicker.css @@ -0,0 +1,3 @@ +.layui-iconpicker .layui-anim{ + width: 300px!important; +} \ No newline at end of file diff --git a/component/pear/css/pear.css b/component/pear/css/pear.css index c962b31..b03a883 100644 --- a/component/pear/css/pear.css +++ b/component/pear/css/pear.css @@ -14,4 +14,5 @@ @import url("pear-module/link.css"); @import url("pear-module/step.css"); @import url("pear-module/tab.css"); -@import url("pear-module/tag.css"); \ No newline at end of file +@import url("pear-module/tag.css"); +@import url("pear-module/iconPicker.css"); \ No newline at end of file diff --git a/component/pear/module/iconPicker.js b/component/pear/module/iconPicker.js new file mode 100644 index 0000000..373e282 --- /dev/null +++ b/component/pear/module/iconPicker.js @@ -0,0 +1,400 @@ +/** + * Layui图标选择器 + * @author wujiawei0926@yeah.net + * @version 1.1 + */ + +layui.define(['laypage', 'form'], function (exports) { + "use strict"; + + var IconPicker =function () { + this.v = '1.1'; + }, _MOD = 'iconPicker', + _this = this, + $ = layui.jquery, + laypage = layui.laypage, + form = layui.form, + BODY = 'body', + TIPS = '请选择图标'; + + /** + * 渲染组件 + */ + IconPicker.prototype.render = function(options){ + var opts = options, + // DOM选择器 + elem = opts.elem, + // 数据类型:fontClass/unicode + type = opts.type == null ? 'fontClass' : opts.type, + // 是否分页: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(), + // 是否使用的class数据 + isFontClass = opts.type === 'fontClass', + // 初始化时input的值 + ORIGINAL_ELEM_VALUE = $(elem).val(), + TITLE = 'layui-select-title', + TITLE_ID = 'layui-select-title-' + tmp, + ICON_BODY = 'layui-iconpicker-' + tmp, + PICKER_BODY = 'layui-iconpicker-body-' + tmp, + PAGE_ID = 'layui-iconpicker-page-' + tmp, + LIST_BOX = 'layui-iconpicker-list-box', + selected = 'layui-form-selected', + unselect = 'layui-unselect'; + + var a = { + init: function () { + data = common.getData[type](); + + a.hideElem().createSelect().createBody().toggleSelect(); + a.preventEvent().inputListen(); + common.loadCss(); + + if (success) { + success(this.successHandle()); + } + + return a; + }, + successHandle: function(){ + var d = { + options: opts, + data: data, + id: tmp, + elem: $('#' + ICON_BODY) + }; + return d; + }, + /** + * 隐藏elem + */ + hideElem: function () { + $(elem).hide(); + return a; + }, + /** + * 绘制select下拉选择框 + */ + createSelect: function () { + var oriIcon = ''; + + // 默认图标 + if(ORIGINAL_ELEM_VALUE === '') { + if(isFontClass) { + ORIGINAL_ELEM_VALUE = 'layui-icon-circle-dot'; + } else { + ORIGINAL_ELEM_VALUE = ''; + } + } + + if (isFontClass) { + oriIcon = ''; + } else { + oriIcon += ORIGINAL_ELEM_VALUE; + } + oriIcon += ''; + + var selectHtml = '
' + + '
' + + '
'+ + '' + + oriIcon + + ''+ + '' + + '
'+ + '
' + + '
' + + '123' + + '
'; + $(elem).after(selectHtml); + 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 () { + // 获取数据 + var searchHtml = ''; + + if (search) { + searchHtml = ''; + } + + // 组合dom + var bodyHtml = '
' + + searchHtml + + '
'+ + '
'; + $('#' + ICON_BODY).find('.layui-anim').eq(0).html(bodyHtml); + a.search().createList().check().page(); + + return a; + }, + /** + * 绘制图标列表 + * @param text 模糊查询关键字 + * @returns {string} + */ + createList: function (text) { + var d = data, + l = d.length, + pageHtml = '', + listHtml = $('
')//'
'; + + // 计算分页数据 + var _limit = limit, // 每页显示数量 + _pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1), // 总计多少页 + _id = PAGE_ID; + + // 图标列表 + var icons = []; + + for (var i = 0; i < l; i++) { + var obj = d[i]; + + // 判断是否模糊查询 + if (text && obj.indexOf(text) === -1) { + continue; + } + + // 是否自定义格子宽度 + var style = ''; + if (cellWidth !== null) { + style += ' style="width:' + cellWidth + '"'; + } + + // 每个图标dom + var icon = '
'; + if (isFontClass){ + icon += ''; + } else { + icon += ''+ obj.replace('amp;', '') +''; + } + icon += '
'; + + icons.push(icon); + } + + // 查询出图标后再分页 + l = icons.length; + _pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1); + for (var i = 0; i < _pages; i++) { + // 按limit分块 + var lm = $('
'); + + for (var j = i * _limit; j < (i+1) * _limit && j < l; j++) { + lm.append(icons[j]); + } + + listHtml.append(lm); + } + + // 无数据 + if (l === 0) { + listHtml.append('

无数据

'); + } + + // 判断是否分页 + if (page){ + $('#' + PICKER_BODY).addClass('layui-iconpicker-body-page'); + pageHtml = '
' + + '
' + + '1/' + + ''+ _pages +'' + + ' ('+ l +')' + + '
' + + '
' + + ' ' + + ' ' + + '
' + + '
'; + } + + + $('#' + ICON_BODY).find('.layui-anim').find('.' + LIST_BOX).html('').append(listHtml).append(pageHtml); + return a; + }, + // 阻止Layui的一些默认事件 + 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) { + current=current-1; + $(icon + '[prev]').attr('data-index', current); + } else if (!isPrev && current < total){ + current=current+1; + $(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); + }); + return a; + }, + /** + * 点击选中图标 + */ + check: function () { + var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item'; + a.event('click', item, function (e) { + var el = $(e.currentTarget).find('.layui-icon'), + icon = ''; + if (isFontClass) { + var clsArr = el.attr('class').split(/[\s\n]/), + cls = clsArr[1], + icon = cls; + $('#' + TITLE_ID).find('.layui-iconpicker-item .layui-icon').html('').attr('class', clsArr.join(' ')); + } else { + var cls = el.html(), + icon = cls; + $('#' + TITLE_ID).find('.layui-iconpicker-item .layui-icon').html(icon); + } + + $('#' + ICON_BODY).removeClass(selected).addClass(unselect); + $(elem).val(icon).attr('value', icon); + // 回调 + if (click) { + click({ + icon: icon + }); + } + + }); + return a; + }, + // 监听原始input数值改变 + inputListen: function(){ + var el = $(elem); + a.event('change', elem, function(){ + var value = el.val(); + }) + // el.change(function(){ + + // }); + return a; + }, + event: function (evt, el, fn) { + $(BODY).on(evt, el, fn); + } + }; + + var common = { + /** + * 加载样式表 + */ + loadCss: function () { + var css = '.layui-iconpicker {max-width: 280px;}.layui-iconpicker .layui-anim{display:none;width:280px;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:100%;float:left;text-align:center;background:#fff;transition:all .3s;}.layui-iconpicker-icon i{line-height:38px;font-size:18px;}.layui-iconpicker-item > .layui-edge{left:70px;}.layui-iconpicker-item:hover{border-color:#D2D2D2!important;}.layui-iconpicker-item:hover .layui-iconpicker-icon{border-color:#D2D2D2!important;}.layui-iconpicker.layui-form-selected .layui-anim{display:block;}.layui-iconpicker-body{padding:6px;}.layui-iconpicker .layui-iconpicker-list{background-color:#fff;border:1px solid #ccc;border-radius:4px;}.layui-iconpicker .layui-iconpicker-icon-item{display:inline-block;width:21.1%;line-height:36px;text-align:center;cursor:pointer;vertical-align:top;height:36px;margin:4px;border:1px solid #ddd;border-radius:2px;transition:300ms;}.layui-iconpicker .layui-iconpicker-icon-item i.layui-icon{font-size:17px;}.layui-iconpicker .layui-iconpicker-icon-item:hover{background-color:#eee;border-color:#ccc;-webkit-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;-moz-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;box-shadow:0 0 2px #aaa,0 0 2px #fff inset;text-shadow:0 0 1px #fff;}.layui-iconpicker-search{position:relative;margin:0 0 6px 0;border:1px solid #e6e6e6;border-radius:2px;transition:300ms;}.layui-iconpicker-search:hover{border-color:#D2D2D2!important;}.layui-iconpicker-search .layui-input{cursor:text;display:inline-block;width:86%;border:none;padding-right:0;margin-top:1px;}.layui-iconpicker-search .layui-icon{position:absolute;top:11px;right:4%;}.layui-iconpicker-tips{text-align:center;padding:8px 0;cursor:not-allowed;}.layui-iconpicker-page{margin-top:6px;margin-bottom:-6px;font-size:12px;padding:0 2px;}.layui-iconpicker-page-count{display:inline-block;}.layui-iconpicker-page-operate{display:inline-block;float:right;cursor:default;}.layui-iconpicker-page-operate .layui-icon{font-size:12px;cursor:pointer;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit{display:none;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit:first-child{display:block;}'; + var $style = $('head').find('style[iconpicker]'); + if ($style.length === 0) { + $('head').append(''); + } + }, + /** + * 获取数据 + */ + getData: { + fontClass: function () { + var arr = ["layui-icon-rate-half","layui-icon-rate","layui-icon-rate-solid","layui-icon-cellphone","layui-icon-vercode","layui-icon-login-wechat","layui-icon-login-qq","layui-icon-login-weibo","layui-icon-password","layui-icon-username","layui-icon-refresh-3","layui-icon-auz","layui-icon-spread-left","layui-icon-shrink-right","layui-icon-snowflake","layui-icon-tips","layui-icon-note","layui-icon-home","layui-icon-senior","layui-icon-refresh","layui-icon-refresh-1","layui-icon-flag","layui-icon-theme","layui-icon-notice","layui-icon-website","layui-icon-console","layui-icon-face-surprised","layui-icon-set","layui-icon-template-1","layui-icon-app","layui-icon-template","layui-icon-praise","layui-icon-tread","layui-icon-male","layui-icon-female","layui-icon-camera","layui-icon-camera-fill","layui-icon-more","layui-icon-more-vertical","layui-icon-rmb","layui-icon-dollar","layui-icon-diamond","layui-icon-fire","layui-icon-return","layui-icon-location","layui-icon-read","layui-icon-survey","layui-icon-face-smile","layui-icon-face-cry","layui-icon-cart-simple","layui-icon-cart","layui-icon-next","layui-icon-prev","layui-icon-upload-drag","layui-icon-upload","layui-icon-download-circle","layui-icon-component","layui-icon-file-b","layui-icon-user","layui-icon-find-fill","layui-icon-loading","layui-icon-loading-1","layui-icon-add-1","layui-icon-play","layui-icon-pause","layui-icon-headset","layui-icon-video","layui-icon-voice","layui-icon-speaker","layui-icon-fonts-del","layui-icon-fonts-code","layui-icon-fonts-html","layui-icon-fonts-strong","layui-icon-unlink","layui-icon-picture","layui-icon-link","layui-icon-face-smile-b","layui-icon-align-left","layui-icon-align-right","layui-icon-align-center","layui-icon-fonts-u","layui-icon-fonts-i","layui-icon-tabs","layui-icon-radio","layui-icon-circle","layui-icon-edit","layui-icon-share","layui-icon-delete","layui-icon-form","layui-icon-cellphone-fine","layui-icon-dialogue","layui-icon-fonts-clear","layui-icon-layer","layui-icon-date","layui-icon-water","layui-icon-code-circle","layui-icon-carousel","layui-icon-prev-circle","layui-icon-layouts","layui-icon-util","layui-icon-templeate-1","layui-icon-upload-circle","layui-icon-tree","layui-icon-table","layui-icon-chart","layui-icon-chart-screen","layui-icon-engine","layui-icon-triangle-d","layui-icon-triangle-r","layui-icon-file","layui-icon-set-sm","layui-icon-add-circle","layui-icon-404","layui-icon-about","layui-icon-up","layui-icon-down","layui-icon-left","layui-icon-right","layui-icon-circle-dot","layui-icon-search","layui-icon-set-fill","layui-icon-group","layui-icon-friends","layui-icon-reply-fill","layui-icon-menu-fill","layui-icon-log","layui-icon-picture-fine","layui-icon-face-smile-fine","layui-icon-list","layui-icon-release","layui-icon-ok","layui-icon-help","layui-icon-chat","layui-icon-top","layui-icon-star","layui-icon-star-fill","layui-icon-close-fill","layui-icon-close","layui-icon-ok-circle","layui-icon-add-circle-fine"]; + return arr; + }, + unicode: function () { + return ["&#xe6c9;","&#xe67b;","&#xe67a;","&#xe678;","&#xe679;","&#xe677;","&#xe676;","&#xe675;","&#xe673;","&#xe66f;","&#xe9aa;","&#xe672;","&#xe66b;","&#xe668;","&#xe6b1;","&#xe702;","&#xe66e;","&#xe68e;","&#xe674;","&#xe669;","&#xe666;","&#xe66c;","&#xe66a;","&#xe667;","&#xe7ae;","&#xe665;","&#xe664;","&#xe716;","&#xe656;","&#xe653;","&#xe663;","&#xe6c6;","&#xe6c5;","&#xe662;","&#xe661;","&#xe660;","&#xe65d;","&#xe65f;","&#xe671;","&#xe65e;","&#xe659;","&#xe735;","&#xe756;","&#xe65c;","&#xe715;","&#xe705;","&#xe6b2;","&#xe6af;","&#xe69c;","&#xe698;","&#xe657;","&#xe65b;","&#xe65a;","&#xe681;","&#xe67c;","&#xe601;","&#xe857;","&#xe655;","&#xe770;","&#xe670;","&#xe63d;","&#xe63e;","&#xe654;","&#xe652;","&#xe651;","&#xe6fc;","&#xe6ed;","&#xe688;","&#xe645;","&#xe64f;","&#xe64e;","&#xe64b;","&#xe62b;","&#xe64d;","&#xe64a;","&#xe64c;","&#xe650;","&#xe649;","&#xe648;","&#xe647;","&#xe646;","&#xe644;","&#xe62a;","&#xe643;","&#xe63f;","&#xe642;","&#xe641;","&#xe640;","&#xe63c;","&#xe63b;","&#xe63a;","&#xe639;","&#xe638;","&#xe637;","&#xe636;","&#xe635;","&#xe634;","&#xe633;","&#xe632;","&#xe631;","&#xe630;","&#xe62f;","&#xe62e;","&#xe62d;","&#xe62c;","&#xe629;","&#xe628;","&#xe625;","&#xe623;","&#xe621;","&#xe620;","&#xe61f;","&#xe61c;","&#xe60b;","&#xe619;","&#xe61a;","&#xe603;","&#xe602;","&#xe617;","&#xe615;","&#xe614;","&#xe613;","&#xe612;","&#xe611;","&#xe60f;","&#xe60e;","&#xe60d;","&#xe60c;","&#xe60a;","&#xe609;","&#xe605;","&#xe607;","&#xe606;","&#xe604;","&#xe600;","&#xe658;","&#x1007;","&#x1006;","&#x1005;","&#xe608;"]; + } + } + }; + + a.init(); + return new IconPicker(); + }; + + /** + * 选中图标 + * @param filter lay-filter + * @param iconName 图标名称,自动识别fontClass/unicode + */ + IconPicker.prototype.checkIcon = function (filter, iconName){ + var el = $('*[lay-filter='+ filter +']'), + p = el.next().find('.layui-iconpicker-item .layui-icon'), + c = iconName; + + if (c.indexOf('#xe') > 0){ + p.html(c); + } else { + p.html('').attr('class', 'layui-icon ' + c); + } + el.attr('value', c).val(c); + }; + + var iconPicker = new IconPicker(); + exports(_MOD, iconPicker); +}); \ No newline at end of file diff --git a/component/pear/pear.js b/component/pear/pear.js index 160f235..27bf4b3 100644 --- a/component/pear/pear.js +++ b/component/pear/pear.js @@ -20,5 +20,6 @@ layui.config({ notice: "notice", step:"step", tag:"tag", - popup:"popup" + popup:"popup", + iconPicker:"iconPicker" }); diff --git a/view/document/iconPicker.html b/view/document/iconPicker.html new file mode 100644 index 0000000..d552cea --- /dev/null +++ b/view/document/iconPicker.html @@ -0,0 +1,244 @@ + + + + + + + Document + + + +
+
+
+
开发环境
+
+ IconPicker 提供图标选择功能 +
+
+
+
+
+
+

显示代码

+
+
+								
+								 并
+								
+								 并
+								
+							
+
+
+
+
+
+
+
+ 默认图标 +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+

显示代码

+
+
+								layui.use(['iconPicker'], function() {
+								    var iconPicker = layui.iconPicker;
+								
+								    iconPicker.render({
+								        elem: '#iconPicker',
+								        type: 'fontClass',
+								        search: true,
+								        page: true,
+								        limit: 16,
+								        click: function(data) {
+								           console.log(data);
+								        },
+								        success: function(d) {
+								            console.log(d);
+								        }
+								    });
+									
+								});
+							
+
+
+
+
+
+
+
默认选中
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+

显示代码

+
+
+								layui.use(['iconPicker'], function() {
+								    var iconPicker = layui.iconPicker;
+								
+								    iconPicker.render({
+								        elem: '#iconPicker2',
+								        type: 'fontClass',
+								        search: true,
+								        page: true,
+								        limit: 16,
+								        click: function(data) {
+								           console.log(data);
+								        },
+								        success: function(d) {
+								            console.log(d);
+								        }
+								    });
+									
+								});
+							
+
+
+
+
+
+
+
不分页
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+

显示代码

+
+
+								layui.use(['iconPicker'], function() {
+								    var iconPicker = layui.iconPicker;
+								
+								    iconPicker.render({
+								        elem: '#iconPicker',
+								        type: 'fontClass',
+								        search: true,
+								        page: false,
+								        limit: 16,
+								        click: function(data) {
+								           console.log(data);
+								        },
+								        success: function(d) {
+								            console.log(d);
+								        }
+								    });
+									
+								});
+							
+
+
+
+
+
+ + + + + diff --git a/view/document/popup.html b/view/document/popup.html index db7201b..f411f04 100644 --- a/view/document/popup.html +++ b/view/document/popup.html @@ -11,7 +11,7 @@
开发环境
- Popup 基于 Layer 的二次封装 + Popup 基于 Layer 的 二次封装, 提供简洁高效的 API 调用