234 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| layui.define(['jquery', 'tools'], function (exports) {
 | |
| 	"use strict";
 | |
| 
 | |
| 	/**
 | |
| 	 * @since Pear Admin 4.0
 | |
| 	 * 
 | |
| 	 * Button component
 | |
| 	 * */
 | |
| 	var MOD_NAME = 'menuSearch',
 | |
| 		tools = layui.tools,
 | |
| 		$ = layui.jquery;
 | |
| 
 | |
| 	var menuSearch = function (opt) {
 | |
| 		this.option = opt;
 | |
| 	};
 | |
| 
 | |
| 	/**
 | |
| 	 * @since Pear Admin 4.0
 | |
| 	 * 
 | |
| 	 * Button start loading
 | |
| 	 * */
 | |
| 	menuSearch.prototype.render = function (opt) {
 | |
| 
 | |
| 		var options = {
 | |
| 			select: opt.select,
 | |
| 			elem: opt.elem,
 | |
| 			dataProvider: opt.dataProvider,
 | |
| 		}
 | |
| 
 | |
| 		$('body').on("click", options.elem, function () {
 | |
| 
 | |
| 			var _html = [
 | |
| 				`<div class="menu-search-content">
 | |
| 				  <div class="layui-form menu-search-input-wrapper">
 | |
| 				    <div class=" layui-input-wrap layui-input-wrap-prefix">
 | |
| 				      <div class="layui-input-prefix">
 | |
| 				        <i class="layui-icon layui-icon-search"></i>
 | |
| 				      </div>
 | |
| 				      <input type="text" name="menuSearch" value="" placeholder="搜索菜单" autocomplete="off" class="layui-input" lay-affix="clear">
 | |
| 				    </div>
 | |
| 				  </div>
 | |
| 				  <div class="menu-search-no-data">暂 无 信 息</div>
 | |
| 				  <ul class="menu-search-list">
 | |
| 				  </ul>
 | |
| 				  <div class="menu-search-tips">
 | |
| 				    <div>
 | |
| 				      <span class="mr-1">选择</span><kbd class="mr-1 w-5"> ↑ </kbd><kbd class="mr-5 w-5"> ↓ </kbd>
 | |
| 				      <span class="mr-1">确定</span><kbd class="mr-5"> Enter </kbd><span class="mr-1">关闭</span><kbd class="mr-1"> Esc </kbd>
 | |
| 				    </div>
 | |
| 				  </div>
 | |
| 				</div>`
 | |
| 			].join('');
 | |
| 
 | |
| 			layer.open({
 | |
| 				type: 1,
 | |
| 				offset: "10%",
 | |
| 				area: ['600px'],
 | |
| 				title: false,
 | |
| 				closeBtn: 0,
 | |
| 				shadeClose: true,
 | |
| 				anim: 0,
 | |
| 				move: false,
 | |
| 				content: _html,
 | |
| 				success: function (layero, layeridx) {
 | |
| 
 | |
| 					var $layer = layero;
 | |
| 					var $content = $(layero).children('.layui-layer-content');
 | |
| 					var $input = $(".menu-search-input-wrapper input");
 | |
| 					var $noData = $(".menu-search-no-data");
 | |
| 					var $list = $(".menu-search-list");
 | |
| 					var menuData = options.dataProvider();
 | |
| 
 | |
| 					$layer.css("border-radius", "6px");
 | |
| 					$input.off("focus").focus();
 | |
| 
 | |
| 					// 搜索输入事件
 | |
| 					$input.off("input").on("input", tools.debounce(function () {
 | |
| 						var keywords = $input.val().trim();
 | |
| 						var filteredMenus = filterHandle(menuData, keywords);
 | |
| 
 | |
| 						if (filteredMenus.length) {
 | |
| 							var tiledMenus = tiledHandle(filteredMenus);
 | |
| 							var listHtml = createList(tiledMenus);
 | |
| 							$noData.css("display", "none");
 | |
| 							$list.html("").append(listHtml).children(":first").addClass("this")
 | |
| 						} else {
 | |
| 							$list.html("");
 | |
| 							$noData.css("display", "flex");
 | |
| 						}
 | |
| 						var currentHeight = $(".menu-search-content").outerHeight()
 | |
| 						$layer.css("height", currentHeight);
 | |
| 						$content.css("height", currentHeight);
 | |
| 					}, 500)
 | |
| 					)
 | |
| 
 | |
| 					// 列表点击事件
 | |
| 					$list.off("click").on("click", "li", function () {
 | |
| 						var id = $(this).attr("smenu-id");
 | |
| 						var title = $(this).attr("smenu-title");
 | |
| 						var url = $(this).attr("smenu-url");
 | |
| 						var type = $(this).attr("smenu-type");
 | |
| 						var openType = $(this).attr("smenu-open-type");
 | |
| 
 | |
| 						options.select({ id, title, url, type, openType });
 | |
| 
 | |
| 						layer.close(layeridx);
 | |
| 					})
 | |
| 
 | |
| 					$list.off('mouseenter').on("mouseenter", "li", function () {
 | |
| 						$(".menu-search-list li.this").removeClass("this");
 | |
| 						$(this).addClass("this");
 | |
| 					}).off("mouseleave").on("mouseleave", "li", function () {
 | |
| 						$(this).removeClass("this");
 | |
| 					})
 | |
| 
 | |
| 					// 监听键盘事件
 | |
| 					$('.menu-search-content').off("keydown").keydown(function (e) {
 | |
| 						if (e.keyCode === 13 || e.keyCode === 32) {
 | |
| 							e.preventDefault();
 | |
| 							var that = $(".menu-search-list li.this");
 | |
| 							var id = that.attr("smenu-id");
 | |
| 							var title = that.attr("smenu-title");
 | |
| 							var url = that.attr("smenu-url");
 | |
| 							var type = that.attr("smenu-type");
 | |
| 							var openType = that.attr("smenu-open-type");
 | |
| 
 | |
| 							options.select({ id, title, url, type, openType });
 | |
| 
 | |
| 							layer.close(layeridx);
 | |
| 						} else if (e.keyCode === 38) {
 | |
| 							e.preventDefault();
 | |
| 							var prevEl = $(".menu-search-list li.this").prev();
 | |
| 							$(".menu-search-list li.this").removeClass("this");
 | |
| 							if (prevEl.length !== 0) {
 | |
| 								prevEl.addClass("this");
 | |
| 							} else {
 | |
| 								$list.children().last().addClass("this");
 | |
| 							}
 | |
| 						} else if (e.keyCode === 40) {
 | |
| 							e.preventDefault();
 | |
| 							var nextEl = $(".menu-search-list li.this").next();
 | |
| 							$(".menu-search-list li.this").removeClass("this");
 | |
| 							if (nextEl.length !== 0) {
 | |
| 								nextEl.addClass("this");
 | |
| 							} else {
 | |
| 								$list.children().first().addClass("this");
 | |
| 							}
 | |
| 						} else if (e.keyCode === 27) {
 | |
| 							e.preventDefault();
 | |
| 							layer.close(layeridx);
 | |
| 						}
 | |
| 					})
 | |
| 				}
 | |
| 			})
 | |
| 		});
 | |
| 
 | |
| 		return new menuSearch(options);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @since Pear Admin 4.0
 | |
| 	 * 
 | |
| 	 * 创建结果列表
 | |
| 	 */
 | |
| 	var createList = function (data) {
 | |
| 		var listHtml = '';
 | |
| 		$.each(data, function (index, item) {
 | |
| 			listHtml += `<li smenu-open-type="${item.info.openType}" smenu-id="${item.info.id}" smenu-icon="'${item.info.icon}" smenu-url="${item.info.href}" smenu-title="${item.info.title}" smenu-type="${item.info.type}">
 | |
| 			   <span><i style="margin-right:10px" class="${item.info.icon}"></i>${item.path}</span>
 | |
| 			   <i class="layui-icon layui-icon-right"></i>
 | |
| 			 </li>`
 | |
| 		})
 | |
| 		return listHtml;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @since Pear Admin 4.0
 | |
| 	 * 
 | |
| 	 * Tree 转 path 列表
 | |
| 	 */
 | |
| 	var tiledHandle = function (data) {
 | |
| 		var tiledMenus = [];
 | |
| 		var treeTiled = function (data, content) {
 | |
| 			var path = "";
 | |
| 			var separator = " / ";
 | |
| 			if (!content) content = "";
 | |
| 			$.each(data, function (index, item) {
 | |
| 				if (item.children && item.children.length) {
 | |
| 					path += content + item.title + separator;
 | |
| 					var childPath = treeTiled(item.children, path);
 | |
| 					path += childPath;
 | |
| 					if (!childPath) path = ""; // 重置路径
 | |
| 				} else {
 | |
| 					path += content + item.title
 | |
| 					tiledMenus.push({ path: path, info: item });
 | |
| 					path = ""; //重置路径
 | |
| 				}
 | |
| 			})
 | |
| 			return path;
 | |
| 		};
 | |
| 		treeTiled(data);
 | |
| 
 | |
| 		return tiledMenus;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @since Pear Admin 4.0
 | |
| 	 * 
 | |
| 	 * 查询匹配算法
 | |
| 	 */
 | |
| 	var filterHandle = function (filterData, val) {
 | |
| 		if (!val) return [];
 | |
| 		var filteredMenus = [];
 | |
| 		filterData = $.extend(true, {}, filterData);
 | |
| 		$.each(filterData, function (index, item) {
 | |
| 			if (item.children && item.children.length) {
 | |
| 				var children = filterHandle(item.children, val)
 | |
| 				var obj = $.extend({}, item, { children: children });
 | |
| 				if (children && children.length) {
 | |
| 					filteredMenus.push(obj);
 | |
| 				} else if (item.title.indexOf(val) >= 0) {
 | |
| 					item.children = []; // 父级匹配但子级不匹配,就去除子级
 | |
| 					filteredMenus.push($.extend({}, item));
 | |
| 				}
 | |
| 			} else if (item.title.indexOf(val) >= 0) {
 | |
| 				filteredMenus.push(item);
 | |
| 			}
 | |
| 		})
 | |
| 		return filteredMenus;
 | |
| 	}
 | |
| 
 | |
| 	exports(MOD_NAME, new menuSearch());
 | |
| });
 |