From d7fe3b19ab7a906b30ad8ba73e6cd56cb5deedef Mon Sep 17 00:00:00 2001 From: ZZJ <zzjdsg2300@163.com> Date: 星期一, 20 十二月 2021 19:12:09 +0800 Subject: [PATCH] 搜索 --- src/components/giantTree/zTree/ztree.vue | 341 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 286 insertions(+), 55 deletions(-) diff --git a/src/components/giantTree/zTree/ztree.vue b/src/components/giantTree/zTree/ztree.vue index b8e5024..147ccec 100644 --- a/src/components/giantTree/zTree/ztree.vue +++ b/src/components/giantTree/zTree/ztree.vue @@ -1,15 +1,25 @@ <template> - <div class="ztree" :id="ztreeId"></div> + <div> + <div class="search"> + <el-input placeholder="鎼滅储" v-model="keyWord"> + <i slot="suffix" class="el-input__icon el-icon-search" id="key"></i> + </el-input> + </div> + <div class="ztree" :id="ztreeId"></div> + </div> </template> <script> import * as $ from "jquery"; +import { Loading } from "element-ui"; + if (!window.jQuery) { window.jQuery = $; } // require("@ztree/ztree_v3/js/jquery.ztree.all"); require("./ztree_v3/jquery.ztree.all"); +require("./ztree_v3/jquery.ztree.exhide"); export default { props: { @@ -41,11 +51,11 @@ showLine: true, showIcon: true, // default to hide icon addHoverDom: this.addHoverDom, - removeHoverDom: this.removeHoverDom + removeHoverDom: this.removeHoverDom, }, check: { - chkboxType: { "Y": "", "N": "" }, - enable: this.showCheckbox + chkboxType: { Y: "", N: "" }, + enable: this.showCheckbox, }, callback: { onAsyncError: (...arg) => { @@ -59,6 +69,7 @@ }, onClick: (...arg) => { this.$emit("onClick", ...arg); + this.removeHoverIcon(...arg); }, onCollapse: (...arg) => { this.$emit("onCollapse", ...arg); @@ -95,6 +106,10 @@ }, }, }, + keyWord: "", + options: { + target: "", + }, }; }, watch: { @@ -112,6 +127,8 @@ Object.assign({}, this.ztreeSetting, this.setting), this.list ); + console.log("---------"); + this.fuzzySearch(this.ztreeObj, "#key", null, true); //鍒濆鍖栨ā绯婃悳绱㈡柟娉� this.$emit("onCreated", this.ztreeObj); }); }, @@ -120,6 +137,10 @@ }, showCheckbox: { handler: function () { + let top = $("#" + this.ztreeId) + .parent() + .scrollTop(); + this.ztreeSetting.check.enable = this.showCheckbox; if (this.ztreeObj) { @@ -132,11 +153,14 @@ Object.assign({}, this.ztreeSetting, this.setting), this.list ); + $("#" + this.ztreeId) + .parent() + .scrollTop(top); this.$emit("onCreated", this.ztreeObj); }); }, immediate: true, - } + }, }, methods: { addHoverDom(treeid, treeNode) { @@ -144,119 +168,311 @@ const item = document.getElementById(`${treeNode.tId}_a`); // 鏂囦欢澶规柊澧炴寜閽� - if (item && !item.querySelector('.el-icon-circle-plus-outline') && treeNode.isParent && !this.readonly && !this.gb28181) { - const btn = document.createElement('i'); + if ( + item && + !item.querySelector(".el-icon-circle-plus-outline") && + treeNode.isParent && + !this.readonly && + !this.gb28181 + ) { + const btn = document.createElement("i"); btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add('el-icon-circle-plus-outline'); - btn.classList.add('primary'); + btn.classList.add("el-icon-circle-plus-outline"); + btn.classList.add("primary"); // btn.innerText = '鍒犻櫎'; - btn.addEventListener('click', (e) => { - e.stopPropagation() + btn.addEventListener("click", (e) => { + e.stopPropagation(); // this.clickRemove(treeNode) _vue.$emit("onAddNode", treeNode); - }) + }); item.appendChild(btn); } // 鏂囦欢澶瑰垹闄ゆ寜閽� - if (item && !item.querySelector('.el-icon-remove-outline') && treeNode.isParent && !this.readonly && !treeNode.children && !this.gb28181) { - const btn = document.createElement('i'); + if ( + item && + !item.querySelector(".el-icon-remove-outline") && + treeNode.isParent && + !this.readonly && + !treeNode.children && + !this.gb28181 + ) { + const btn = document.createElement("i"); btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add('el-icon-remove-outline'); - btn.classList.add('danger'); + btn.classList.add("el-icon-remove-outline"); + btn.classList.add("danger"); // btn.innerText = '鍒犻櫎'; - btn.addEventListener('click', (e) => { - e.stopPropagation() + btn.addEventListener("click", (e) => { + e.stopPropagation(); // this.clickRemove(treeNode) _vue.$emit("onRemoveNode", treeNode); - }) + }); item.appendChild(btn); } // 鏂囦欢澶圭紪杈戞寜閽� - if (item && !item.querySelector('.el-icon-edit') && treeNode.isParent && !this.readonly) { - const btn = document.createElement('i'); + if ( + item && + !item.querySelector(".el-icon-edit") && + treeNode.isParent && + !this.readonly + ) { + const btn = document.createElement("i"); btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add('el-icon-edit'); - btn.classList.add('primary'); + btn.classList.add("el-icon-edit"); + btn.classList.add("primary"); // btn.innerText = '鍒犻櫎'; - btn.addEventListener('click', (e) => { - e.stopPropagation() + btn.addEventListener("click", (e) => { + e.stopPropagation(); // this.clickRemove(treeNode) _vue.$emit("onRenameNode", treeNode); - }) + }); item.appendChild(btn); } // 娣诲姞鎽勫儚鏈烘寜閽� - if (item && !item.querySelector('.iconshishishipin') && treeNode.isParent && !this.readonly && !this.gb28181) { - const btn = document.createElement('i'); + if ( + item && + !item.querySelector(".iconshishishipin") && + treeNode.isParent && + !this.readonly && + !this.gb28181 + ) { + const btn = document.createElement("i"); btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add('iconfont'); - btn.classList.add('iconshishishipin'); - btn.classList.add('primary'); - btn.classList.add('icon-fix'); + btn.classList.add("iconfont"); + btn.classList.add("iconshishishipin"); + btn.classList.add("primary"); + btn.classList.add("icon-fix"); // btn.innerText = '鍒犻櫎'; - btn.addEventListener('click', (e) => { - e.stopPropagation() + btn.addEventListener("click", (e) => { + e.stopPropagation(); // this.clickRemove(treeNode) _vue.$emit("onAddDevice", treeNode.id); - }) + }); item.appendChild(btn); } // 瀵煎叆鎽勫儚鏈烘寜閽� - if (item && !item.querySelector('.icondaoru') && treeNode.isParent && !this.readonly && !this.gb28181) { - const btn = document.createElement('i'); + if ( + item && + !item.querySelector(".icondaoru") && + treeNode.isParent && + !this.readonly && + !this.gb28181 + ) { + const btn = document.createElement("i"); btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add('iconfont'); - btn.classList.add('icondaoru'); - btn.classList.add('primary'); - btn.classList.add('icon-fix'); + btn.classList.add("iconfont"); + btn.classList.add("icondaoru"); + btn.classList.add("primary"); + btn.classList.add("icon-fix"); // btn.innerText = '鍒犻櫎'; - btn.addEventListener('click', (e) => { - e.stopPropagation() + btn.addEventListener("click", (e) => { + e.stopPropagation(); // this.clickRemove(treeNode) _vue.$emit("onImport", treeNode.id); - }) + }); + + item.appendChild(btn); + } + + // 鏌ョ湅搴曞浘鎸夐挳 + if ( + item && + !item.querySelector(".icontupian1") && + treeNode.type == "camera" + ) { + const btn = document.createElement("i"); + btn.id = `${treeid}_${treeNode.id}_btn`; + btn.classList.add("iconfont"); + btn.classList.add("icontupian1"); + btn.classList.add("primary"); + btn.classList.add("icon-fix"); + // btn.innerText = '鍒犻櫎'; + btn.addEventListener("click", (e) => { + e.stopPropagation(); + // this.clickRemove(treeNode) + _vue.$emit("onShowPic", treeNode); + }); item.appendChild(btn); } }, + removeHoverIcon(evt, treeId, item) { + this.removeHoverDom(treeId, item); + }, removeHoverDom(treeid, treeNode) { const item = document.getElementById(`${treeNode.tId}_a`); if (item) { - let btn = item.querySelector('.el-icon-circle-plus-outline'); + let btn = item.querySelector(".el-icon-circle-plus-outline"); if (btn) { - item.removeChild(item.querySelector('.el-icon-circle-plus-outline')) + item.removeChild(item.querySelector(".el-icon-circle-plus-outline")); } - btn = item.querySelector('.el-icon-remove-outline'); + btn = item.querySelector(".el-icon-remove-outline"); if (btn) { - item.removeChild(item.querySelector('.el-icon-remove-outline')) + item.removeChild(item.querySelector(".el-icon-remove-outline")); } - btn = item.querySelector('.el-icon-edit'); + btn = item.querySelector(".el-icon-edit"); if (btn) { - item.removeChild(item.querySelector('.el-icon-edit')) + item.removeChild(item.querySelector(".el-icon-edit")); } - btn = item.querySelector('.iconshishishipin'); + btn = item.querySelector(".iconshishishipin"); if (btn) { - item.removeChild(item.querySelector('.iconshishishipin')) + item.removeChild(item.querySelector(".iconshishishipin")); } - btn = item.querySelector('.icondaoru'); + btn = item.querySelector(".icondaoru"); if (btn) { - item.removeChild(item.querySelector('.icondaoru')) + item.removeChild(item.querySelector(".icondaoru")); + } + + btn = item.querySelector(".icontupian1"); + if (btn) { + item.removeChild(item.querySelector(".icontupian1")); } } }, - } + fuzzySearch(zTreeObj, searchField, isHighLight, isExpand) { + const _this = this; + + if (!zTreeObj) { + alert("fail to get ztree object"); + } + var nameKey = zTreeObj.setting.data.key.name; //get the key of the node name + isHighLight = isHighLight === false ? false : true; //default true, only use false to disable highlight + isExpand = isExpand ? true : false; // not to expand in default + zTreeObj.setting.view.nameIsHTML = isHighLight; //allow use html in node name for highlight use + + var metaChar = "[\\[\\]\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]"; //js meta characters + var rexMeta = new RegExp(metaChar, "gi"); //regular expression to match meta characters + + // keywords filter function + function ztreeFilter(zTreeObj, _keywords, callBackFunc) { + if (!_keywords) { + _keywords = ""; //default blank for _keywords + } + + // function to find the matching node + function filterFunc(node) { + if (node && node.oldname && node.oldname.length > 0) { + node[nameKey] = node.oldname; //recover oldname of the node if exist + } + zTreeObj.updateNode(node); //update node to for modifications take effect + if (_keywords.length == 0) { + //return true to show all nodes if the keyword is blank + zTreeObj.showNode(node); + zTreeObj.expandNode(node, isExpand); + return true; + } + //transform node name and keywords to lowercase + if ( + node[nameKey] && + node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase()) != -1 + ) { + if (isHighLight) { + //highlight process + //a new variable 'newKeywords' created to store the keywords information + //keep the parameter '_keywords' as initial and it will be used in next node + //process the meta characters in _keywords thus the RegExp can be correctly used in str.replace + var newKeywords = _keywords.replace(rexMeta, function (matchStr) { + //add escape character before meta characters + return "\\" + matchStr; + }); + node.oldname = node[nameKey]; //store the old name + var rexGlobal = new RegExp(newKeywords, "gi"); //'g' for global,'i' for ignore case + //use replace(RegExp,replacement) since replace(/substr/g,replacement) cannot be used here + node[nameKey] = node.oldname.replace( + rexGlobal, + function (originalText) { + //highlight the matching words in node name + var highLightText = + '<span style="color: whitesmoke;background-color: darkred;">' + + originalText + + "</span>"; + return highLightText; + } + ); + zTreeObj.updateNode(node); //update node for modifications take effect + } + zTreeObj.showNode(node); //show node with matching keywords + return true; //return true and show this node + } + + zTreeObj.hideNode(node); // hide node that not matched + return false; //return false for node not matched + } + + var nodesShow = zTreeObj.getNodesByFilter(filterFunc); //get all nodes that would be shown + processShowNodes(nodesShow, _keywords); //nodes should be reprocessed to show correctly + } + + /** + * reprocess of nodes before showing + */ + function processShowNodes(nodesShow, _keywords) { + if (nodesShow && nodesShow.length > 0) { + //process the ancient nodes if _keywords is not blank + if (_keywords.length > 0) { + $.each(nodesShow, function (n, obj) { + var pathOfOne = obj.getPath(); //get all the ancient nodes including current node + if (pathOfOne && pathOfOne.length > 0) { + //i < pathOfOne.length-1 process every node in path except self + for (var i = 0; i < pathOfOne.length - 1; i++) { + zTreeObj.showNode(pathOfOne[i]); //show node + zTreeObj.expandNode(pathOfOne[i], true); //expand node + } + } + }); + } else { + //show all nodes when _keywords is blank and expand the root nodes + var rootNodes = zTreeObj.getNodesByParam("level", "0"); //get all root nodes + $.each(rootNodes, function (n, obj) { + zTreeObj.expandNode(obj, true); //expand all root nodes + }); + } + } + } + + //listen to change in input element + $(searchField).bind("click", function () { + _this.options.target = document.querySelector( + "#" + _this.ztreeId + ).parentNode.parentNode; + console.log(_this.options.target); + let loadingInstance = Loading.service(_this.options); + console.log(_this.keyWord); + // var _keywords = $(this).val(); + searchNodeLazy(_this.keyWord); //call lazy load + loadingInstance.close(); + }); + + var timeoutId = null; + var lastKeyword = ""; + // excute lazy load once after input change, the last pending task will be cancled + function searchNodeLazy(_keywords) { + if (timeoutId) { + //clear pending task + clearTimeout(timeoutId); + } + timeoutId = setTimeout(function () { + if (lastKeyword === _keywords) { + return; + } + ztreeFilter(zTreeObj, _keywords); //lazy load ztreeFilter function + // $(searchField).focus();//focus input field again after filtering + lastKeyword = _keywords; + }, 500); + } + }, + }, }; </script> @@ -591,3 +807,18 @@ position: absolute; } </style> + +<style scoped lang="scss"> +.search { + width: 300px; + + ::v-deep .el-input__suffix { + right: 0; + width: 50px; + background: skyblue; + color: #fff; + cursor: pointer; + background-color: rgb(61, 104, 255); + } +} +</style> \ No newline at end of file -- Gitblit v1.8.0