From 5381d22231e168bd5dff9cb7234474c408baeefe Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Sat, 4 May 2019 17:21:47 +0800 Subject: [PATCH] =?UTF-8?q?BI-44287=20feat:=20=E6=96=B0=E5=A2=9E=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=B8=8D=E5=BD=B1=E5=93=8D=E7=88=B6=E5=AD=90=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E7=9A=84=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gruntfile.js | 3 + .../component/demo.treevaluechoosercombo.js | 16 +- dist/2.0/fineui.css | 31 +- dist/2.0/fineui.ie.js | 1442 ++++++++++++++-- dist/2.0/fineui.js | 1442 ++++++++++++++-- dist/base.css | 23 +- dist/base.js | 347 +++- dist/bundle.css | 31 +- dist/bundle.ie.js | 1442 ++++++++++++++-- dist/bundle.js | 1442 ++++++++++++++-- dist/case.js | 80 + dist/demo.js | 16 +- dist/fineui.css | 31 +- dist/fineui.ie.js | 1442 ++++++++++++++-- dist/fineui.js | 1442 ++++++++++++++-- dist/fineui_without_jquery_polyfill.js | 1509 ++++++++++++---- dist/resource.css | 8 +- dist/widget.js | 1515 +++++++++++++---- public/css/background.css | 8 +- .../tree/ztree/jquery.ztree.excheck-3.5.js | 4 +- src/base/tree/ztree/list/listasynctree.js | 123 ++ src/base/tree/ztree/list/listparttree.js | 92 + src/base/tree/ztree/list/listtreeview.js | 114 ++ src/base/tree/ztree/parttree.js | 15 +- src/case/tree/ztree/tree.list.display.js | 81 + .../abstract.treevaluechooser.list.js | 261 +++ .../combo.listtreevaluechooser.js | 54 + .../base/colorchooser/colorpicker/editor.css | 8 +- src/css/base/tree/tree.css | 15 + src/css/resource/background.css | 8 +- src/less/base/tree/tree.list.display.less | 17 + src/less/resource/background.less | 4 +- .../multitree/check/multi.tree.check.pane.js | 7 +- src/widget/multitree/multi.tree.list.combo.js | 295 ++++ src/widget/multitree/multi.tree.popup.js | 11 +- .../trigger/multi.tree.search.insert.pane.js | 87 +- .../{ => trigger}/multi.tree.search.pane.js | 0 .../trigger/searcher.list.multi.tree.js | 158 ++ ui/css/background.css | 8 +- 39 files changed, 12037 insertions(+), 1595 deletions(-) create mode 100644 src/base/tree/ztree/list/listasynctree.js create mode 100644 src/base/tree/ztree/list/listparttree.js create mode 100644 src/base/tree/ztree/list/listtreeview.js create mode 100644 src/case/tree/ztree/tree.list.display.js create mode 100644 src/component/treevaluechooser/abstract.treevaluechooser.list.js create mode 100644 src/component/treevaluechooser/combo.listtreevaluechooser.js create mode 100644 src/less/base/tree/tree.list.display.less create mode 100644 src/widget/multitree/multi.tree.list.combo.js rename src/widget/multitree/{ => trigger}/multi.tree.search.pane.js (100%) create mode 100644 src/widget/multitree/trigger/searcher.list.multi.tree.js diff --git a/Gruntfile.js b/Gruntfile.js index e81af8caa..9f5ff5a10 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -49,6 +49,9 @@ module.exports = function (grunt) { "src/base/tree/ztree/treeview.js", "src/base/tree/ztree/asynctree.js", "src/base/tree/ztree/parttree.js", + "src/base/tree/ztree/list/listtreeview.js", + "src/base/tree/ztree/list/listasynctree.js", + "src/base/tree/ztree/list/listparttree.js", "src/base/**/*.js" ], dest: "dist/base.js" diff --git a/demo/js/component/demo.treevaluechoosercombo.js b/demo/js/component/demo.treevaluechoosercombo.js index 91e11a72c..1d5075e13 100644 --- a/demo/js/component/demo.treevaluechoosercombo.js +++ b/demo/js/component/demo.treevaluechoosercombo.js @@ -12,11 +12,21 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); } }); + var widget1 = BI.createWidget({ + type: "bi.list_tree_value_chooser_insert_combo", + itemsCreator: function (op, callback) { + callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); + } + }); return { type: "bi.vertical", - hgap: 200, - vgap: 10, - items: [widget] + items: [{ + type: "bi.vertical_adapt", + hgap: 200, + vgap: 10, + items: [widget, widget1] + }] + }; } }); diff --git a/dist/2.0/fineui.css b/dist/2.0/fineui.css index d03531953..40180856d 100644 --- a/dist/2.0/fineui.css +++ b/dist/2.0/fineui.css @@ -2228,8 +2228,8 @@ textarea { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -2274,8 +2274,8 @@ textarea { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { @@ -3775,6 +3775,21 @@ body .bi-button.button-ignore.disabled.ghost .b-font:before, opacity: 1; filter: alpha(opacity=100); } + +.bi-list-display-tree .ztree li a, +.bi-list-display-tree .ztree li span { + cursor: default !important; +} +.bi-list-display-tree .ztree li a:hover { + text-decoration: none; +} +.bi-list-display-tree .ztree li a.curSelectedNode { + padding-top: 1px; + border: none; + background-color: inherit; + opacity: 1; + filter: alpha(opacity=100); +} .ztree * { padding: 0; margin: 0; @@ -4558,8 +4573,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -4604,8 +4619,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/dist/2.0/fineui.ie.js b/dist/2.0/fineui.ie.js index 4ec7479be..3591d85da 100644 --- a/dist/2.0/fineui.ie.js +++ b/dist/2.0/fineui.ie.js @@ -37918,7 +37918,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38020,12 +38027,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38040,7 +38041,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -49543,6 +49870,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -49551,7 +49880,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -58900,6 +59229,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72132,7 +72541,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72174,7 +72586,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -72784,6 +73196,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -72796,24 +73502,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -72881,79 +73590,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73035,52 +73671,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73125,6 +73774,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -83619,7 +84498,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/2.0/fineui.js b/dist/2.0/fineui.js index f75e83c0c..862e443c4 100644 --- a/dist/2.0/fineui.js +++ b/dist/2.0/fineui.js @@ -38322,7 +38322,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38424,12 +38431,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38444,7 +38445,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -49947,6 +50274,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -49955,7 +50284,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -59304,6 +59633,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72536,7 +72945,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72578,7 +72990,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -73188,6 +73600,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -73200,24 +73906,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -73285,79 +73994,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73439,52 +74075,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73529,6 +74178,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -84023,7 +84902,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/base.css b/dist/base.css index edecdcf44..885f7082f 100644 --- a/dist/base.css +++ b/dist/base.css @@ -72,8 +72,8 @@ _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -118,8 +118,8 @@ _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { @@ -1619,6 +1619,21 @@ body .bi-button.button-ignore.disabled.ghost .b-font:before, opacity: 1; filter: alpha(opacity=100); } + +.bi-list-display-tree .ztree li a, +.bi-list-display-tree .ztree li span { + cursor: default !important; +} +.bi-list-display-tree .ztree li a:hover { + text-decoration: none; +} +.bi-list-display-tree .ztree li a.curSelectedNode { + padding-top: 1px; + border: none; + background-color: inherit; + opacity: 1; + filter: alpha(opacity=100); +} .ztree * { padding: 0; margin: 0; diff --git a/dist/base.js b/dist/base.js index d92486f83..4f2350b06 100644 --- a/dist/base.js +++ b/dist/base.js @@ -2455,7 +2455,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -2557,12 +2564,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -2577,7 +2578,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -14080,6 +14407,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -14088,7 +14417,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; diff --git a/dist/bundle.css b/dist/bundle.css index d03531953..40180856d 100644 --- a/dist/bundle.css +++ b/dist/bundle.css @@ -2228,8 +2228,8 @@ textarea { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -2274,8 +2274,8 @@ textarea { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { @@ -3775,6 +3775,21 @@ body .bi-button.button-ignore.disabled.ghost .b-font:before, opacity: 1; filter: alpha(opacity=100); } + +.bi-list-display-tree .ztree li a, +.bi-list-display-tree .ztree li span { + cursor: default !important; +} +.bi-list-display-tree .ztree li a:hover { + text-decoration: none; +} +.bi-list-display-tree .ztree li a.curSelectedNode { + padding-top: 1px; + border: none; + background-color: inherit; + opacity: 1; + filter: alpha(opacity=100); +} .ztree * { padding: 0; margin: 0; @@ -4558,8 +4573,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -4604,8 +4619,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/dist/bundle.ie.js b/dist/bundle.ie.js index 4ec7479be..3591d85da 100644 --- a/dist/bundle.ie.js +++ b/dist/bundle.ie.js @@ -37918,7 +37918,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38020,12 +38027,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38040,7 +38041,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -49543,6 +49870,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -49551,7 +49880,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -58900,6 +59229,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72132,7 +72541,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72174,7 +72586,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -72784,6 +73196,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -72796,24 +73502,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -72881,79 +73590,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73035,52 +73671,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73125,6 +73774,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -83619,7 +84498,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/bundle.js b/dist/bundle.js index f75e83c0c..862e443c4 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -38322,7 +38322,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38424,12 +38431,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38444,7 +38445,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -49947,6 +50274,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -49955,7 +50284,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -59304,6 +59633,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72536,7 +72945,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72578,7 +72990,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -73188,6 +73600,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -73200,24 +73906,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -73285,79 +73994,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73439,52 +74075,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73529,6 +74178,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -84023,7 +84902,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/case.js b/dist/case.js index 5890a0020..82dd9f7a5 100644 --- a/dist/case.js +++ b/dist/case.js @@ -9155,6 +9155,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. diff --git a/dist/demo.js b/dist/demo.js index 910eb5bcc..9831888e1 100644 --- a/dist/demo.js +++ b/dist/demo.js @@ -2707,11 +2707,21 @@ BI.shortcut("demo.center", Demo.Center);Demo.TreeValueChooser = BI.inherit(BI.Wi callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); } }); + var widget1 = BI.createWidget({ + type: "bi.list_tree_value_chooser_insert_combo", + itemsCreator: function (op, callback) { + callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); + } + }); return { type: "bi.vertical", - hgap: 200, - vgap: 10, - items: [widget] + items: [{ + type: "bi.vertical_adapt", + hgap: 200, + vgap: 10, + items: [widget, widget1] + }] + }; } }); diff --git a/dist/fineui.css b/dist/fineui.css index 1c296a696..68d3fd322 100644 --- a/dist/fineui.css +++ b/dist/fineui.css @@ -2228,8 +2228,8 @@ textarea { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -2274,8 +2274,8 @@ textarea { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { @@ -3775,6 +3775,21 @@ body .bi-button.button-ignore.disabled.ghost .b-font:before, opacity: 1; filter: alpha(opacity=100); } + +.bi-list-display-tree .ztree li a, +.bi-list-display-tree .ztree li span { + cursor: default !important; +} +.bi-list-display-tree .ztree li a:hover { + text-decoration: none; +} +.bi-list-display-tree .ztree li a.curSelectedNode { + padding-top: 1px; + border: none; + background-color: inherit; + opacity: 1; + filter: alpha(opacity=100); +} .ztree * { padding: 0; margin: 0; @@ -4558,8 +4573,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('resources?path=/com/fr/web/ui/images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/2x/icon/half_selected.png'); + background: url('resources?path=/com/fr/web/ui/images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -4604,8 +4619,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('resources?path=/com/fr/web/ui/images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/1x/icon/half_selected.png'); + background: url('resources?path=/com/fr/web/ui/images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/dist/fineui.ie.js b/dist/fineui.ie.js index af5c350f2..d88578187 100644 --- a/dist/fineui.ie.js +++ b/dist/fineui.ie.js @@ -38163,7 +38163,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38265,12 +38272,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38285,7 +38286,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -49788,6 +50115,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -49796,7 +50125,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -59145,6 +59474,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72377,7 +72786,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72419,7 +72831,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -73029,6 +73441,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -73041,24 +73747,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -73126,79 +73835,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73280,52 +73916,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73370,6 +74019,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -83864,7 +84743,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/fineui.js b/dist/fineui.js index e49d3e252..d99cbfd13 100644 --- a/dist/fineui.js +++ b/dist/fineui.js @@ -38567,7 +38567,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -38669,12 +38676,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, @@ -38689,7 +38690,333 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { } }); -BI.shortcut("bi.part_tree", BI.PartTree);BI.prepares.push(function () { +BI.shortcut("bi.part_tree", BI.PartTree);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView);/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree);/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree);BI.prepares.push(function () { BI.Resizers = new BI.ResizeController(); BI.Layers = new BI.LayerController(); BI.Maskers = new BI.MaskersController(); @@ -50192,6 +50519,8 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -50200,7 +50529,7 @@ BI.shortcut("bi.custom_tree", BI.CustomTree);/* } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; @@ -59549,6 +59878,86 @@ BI.DisplayTree = BI.inherit(BI.TreeView, { BI.DisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.display_tree", BI.DisplayTree);/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree);/** * 简单的多选树 * * Created by GUY on 2016/2/16. @@ -72781,7 +73190,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -72823,7 +73235,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -73433,6 +73845,300 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** * 带加载的多选下拉面板 * @class BI.MultiTreePopup * @extends BI.Pane @@ -73445,24 +74151,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ @@ -73530,79 +74239,6 @@ BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane - * @extends BI.Pane - */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { - - _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn - }); - }, - - _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; - - this.partTree = BI.createWidget({ - type: "bi.part_tree", - element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value - }); - - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - }); - - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); - }); - }, - - hasChecked: function () { - return this.partTree.hasChecked(); - }, - - setValue: function (v) { - this.setSelectedValue(v.value); - }, - - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); - }, - - getValue: function () { - return this.partTree.getValue(); - }, - - empty: function () { - this.partTree.empty(); - }, - - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); - } -}); - -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; - -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; - -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -73684,52 +74320,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -73774,6 +74423,236 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane + */ + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", + itemsCreator: BI.emptyFn, + keywordGetter: BI.emptyFn + }); + }, + + _init: function () { + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** * searcher * Created by guy on 15/11/3. * @class BI.MultiTreeSearcher @@ -84268,7 +85147,320 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } });/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/fineui_without_jquery_polyfill.js b/dist/fineui_without_jquery_polyfill.js index 12a530339..8adf3980e 100644 --- a/dist/fineui_without_jquery_polyfill.js +++ b/dist/fineui_without_jquery_polyfill.js @@ -55581,7 +55581,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -55623,7 +55626,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -56233,176 +56236,400 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** - * 带加载的多选下拉面板 - * @class BI.MultiTreePopup - * @extends BI.Pane + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single */ -BI.MultiTreePopup = BI.inherit(BI.Pane, { + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, _defaultConfig: function () { - return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-popup", - maxWidth: "auto", - minWidth: 100, - maxHeight: 400, - onLoaded: BI.emptyFn + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 }); }, _init: function () { - BI.MultiTreePopup.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); - this.selectedValues = {}; + var self = this, o = this.options; - this.tree = BI.createWidget({ - type: "bi.async_tree", - height: 400, - cls: "popup-view-tree", - itemsCreator: opts.itemsCreator, - onLoaded: opts.onLoaded, - value: opts.value || {} - }); + var isInit = false; + var want2showCounter = false; - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - element: this, - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], - el: this.tree - }); + this.storeValue = {value: o.value || []}; - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); - break; - } - }); + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} - this.tree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); }); - this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } }); - }, - - getValue: function () { - return this.tree.getValue(); - }, + var change = false; + var clear = false; // 标识当前是否点击了清空 - setValue: function (v) { - v || (v = {}); - this.tree.setSelectedValue(v.value); - }, + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; - populate: function (config) { - this.tree.stroke(config); - }, + var isPopupView = function () { + return self.combo.isViewVisible(); + }; - hasChecked: function () { - return this.tree.hasChecked(); - }, + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } - resetWidth: function (w) { - this.popupView.resetWidth(w); - } -}); + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); -BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); -BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** + * 带加载的多选下拉面板 + * @class BI.MultiTreePopup * @extends BI.Pane */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { +BI.MultiTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-popup", + maxWidth: "auto", + minWidth: 100, + maxHeight: 400, + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; - this.partTree = BI.createWidget({ - type: "bi.part_tree", + this.selectedValues = {}; + + this.tree = BI.createWidget(opts.el, { + type: "bi.async_tree", + height: 400, + cls: "popup-view-tree", + itemsCreator: opts.itemsCreator, + onLoaded: opts.onLoaded, + value: v.value || {} + }); + + this.popupView = BI.createWidget({ + type: "bi.multi_popup_view", element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], + el: this.tree }); - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { + switch (index) { + case 0: + self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); + break; + case 1: + self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); + break; + } }); - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + this.tree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); + }); + + this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { + self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); }); + }, - hasChecked: function () { - return this.partTree.hasChecked(); + getValue: function () { + return this.tree.getValue(); }, setValue: function (v) { - this.setSelectedValue(v.value); + v || (v = {}); + this.tree.setSelectedValue(v.value); }, - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); + populate: function (config) { + this.tree.stroke(config); }, - getValue: function () { - return this.partTree.getValue(); + hasChecked: function () { + return this.tree.hasChecked(); }, - empty: function () { - this.partTree.empty(); + resetHeight: function (h) { + this.popupView.resetHeight(h); }, - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); + resetWidth: function (w) { + this.popupView.resetWidth(w); } }); -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; +BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** +BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -56484,52 +56711,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -56574,38 +56814,268 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiTreeSearcher - * @extends Widget + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane */ -BI.MultiTreeSearcher = BI.inherit(BI.Widget, { + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-searcher", + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", itemsCreator: BI.emptyFn, - valueFormatter: function (v) { - return v; - }, - popup: {}, - - adapter: null, - masker: {} + keywordGetter: BI.emptyFn }); }, _init: function () { - BI.MultiTreeSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.multi_select_editor", - height: o.height, - el: { - type: "bi.simple_state_editor", - height: o.height - } - }); + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", + element: this, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiTreeSearcher + * @extends Widget + */ +BI.MultiTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); this.searcher = BI.createWidget({ type: "bi.searcher", @@ -66668,52 +67138,456 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return true; } } - return false; + return false; + } + }, + + _reqAdjustTreeNode: function (op, callback) { + var self = this; + var result = []; + var selectedValues = op.selectedValues; + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + BI.each(selectedValues, function (k, v) { + result.push([k]); + }); + + dealWithSelectedValues(selectedValues, []); + + var jo = {}; + BI.each(result, function (i, strs) { + self._buildTree(jo, strs); + }); + callback(jo); + + function dealWithSelectedValues(selected, parents) { + if (selected == null || BI.isEmpty(selected)) { + return true; + } + var can = true; + BI.each(selected, function (k, v) { + var p = BI.clone(parents); + p.push(k); + if (!dealWithSelectedValues(selected[k], p)) { + BI.each(selected[k], function (nk, nv) { + var t = BI.clone(p); + t.push(nk); + result.push(t); + }); + can = false; + } + }); + return can && isAllSelected(selected, parents); + } + + function isAllSelected(selected, parents) { + return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, isAllSelect, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isAllSelect || isSelected(parentValues, current); + createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isCurAllSelected || (isSelected(parentValues, current) && checked); + createOneJson(parentValues, current, true, checked, false, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: half, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return false; + } + return BI.any(find, function (v) { + if (v === value) { + return true; + } + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var checkState = op.checkState || {}; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || {}; + var valueMap = {}; + // if (judgeState(parentValues, selectedValues, checkState)) { + valueMap = dealWidthSelectedValue(parentValues, selectedValues); + // } + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: state[0], + halfCheck: state[1] + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function judgeState(parentValues, selected_value, checkState) { + var checked = checkState.checked, half = checkState.half; + if (parentValues.length > 0 && !checked) { + return false; + } + return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); + } + + function dealWidthSelectedValue(parentValues, selectedValues) { + var valueMap = {}; + BI.each(parentValues, function (i, v) { + selectedValues = selectedValues[v] || {}; + }); + BI.each(selectedValues, function (value, obj) { + if (BI.isNull(obj)) { + valueMap[value] = [0, 0]; + return; + } + if (BI.isEmpty(obj)) { + valueMap[value] = [2, 0]; + return; + } + var nextNames = {}; + BI.each(obj, function (t, o) { + if (BI.isNull(o) || BI.isEmpty(o)) { + nextNames[t] = true; + } + }); + valueMap[value] = [1, BI.size(nextNames)]; + }); + return valueMap; + } + + function getCheckState(current, parentValues, valueMap, checkState) { + var checked = checkState.checked, half = checkState.half; + var tempCheck = false, halfCheck = false; + if (BI.has(valueMap, current)) { + // 可能是半选 + if (valueMap[current][0] === 1) { + var values = BI.clone(parentValues); + values.push(current); + var childCount = self._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { + halfCheck = true; + } + } else if (valueMap[current][0] === 2) { + tempCheck = true; + } + } + var check; + if (!checked && !halfCheck && !tempCheck) { + check = BI.has(valueMap, current); + } else { + check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); + } + return [check, halfCheck]; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + return BI.map(BI.difference(BI.keys(selectedValues), BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + }, + + _getNode: function (selectedValues, parentValues) { + var pNode = selectedValues; + for (var i = 0, len = parentValues.length; i < len; i++) { + if (pNode == null) { + return null; + } + pNode = pNode[parentValues[i]]; + } + return pNode; + }, + + _deleteNode: function (selectedValues, values) { + var name = values[values.length - 1]; + var p = values.slice(0, values.length - 1); + var pNode = this._getNode(selectedValues, p); + if (pNode != null && pNode[name]) { + delete pNode[name]; + // 递归删掉空父节点 + while (p.length > 0 && BI.isEmpty(pNode)) { + name = p[p.length - 1]; + p = p.slice(0, p.length - 1); + pNode = this._getNode(selectedValues, p); + if (pNode != null) { + delete pNode[name]; + } + } + } + }, + + _buildTree: function (jo, values) { + var t = jo; + BI.each(values, function (i, v) { + if (!BI.has(t, v)) { + t[v] = {}; + } + t = t[v]; + }); + }, + + _isMatch: function (parentValues, value, keyword) { + var node = this._getTreeNode(parentValues, value); + if (!node) { + return false; + } + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }, + + _getTreeNode: function (parentValues, v) { + var self = this; + var findParentNode; + var index = 0; + this.tree.traverse(function (node) { + if (self.tree.isRoot(node)) { + return; + } + if (index > parentValues.length) { + return false; + } + if (index === parentValues.length && node.value === v) { + findParentNode = node; + return false; + } + if (node.value === parentValues[index]) { + index++; + return; + } + return true; + }); + return findParentNode; + }, + + _getChildren: function (parentValues) { + if (parentValues.length > 0) { + var value = BI.last(parentValues); + var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); + } else { + var parent = this.tree.getRoot(); } + return parent.getChildren(); }, - _reqAdjustTreeNode: function (op, callback) { + _getChildCount: function (parentValues) { + return this._getChildren(parentValues).length; + } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { var self = this; - var result = []; + var result = {}; var selectedValues = op.selectedValues; + if (selectedValues == null || BI.isEmpty(selectedValues)) { callback({}); return; } - BI.each(selectedValues, function (k, v) { - result.push([k]); - }); - dealWithSelectedValues(selectedValues, []); + doCheck([], this.tree.getRoot(), selectedValues); - var jo = {}; - BI.each(result, function (i, strs) { - self._buildTree(jo, strs); + callback({ + items: BI.values(result) }); - callback(jo); - function dealWithSelectedValues(selected, parents) { - if (selected == null || BI.isEmpty(selected)) { - return true; - } - var can = true; - BI.each(selected, function (k, v) { - var p = BI.clone(parents); - p.push(k); - if (!dealWithSelectedValues(selected[k], p)) { - BI.each(selected[k], function (nk, nv) { - var t = BI.clone(p); - t.push(nk); - result.push(t); - }); - can = false; - } + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); }); - return can && isAllSelected(selected, parents); } - function isAllSelected(selected, parents) { - return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; } }, @@ -66748,9 +67622,9 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var output = []; for (var i = start, len = children.length; i < len; i++) { if (output.length < self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, result); + var find = nodeSearch(1, [], children[i].value, result); } else if (output.length === self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, []); + var find = nodeSearch(1, [], children[i].value, []); } if (find[0] === true) { output.push(children[i].value); @@ -66771,10 +67645,10 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return output; } - function nodeSearch(deep, parentValues, current, isAllSelect, result) { + function nodeSearch(deep, parentValues, current, result) { if (self._isMatch(parentValues, current, keyword)) { - var checked = isAllSelect || isSelected(parentValues, current); - createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); return [true, checked]; } var newParents = BI.clone(parentValues); @@ -66783,9 +67657,8 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var can = false, checked = false; - var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); BI.each(children, function (i, child) { - var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + var state = nodeSearch(deep + 1, newParents, child.value, result); if (state[1] === true) { checked = true; } @@ -66794,13 +67667,13 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { } }); if (can === true) { - checked = isCurAllSelected || (isSelected(parentValues, current) && checked); - createOneJson(parentValues, current, true, checked, false, false, result); + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); } return [can, checked]; } - function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { + function createOneJson(parentValues, value, isOpen, checked, flag, result) { var node = self._getTreeNode(parentValues, value); result.push({ id: node.id, @@ -66811,7 +67684,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, - halfCheck: half, + halfCheck: false, flag: flag }); } @@ -66844,15 +67717,9 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { }); } - function isSelected(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return false; - } - return BI.any(find, function (v) { - if (v === value) { - return true; - } + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; }); } @@ -66876,16 +67743,12 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var self = this; var result = []; var times = op.times; - var checkState = op.checkState || {}; var parentValues = op.parentValues || []; - var selectedValues = op.selectedValues || {}; - var valueMap = {}; - // if (judgeState(parentValues, selectedValues, checkState)) { - valueMap = dealWidthSelectedValue(parentValues, selectedValues); - // } + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); var nodes = this._getChildren(parentValues); for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { - var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); + var checked = BI.has(valueMap, nodes[i].value); result.push({ id: nodes[i].id, pId: nodes[i].pId, @@ -66893,8 +67756,8 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { text: nodes[i].text, times: 1, isParent: nodes[i].getChildrenLength() > 0, - checked: state[0], - halfCheck: state[1] + checked: checked, + halfCheck: false }); } // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 @@ -66908,68 +67771,21 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { }); }); - function judgeState(parentValues, selected_value, checkState) { - var checked = checkState.checked, half = checkState.half; - if (parentValues.length > 0 && !checked) { - return false; - } - return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); - } - - function dealWidthSelectedValue(parentValues, selectedValues) { + function dealWidthSelectedValue(selectedValues) { var valueMap = {}; - BI.each(parentValues, function (i, v) { - selectedValues = selectedValues[v] || {}; - }); - BI.each(selectedValues, function (value, obj) { - if (BI.isNull(obj)) { - valueMap[value] = [0, 0]; - return; - } - if (BI.isEmpty(obj)) { - valueMap[value] = [2, 0]; - return; - } - var nextNames = {}; - BI.each(obj, function (t, o) { - if (BI.isNull(o) || BI.isEmpty(o)) { - nextNames[t] = true; - } - }); - valueMap[value] = [1, BI.size(nextNames)]; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; }); return valueMap; } - - function getCheckState(current, parentValues, valueMap, checkState) { - var checked = checkState.checked, half = checkState.half; - var tempCheck = false, halfCheck = false; - if (BI.has(valueMap, current)) { - // 可能是半选 - if (valueMap[current][0] === 1) { - var values = BI.clone(parentValues); - values.push(current); - var childCount = self._getChildCount(values); - if (childCount > 0 && childCount !== valueMap[current][1]) { - halfCheck = true; - } - } else if (valueMap[current][0] === 2) { - tempCheck = true; - } - } - var check; - if (!checked && !halfCheck && !tempCheck) { - check = BI.has(valueMap, current); - } else { - check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); - } - return [check, halfCheck]; - } }, _getAddedValueNode: function (parentValues, selectedValues) { var nodes = this._getChildren(parentValues); - return BI.map(BI.difference(BI.keys(selectedValues), BI.map(nodes, "value")), function (idx, v) { + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { return { id: BI.UUID(), pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), @@ -66981,94 +67797,61 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { halfCheck: false }; }); - }, + } +});/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { - _getNode: function (selectedValues, parentValues) { - var pNode = selectedValues; - for (var i = 0, len = parentValues.length; i < len; i++) { - if (pNode == null) { - return null; - } - pNode = pNode[parentValues[i]]; - } - return pNode; + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); }, - _deleteNode: function (selectedValues, values) { - var name = values[values.length - 1]; - var p = values.slice(0, values.length - 1); - var pNode = this._getNode(selectedValues, p); - if (pNode != null && pNode[name]) { - delete pNode[name]; - // 递归删掉空父节点 - while (p.length > 0 && BI.isEmpty(pNode)) { - name = p[p.length - 1]; - p = p.slice(0, p.length - 1); - pNode = this._getNode(selectedValues, p); - if (pNode != null) { - delete pNode[name]; - } - } + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); } - }, - - _buildTree: function (jo, values) { - var t = jo; - BI.each(values, function (i, v) { - if (!BI.has(t, v)) { - t[v] = {}; - } - t = t[v]; + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height }); - }, - _isMatch: function (parentValues, value, keyword) { - var node = this._getTreeNode(parentValues, value); - if (!node) { - return false; - } - var find = BI.Func.getSearchResult([node.text || node.value], keyword); - return find.find.length > 0 || find.match.length > 0; + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); }, - _getTreeNode: function (parentValues, v) { - var self = this; - var findParentNode; - var index = 0; - this.tree.traverse(function (node) { - if (self.tree.isRoot(node)) { - return; - } - if (index > parentValues.length) { - return false; - } - if (index === parentValues.length && node.value === v) { - findParentNode = node; - return false; - } - if (node.value === parentValues[index]) { - index++; - return; - } - return true; - }); - return findParentNode; + setValue: function (v) { + this.combo.setValue(v); }, - _getChildren: function (parentValues) { - if (parentValues.length > 0) { - var value = BI.last(parentValues); - var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); - } else { - var parent = this.tree.getRoot(); - } - return parent.getChildren(); + getValue: function () { + return this.combo.getValue(); }, - _getChildCount: function (parentValues) { - return this._getChildren(parentValues).length; + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); } -});/** +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/dist/resource.css b/dist/resource.css index cad505e88..fe83a374a 100644 --- a/dist/resource.css +++ b/dist/resource.css @@ -122,8 +122,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -168,8 +168,8 @@ textarea::-webkit-scrollbar-thumb:hover { _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/dist/widget.js b/dist/widget.js index a45f95b02..0a3250a50 100644 --- a/dist/widget.js +++ b/dist/widget.js @@ -12585,7 +12585,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -12627,7 +12630,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { @@ -13237,176 +13240,400 @@ BI.MultiTreeInsertCombo = BI.inherit(BI.Single, { BI.MultiTreeInsertCombo.EVENT_CONFIRM = "MultiTreeInsertCombo.EVENT_CONFIRM"; BI.shortcut("bi.multi_tree_insert_combo", BI.MultiTreeInsertCombo);/** - * 带加载的多选下拉面板 - * @class BI.MultiTreePopup - * @extends BI.Pane + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single */ -BI.MultiTreePopup = BI.inherit(BI.Pane, { + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, _defaultConfig: function () { - return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-popup", - maxWidth: "auto", - minWidth: 100, - maxHeight: 400, - onLoaded: BI.emptyFn + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 }); }, _init: function () { - BI.MultiTreePopup.superclass._init.apply(this, arguments); - - var self = this, opts = this.options; + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); - this.selectedValues = {}; + var self = this, o = this.options; - this.tree = BI.createWidget({ - type: "bi.async_tree", - height: 400, - cls: "popup-view-tree", - itemsCreator: opts.itemsCreator, - onLoaded: opts.onLoaded, - value: opts.value || {} - }); + var isInit = false; + var want2showCounter = false; - this.popupView = BI.createWidget({ - type: "bi.multi_popup_view", - element: this, - stopPropagation: false, - maxWidth: opts.maxWidth, - minWidth: opts.minWidth, - maxHeight: opts.maxHeight, - buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], - el: this.tree - }); + this.storeValue = {value: o.value || []}; - this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { - switch (index) { - case 0: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); - break; - case 1: - self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); - break; - } - }); + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} - this.tree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); }); - this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { - self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } }); - }, - - getValue: function () { - return this.tree.getValue(); - }, + var change = false; + var clear = false; // 标识当前是否点击了清空 - setValue: function (v) { - v || (v = {}); - this.tree.setSelectedValue(v.value); - }, + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; - populate: function (config) { - this.tree.stroke(config); - }, + var isPopupView = function () { + return self.combo.isViewVisible(); + }; - hasChecked: function () { - return this.tree.hasChecked(); - }, + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); - resetHeight: function (h) { - this.popupView.resetHeight(h); - }, + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } - resetWidth: function (w) { - this.popupView.resetWidth(w); - } -}); + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); -BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; -BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); -BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** - * - * 在搜索框中输入文本弹出的面板 - * @class BI.MultiTreeSearchPane + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo);/** + * 带加载的多选下拉面板 + * @class BI.MultiTreePopup * @extends BI.Pane */ - -BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { +BI.MultiTreePopup = BI.inherit(BI.Pane, { _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-search-pane bi-card", - itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + return BI.extend(BI.MultiTreePopup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-popup", + maxWidth: "auto", + minWidth: 100, + maxHeight: 400, + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { - BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); + BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; - this.partTree = BI.createWidget({ - type: "bi.part_tree", + this.selectedValues = {}; + + this.tree = BI.createWidget(opts.el, { + type: "bi.async_tree", + height: 400, + cls: "popup-view-tree", + itemsCreator: opts.itemsCreator, + onLoaded: opts.onLoaded, + value: v.value || {} + }); + + this.popupView = BI.createWidget({ + type: "bi.multi_popup_view", element: this, - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, callback); - }, - value: opts.value + stopPropagation: false, + maxWidth: opts.maxWidth, + minWidth: opts.minWidth, + maxHeight: opts.maxHeight, + buttons: [BI.i18nText("BI-Basic_Clears"), BI.i18nText("BI-Basic_Sure")], + el: this.tree }); - this.partTree.on(BI.Controller.EVENT_CHANGE, function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + this.popupView.on(BI.MultiPopupView.EVENT_CLICK_TOOLBAR_BUTTON, function (index) { + switch (index) { + case 0: + self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CLEAR); + break; + case 1: + self.fireEvent(BI.MultiTreePopup.EVENT_CLICK_CONFIRM); + break; + } }); - this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { - self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + this.tree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreePopup.EVENT_CHANGE); + }); + + this.tree.on(BI.TreeView.EVENT_AFTERINIT, function () { + self.fireEvent(BI.MultiTreePopup.EVENT_AFTERINIT); }); + }, - hasChecked: function () { - return this.partTree.hasChecked(); + getValue: function () { + return this.tree.getValue(); }, setValue: function (v) { - this.setSelectedValue(v.value); + v || (v = {}); + this.tree.setSelectedValue(v.value); }, - setSelectedValue: function (v) { - v || (v = {}); - this.partTree.setSelectedValue(v); + populate: function (config) { + this.tree.stroke(config); }, - getValue: function () { - return this.partTree.getValue(); + hasChecked: function () { + return this.tree.hasChecked(); }, - empty: function () { - this.partTree.empty(); + resetHeight: function (h) { + this.popupView.resetHeight(h); }, - populate: function (op) { - this.partTree.stroke.apply(this.partTree, arguments); + resetWidth: function (w) { + this.popupView.resetWidth(w); } }); -BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiTreePopup.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiTreePopup.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreePopup.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; +BI.MultiTreePopup.EVENT_AFTERINIT = "EVENT_AFTERINIT"; -BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; -BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; -BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** +BI.shortcut("bi.multi_tree_popup_view", BI.MultiTreePopup);/** * 查看已选按钮 * Created by guy on 15/11/3. * @class BI.MultiTreeCheckSelectedButton @@ -13488,52 +13715,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, @@ -13578,43 +13818,273 @@ BI.MultiTreeSearchInsertPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM = "EVENT_ADD_ITEM"; BI.shortcut("bi.multi_tree_search_insert_pane", BI.MultiTreeSearchInsertPane);/** - * searcher - * Created by guy on 15/11/3. - * @class BI.MultiTreeSearcher - * @extends Widget + * + * 在搜索框中输入文本弹出的面板 + * @class BI.MultiTreeSearchPane + * @extends BI.Pane */ -BI.MultiTreeSearcher = BI.inherit(BI.Widget, { + +BI.MultiTreeSearchPane = BI.inherit(BI.Pane, { _defaultConfig: function () { - return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-multi-tree-searcher", + return BI.extend(BI.MultiTreeSearchPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-search-pane bi-card", itemsCreator: BI.emptyFn, - valueFormatter: function (v) { - return v; - }, - popup: {}, - - adapter: null, - masker: {} + keywordGetter: BI.emptyFn }); }, _init: function () { - BI.MultiTreeSearcher.superclass._init.apply(this, arguments); - var self = this, o = this.options; - this.editor = BI.createWidget({ - type: "bi.multi_select_editor", - height: o.height, - el: { - type: "bi.simple_state_editor", - height: o.height - } - }); + BI.MultiTreeSearchPane.superclass._init.apply(this, arguments); - this.searcher = BI.createWidget({ - type: "bi.searcher", + var self = this, opts = this.options; + + this.partTree = BI.createWidget({ + type: "bi.part_tree", element: this, - isAutoSearch: false, + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, callback); + }, + value: opts.value + }); + + this.partTree.on(BI.Controller.EVENT_CHANGE, function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + }); + + this.partTree.on(BI.TreeView.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiTreeSearchPane.EVENT_CHANGE); + }); + }, + + hasChecked: function () { + return this.partTree.hasChecked(); + }, + + setValue: function (v) { + this.setSelectedValue(v.value); + }, + + setSelectedValue: function (v) { + v || (v = {}); + this.partTree.setSelectedValue(v); + }, + + getValue: function () { + return this.partTree.getValue(); + }, + + empty: function () { + this.partTree.empty(); + }, + + populate: function (op) { + this.partTree.stroke.apply(this.partTree, arguments); + } +}); + +BI.MultiTreeSearchPane.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.MultiTreeSearchPane.EVENT_CLICK_CONFIRM = "EVENT_CLICK_CONFIRM"; +BI.MultiTreeSearchPane.EVENT_CLICK_CLEAR = "EVENT_CLICK_CLEAR"; + +BI.shortcut("bi.multi_tree_search_pane", BI.MultiTreeSearchPane);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher);/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiTreeSearcher + * @extends Widget + */ +BI.MultiTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, isAutoSync: false, onSearch: function (op, callback) { callback({ @@ -23672,52 +24142,456 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return true; } } - return false; + return false; + } + }, + + _reqAdjustTreeNode: function (op, callback) { + var self = this; + var result = []; + var selectedValues = op.selectedValues; + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + BI.each(selectedValues, function (k, v) { + result.push([k]); + }); + + dealWithSelectedValues(selectedValues, []); + + var jo = {}; + BI.each(result, function (i, strs) { + self._buildTree(jo, strs); + }); + callback(jo); + + function dealWithSelectedValues(selected, parents) { + if (selected == null || BI.isEmpty(selected)) { + return true; + } + var can = true; + BI.each(selected, function (k, v) { + var p = BI.clone(parents); + p.push(k); + if (!dealWithSelectedValues(selected[k], p)) { + BI.each(selected[k], function (nk, nv) { + var t = BI.clone(p); + t.push(nk); + result.push(t); + }); + can = false; + } + }); + return can && isAllSelected(selected, parents); + } + + function isAllSelected(selected, parents) { + return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, false, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, isAllSelect, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isAllSelect || isSelected(parentValues, current); + createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isCurAllSelected || (isSelected(parentValues, current) && checked); + createOneJson(parentValues, current, true, checked, false, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: half, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return false; + } + return BI.any(find, function (v) { + if (v === value) { + return true; + } + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var checkState = op.checkState || {}; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || {}; + var valueMap = {}; + // if (judgeState(parentValues, selectedValues, checkState)) { + valueMap = dealWidthSelectedValue(parentValues, selectedValues); + // } + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: state[0], + halfCheck: state[1] + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function judgeState(parentValues, selected_value, checkState) { + var checked = checkState.checked, half = checkState.half; + if (parentValues.length > 0 && !checked) { + return false; + } + return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); + } + + function dealWidthSelectedValue(parentValues, selectedValues) { + var valueMap = {}; + BI.each(parentValues, function (i, v) { + selectedValues = selectedValues[v] || {}; + }); + BI.each(selectedValues, function (value, obj) { + if (BI.isNull(obj)) { + valueMap[value] = [0, 0]; + return; + } + if (BI.isEmpty(obj)) { + valueMap[value] = [2, 0]; + return; + } + var nextNames = {}; + BI.each(obj, function (t, o) { + if (BI.isNull(o) || BI.isEmpty(o)) { + nextNames[t] = true; + } + }); + valueMap[value] = [1, BI.size(nextNames)]; + }); + return valueMap; + } + + function getCheckState(current, parentValues, valueMap, checkState) { + var checked = checkState.checked, half = checkState.half; + var tempCheck = false, halfCheck = false; + if (BI.has(valueMap, current)) { + // 可能是半选 + if (valueMap[current][0] === 1) { + var values = BI.clone(parentValues); + values.push(current); + var childCount = self._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { + halfCheck = true; + } + } else if (valueMap[current][0] === 2) { + tempCheck = true; + } + } + var check; + if (!checked && !halfCheck && !tempCheck) { + check = BI.has(valueMap, current); + } else { + check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); + } + return [check, halfCheck]; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + return BI.map(BI.difference(BI.keys(selectedValues), BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + }, + + _getNode: function (selectedValues, parentValues) { + var pNode = selectedValues; + for (var i = 0, len = parentValues.length; i < len; i++) { + if (pNode == null) { + return null; + } + pNode = pNode[parentValues[i]]; + } + return pNode; + }, + + _deleteNode: function (selectedValues, values) { + var name = values[values.length - 1]; + var p = values.slice(0, values.length - 1); + var pNode = this._getNode(selectedValues, p); + if (pNode != null && pNode[name]) { + delete pNode[name]; + // 递归删掉空父节点 + while (p.length > 0 && BI.isEmpty(pNode)) { + name = p[p.length - 1]; + p = p.slice(0, p.length - 1); + pNode = this._getNode(selectedValues, p); + if (pNode != null) { + delete pNode[name]; + } + } + } + }, + + _buildTree: function (jo, values) { + var t = jo; + BI.each(values, function (i, v) { + if (!BI.has(t, v)) { + t[v] = {}; + } + t = t[v]; + }); + }, + + _isMatch: function (parentValues, value, keyword) { + var node = this._getTreeNode(parentValues, value); + if (!node) { + return false; + } + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }, + + _getTreeNode: function (parentValues, v) { + var self = this; + var findParentNode; + var index = 0; + this.tree.traverse(function (node) { + if (self.tree.isRoot(node)) { + return; + } + if (index > parentValues.length) { + return false; + } + if (index === parentValues.length && node.value === v) { + findParentNode = node; + return false; + } + if (node.value === parentValues[index]) { + index++; + return; + } + return true; + }); + return findParentNode; + }, + + _getChildren: function (parentValues) { + if (parentValues.length > 0) { + var value = BI.last(parentValues); + var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); + } else { + var parent = this.tree.getRoot(); } + return parent.getChildren(); }, - _reqAdjustTreeNode: function (op, callback) { + _getChildCount: function (parentValues) { + return this._getChildren(parentValues).length; + } +});BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { var self = this; - var result = []; + var result = {}; var selectedValues = op.selectedValues; + if (selectedValues == null || BI.isEmpty(selectedValues)) { callback({}); return; } - BI.each(selectedValues, function (k, v) { - result.push([k]); - }); - dealWithSelectedValues(selectedValues, []); + doCheck([], this.tree.getRoot(), selectedValues); - var jo = {}; - BI.each(result, function (i, strs) { - self._buildTree(jo, strs); + callback({ + items: BI.values(result) }); - callback(jo); - function dealWithSelectedValues(selected, parents) { - if (selected == null || BI.isEmpty(selected)) { - return true; - } - var can = true; - BI.each(selected, function (k, v) { - var p = BI.clone(parents); - p.push(k); - if (!dealWithSelectedValues(selected[k], p)) { - BI.each(selected[k], function (nk, nv) { - var t = BI.clone(p); - t.push(nk); - result.push(t); - }); - can = false; - } + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); }); - return can && isAllSelected(selected, parents); } - function isAllSelected(selected, parents) { - return BI.isEmpty(selected) || self._getChildCount(parents) === BI.size(selected); + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; } }, @@ -23752,9 +24626,9 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var output = []; for (var i = start, len = children.length; i < len; i++) { if (output.length < self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, result); + var find = nodeSearch(1, [], children[i].value, result); } else if (output.length === self._const.perPage) { - var find = nodeSearch(1, [], children[i].value, false, []); + var find = nodeSearch(1, [], children[i].value, []); } if (find[0] === true) { output.push(children[i].value); @@ -23775,10 +24649,10 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return output; } - function nodeSearch(deep, parentValues, current, isAllSelect, result) { + function nodeSearch(deep, parentValues, current, result) { if (self._isMatch(parentValues, current, keyword)) { - var checked = isAllSelect || isSelected(parentValues, current); - createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); return [true, checked]; } var newParents = BI.clone(parentValues); @@ -23787,9 +24661,8 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var can = false, checked = false; - var isCurAllSelected = isAllSelect || isAllSelected(parentValues, current); BI.each(children, function (i, child) { - var state = nodeSearch(deep + 1, newParents, child.value, isCurAllSelected, result); + var state = nodeSearch(deep + 1, newParents, child.value, result); if (state[1] === true) { checked = true; } @@ -23798,13 +24671,13 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { } }); if (can === true) { - checked = isCurAllSelected || (isSelected(parentValues, current) && checked); - createOneJson(parentValues, current, true, checked, false, false, result); + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); } return [can, checked]; } - function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { + function createOneJson(parentValues, value, isOpen, checked, flag, result) { var node = self._getTreeNode(parentValues, value); result.push({ id: node.id, @@ -23815,7 +24688,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, - halfCheck: half, + halfCheck: false, flag: flag }); } @@ -23848,15 +24721,9 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { }); } - function isSelected(parentValues, value) { - var find = findSelectedObj(parentValues); - if (find == null) { - return false; - } - return BI.any(find, function (v) { - if (v === value) { - return true; - } + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; }); } @@ -23880,16 +24747,12 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var self = this; var result = []; var times = op.times; - var checkState = op.checkState || {}; var parentValues = op.parentValues || []; - var selectedValues = op.selectedValues || {}; - var valueMap = {}; - // if (judgeState(parentValues, selectedValues, checkState)) { - valueMap = dealWidthSelectedValue(parentValues, selectedValues); - // } + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); var nodes = this._getChildren(parentValues); for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { - var state = getCheckState(nodes[i].value, parentValues, valueMap, checkState); + var checked = BI.has(valueMap, nodes[i].value); result.push({ id: nodes[i].id, pId: nodes[i].pId, @@ -23897,8 +24760,8 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { text: nodes[i].text, times: 1, isParent: nodes[i].getChildrenLength() > 0, - checked: state[0], - halfCheck: state[1] + checked: checked, + halfCheck: false }); } // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 @@ -23912,68 +24775,21 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { }); }); - function judgeState(parentValues, selected_value, checkState) { - var checked = checkState.checked, half = checkState.half; - if (parentValues.length > 0 && !checked) { - return false; - } - return (parentValues.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); - } - - function dealWidthSelectedValue(parentValues, selectedValues) { + function dealWidthSelectedValue(selectedValues) { var valueMap = {}; - BI.each(parentValues, function (i, v) { - selectedValues = selectedValues[v] || {}; - }); - BI.each(selectedValues, function (value, obj) { - if (BI.isNull(obj)) { - valueMap[value] = [0, 0]; - return; - } - if (BI.isEmpty(obj)) { - valueMap[value] = [2, 0]; - return; - } - var nextNames = {}; - BI.each(obj, function (t, o) { - if (BI.isNull(o) || BI.isEmpty(o)) { - nextNames[t] = true; - } - }); - valueMap[value] = [1, BI.size(nextNames)]; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; }); return valueMap; } - - function getCheckState(current, parentValues, valueMap, checkState) { - var checked = checkState.checked, half = checkState.half; - var tempCheck = false, halfCheck = false; - if (BI.has(valueMap, current)) { - // 可能是半选 - if (valueMap[current][0] === 1) { - var values = BI.clone(parentValues); - values.push(current); - var childCount = self._getChildCount(values); - if (childCount > 0 && childCount !== valueMap[current][1]) { - halfCheck = true; - } - } else if (valueMap[current][0] === 2) { - tempCheck = true; - } - } - var check; - if (!checked && !halfCheck && !tempCheck) { - check = BI.has(valueMap, current); - } else { - check = ((tempCheck || checked) && !half) || BI.has(valueMap, current); - } - return [check, halfCheck]; - } }, _getAddedValueNode: function (parentValues, selectedValues) { var nodes = this._getChildren(parentValues); - return BI.map(BI.difference(BI.keys(selectedValues), BI.map(nodes, "value")), function (idx, v) { + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { return { id: BI.UUID(), pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), @@ -23985,94 +24801,61 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { halfCheck: false }; }); - }, + } +});/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { - _getNode: function (selectedValues, parentValues) { - var pNode = selectedValues; - for (var i = 0, len = parentValues.length; i < len; i++) { - if (pNode == null) { - return null; - } - pNode = pNode[parentValues[i]]; - } - return pNode; + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); }, - _deleteNode: function (selectedValues, values) { - var name = values[values.length - 1]; - var p = values.slice(0, values.length - 1); - var pNode = this._getNode(selectedValues, p); - if (pNode != null && pNode[name]) { - delete pNode[name]; - // 递归删掉空父节点 - while (p.length > 0 && BI.isEmpty(pNode)) { - name = p[p.length - 1]; - p = p.slice(0, p.length - 1); - pNode = this._getNode(selectedValues, p); - if (pNode != null) { - delete pNode[name]; - } - } + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); } - }, - - _buildTree: function (jo, values) { - var t = jo; - BI.each(values, function (i, v) { - if (!BI.has(t, v)) { - t[v] = {}; - } - t = t[v]; + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height }); - }, - _isMatch: function (parentValues, value, keyword) { - var node = this._getTreeNode(parentValues, value); - if (!node) { - return false; - } - var find = BI.Func.getSearchResult([node.text || node.value], keyword); - return find.find.length > 0 || find.match.length > 0; + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); }, - _getTreeNode: function (parentValues, v) { - var self = this; - var findParentNode; - var index = 0; - this.tree.traverse(function (node) { - if (self.tree.isRoot(node)) { - return; - } - if (index > parentValues.length) { - return false; - } - if (index === parentValues.length && node.value === v) { - findParentNode = node; - return false; - } - if (node.value === parentValues[index]) { - index++; - return; - } - return true; - }); - return findParentNode; + setValue: function (v) { + this.combo.setValue(v); }, - _getChildren: function (parentValues) { - if (parentValues.length > 0) { - var value = BI.last(parentValues); - var parent = this._getTreeNode(parentValues.slice(0, parentValues.length - 1), value); - } else { - var parent = this.tree.getRoot(); - } - return parent.getChildren(); + getValue: function () { + return this.combo.getValue(); }, - _getChildCount: function (parentValues) { - return this._getChildren(parentValues).length; + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); } -});/** +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo);/** * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 * * Created by GUY on 2015/10/29. diff --git a/public/css/background.css b/public/css/background.css index 06d0a8e7f..4a8e7653f 100644 --- a/public/css/background.css +++ b/public/css/background.css @@ -51,8 +51,8 @@ _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -97,8 +97,8 @@ _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/half_selected.png'); + background: url('http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://fine-design-storage.oss-cn-shanghai.aliyuncs.com/fineui/2.0/images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/src/base/tree/ztree/jquery.ztree.excheck-3.5.js b/src/base/tree/ztree/jquery.ztree.excheck-3.5.js index 1a2774bca..fb0a5b8e8 100644 --- a/src/base/tree/ztree/jquery.ztree.excheck-3.5.js +++ b/src/base/tree/ztree/jquery.ztree.excheck-3.5.js @@ -425,6 +425,8 @@ makeChkClass: function(setting, node) { var checkedKey = setting.data.key.checked, c = consts.checkbox, r = consts.radio, + checkboxType = setting.check.chkboxType; + var notEffectByOtherNode = (checkboxType.Y === "" && checkboxType.N === ""); fullStyle = ""; if (node.chkDisabled === true) { fullStyle = c.DISABLED; @@ -433,7 +435,7 @@ } else if (setting.check.chkStyle == r.STYLE) { fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; } else { - fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) || notEffectByOtherNode ? c.FULL:c.PART) : ((node.check_Child_State < 1 || notEffectByOtherNode)? c.FULL:c.PART); } var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; diff --git a/src/base/tree/ztree/list/listasynctree.js b/src/base/tree/ztree/list/listasynctree.js new file mode 100644 index 000000000..a15c73993 --- /dev/null +++ b/src/base/tree/ztree/list/listasynctree.js @@ -0,0 +1,123 @@ +/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为["A", ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListListAsyncTree + * @extends BI.TreeView + */ +BI.ListAsyncTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListAsyncTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListAsyncTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的 + otherParam: BI.cjkEncodeDO(paras) + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + beforeExpand: beforeExpand, + beforeCheck: beforeCheck, + onClick: onClick + } + }; + + function beforeCheck (treeId, treeNode) { + treeNode.half = false; + } + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function beforeExpand (treeId, treeNode) { + self._beforeExpandNode(treeId, treeNode); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + // 展开节点 + _beforeExpandNode: function (treeId, treeNode) { + var self = this, o = this.options; + var parentValues = treeNode.parentValues || self._getParentValues(treeNode); + var op = BI.extend({}, o.paras, { + id: treeNode.id, + times: 1, + parentValues: parentValues.concat(this._getNodeValue(treeNode)) + }); + var complete = function (d) { + var nodes = d.items || []; + if (nodes.length > 0) { + callback(self._dealWidthNodes(nodes), !!d.hasNext); + } + }; + var times = 1; + + function callback (nodes, hasNext) { + self.nodes.addNodes(treeNode, nodes); + // 展开节点是没有分页的 + if (hasNext === true) { + BI.delay(function () { + times++; + op.times = times; + o.itemsCreator(op, complete); + }, 100); + } + } + + if (!treeNode.children) { + setTimeout(function () { + o.itemsCreator(op, complete); + }, 17); + } + }, + + hasChecked: function () { + return !BI.isEmpty(this.options.paras.selectedValues) || BI.ListAsyncTree.superclass.hasChecked.apply(this, arguments); + }, + + // 生成树方法 + stroke: function (config) { + delete this.options.keyword; + BI.extend(this.options.paras, config); + var setting = this._configSetting(); + this._initTree(setting); + } +}); + +BI.shortcut("bi.list_async_tree", BI.ListAsyncTree); \ No newline at end of file diff --git a/src/base/tree/ztree/list/listparttree.js b/src/base/tree/ztree/list/listparttree.js new file mode 100644 index 000000000..8a1fda13b --- /dev/null +++ b/src/base/tree/ztree/list/listparttree.js @@ -0,0 +1,92 @@ +/** + * guy + * 局部树,两个请求树, 第一个请求构造树,第二个请求获取节点 + * @class BI.ListPartTree + * @extends BI.AsyncTree + */ +BI.ListPartTree = BI.inherit(BI.ListAsyncTree, { + _defaultConfig: function () { + return BI.extend(BI.ListPartTree.superclass._defaultConfig.apply(this, arguments), {}); + }, + + _init: function () { + BI.ListPartTree.superclass._init.apply(this, arguments); + }, + + _loadMore: function () { + var self = this, o = this.options; + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: ++this.times + }); + this.tip.setLoading(); + o.itemsCreator(op, function (d) { + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + if (self._stop === true) { + return; + } + if (!hasNext) { + self.tip.setEnd(); + } else { + self.tip.setLoaded(); + } + if (nodes.length > 0) { + self.nodes.addNodes(null, self._dealWidthNodes(nodes)); + } + }); + }, + + _initTree: function (setting, keyword) { + var self = this, o = this.options; + this.times = 1; + var tree = this.tree; + tree.empty(); + self.tip.setVisible(false); + this.loading(); + var op = BI.extend({}, o.paras, { + type: BI.TreeView.REQ_TYPE_INIT_DATA, + times: this.times + }); + var complete = function (d) { + if (self._stop === true || keyword != o.paras.keyword) { + return; + } + var hasNext = !!d.hasNext, nodes = d.items || []; + o.paras.lastSearchValue = d.lastSearchValue; + // 没有请求到数据也要初始化空树, 如果不初始化, 树就是上一次构造的树, 节点信息都是过期的 + callback(nodes.length > 0 ? self._dealWidthNodes(nodes) : []); + self.setTipVisible(nodes.length <= 0); + self.loaded(); + if (!hasNext) { + self.tip.invisible(); + } else { + self.tip.setLoaded(); + } + self.fireEvent(BI.Events.AFTERINIT); + }; + + function callback (nodes) { + if (self._stop === true) { + return; + } + self.nodes = $.fn.zTree.init(tree.element, setting, nodes); + } + + BI.delay(function () { + o.itemsCreator(op, complete); + }, 100); + }, + + // 生成树方法 + stroke: function (config) { + var o = this.options; + delete o.paras.keyword; + BI.extend(o.paras, config); + delete o.paras.lastSearchValue; + var setting = this._configSetting(); + this._initTree(setting, o.paras.keyword); + } +}); + +BI.shortcut("bi.list_part_tree", BI.ListPartTree); \ No newline at end of file diff --git a/src/base/tree/ztree/list/listtreeview.js b/src/base/tree/ztree/list/listtreeview.js new file mode 100644 index 000000000..854267028 --- /dev/null +++ b/src/base/tree/ztree/list/listtreeview.js @@ -0,0 +1,114 @@ +/** + * author: windy + * 继承自treeView, 此树的父子节点的勾选状态互不影响, 此树不会有半选节点 + * 返回value格式为[["A"], ["A", "a"]]表示勾选了A且勾选了a + * @class BI.ListTreeView + * @extends BI.TreeView + */ +BI.ListTreeView = BI.inherit(BI.TreeView, { + + _constants: { + SPLIT: "<|>" + }, + + _defaultConfig: function () { + return BI.extend(BI.ListTreeView.superclass._defaultConfig.apply(this, arguments), {}); + }, + _init: function () { + BI.ListTreeView.superclass._init.apply(this, arguments); + var o = this.options; + this.storeValue = o.value || {}; + }, + + // 配置属性 + _configSetting: function () { + var paras = this.options.paras; + var self = this; + var setting = { + async: { + enable: false + }, + check: { + enable: true, + chkboxType: {Y: "", N: ""} + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + view: { + showIcon: false, + expandSpeed: "", + nameIsHTML: true, + dblClickExpand: false + }, + callback: { + onCheck: onCheck, + onClick: onClick + } + }; + + function onClick (event, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj(treeId); + var checked = treeNode.checked; + self._checkValue(treeNode, !checked); + zTree.checkNode(treeNode, !checked, true, true); + } + + function onCheck (event, treeId, treeNode) { + self._selectTreeNode(treeId, treeNode); + } + + return setting; + }, + + _selectTreeNode: function (treeId, treeNode) { + this._checkValue(treeNode, treeNode.checked); + BI.ListTreeView.superclass._selectTreeNode.apply(this, arguments); + }, + + _transArrayToMap: function (treeArrays) { + var self = this; + var map = {}; + BI.each(treeArrays, function (idx, array) { + var key = array.join(self._constants.SPLIT); + map[key] = true; + }); + return map; + }, + + _transMapToArray: function (treeMap) { + var self = this; + var array = []; + BI.each(treeMap, function (key) { + var item = key.split(self._constants.SPLIT); + array.push(item); + }); + return array; + }, + + _checkValue: function (treeNode, checked) { + var key = BI.concat(this._getParentValues(treeNode), this._getNodeValue(treeNode)).join(this._constants.SPLIT); + if(checked) { + this.storeValue[key] = true; + } else { + delete this.storeValue[key]; + } + }, + + setSelectedValue: function (value) { + this.options.paras.selectedValues = value || []; + this.storeValue = this._transArrayToMap(value); + }, + + getValue: function () { + return this._transMapToArray(this.storeValue); + } +}); + +BI.shortcut("bi.list_tree_view", BI.ListTreeView); \ No newline at end of file diff --git a/src/base/tree/ztree/parttree.js b/src/base/tree/ztree/parttree.js index c201f2141..fbd806d14 100644 --- a/src/base/tree/ztree/parttree.js +++ b/src/base/tree/ztree/parttree.js @@ -42,7 +42,14 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { var parentValues = BI.deepClone(treeNode.parentValues || self._getParentValues(treeNode)); var name = this._getNodeValue(treeNode); if (treeNode.checked === true) { - BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + this._buildTree(self.options.paras.selectedValues, BI.concat(parentValues, name)); + o.itemsCreator({ + type: BI.TreeView.REQ_TYPE_ADJUST_DATA, + selectedValues: self.options.paras.selectedValues + }, function (res) { + self.options.paras.selectedValues = res; + BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); + }); } else { // 如果选中的值中不存在该值不处理 // 因为反正是不选中,没必要管 @@ -144,12 +151,6 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { getValue: function () { var o = this.options; var result = BI.PartTree.superclass.getValue.apply(this, arguments); - o.itemsCreator({ - type: BI.TreeView.REQ_TYPE_ADJUST_DATA, - selectedValues: result - }, function (res) { - result = res; - }); return result; }, diff --git a/src/case/tree/ztree/tree.list.display.js b/src/case/tree/ztree/tree.list.display.js new file mode 100644 index 000000000..3be529e13 --- /dev/null +++ b/src/case/tree/ztree/tree.list.display.js @@ -0,0 +1,81 @@ +/** + * guy + * 异步树 + * @class BI.ListListDisplayTree + * @extends BI.TreeView + */ +BI.ListDisplayTree = BI.inherit(BI.ListTreeView, { + _defaultConfig: function () { + return BI.extend(BI.ListDisplayTree.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-list-display-tree" + }); + }, + _init: function () { + BI.ListDisplayTree.superclass._init.apply(this, arguments); + }, + + // 配置属性 + _configSetting: function () { + var setting = { + view: { + selectedMulti: false, + dblClickExpand: false, + showIcon: false, + nameIsHTML: true, + showTitle: false, + fontCss: getFont + }, + data: { + key: { + title: "title", + name: "text" + }, + simpleData: { + enable: true + } + }, + callback: { + beforeCollapse: beforeCollapse + } + }; + + function beforeCollapse(treeId, treeNode) { + return false; + } + + function getFont(treeId, node) { + return node.font ? node.font : {color: "#999999"}; + } + + return setting; + }, + + _dealWidthNodes: function (nodes) { + nodes = BI.ListDisplayTree.superclass._dealWidthNodes.apply(this, arguments); + var self = this, o = this.options; + BI.each(nodes, function (i, node) { + node.isParent = node.isParent || node.parent; + if (node.text == null) { + if (node.count > 0) { + node.text = node.value + "(" + BI.i18nText("BI-Basic_Altogether") + node.count + BI.i18nText("BI-Basic_Count") + ")"; + } + } + if(node.isLeaf === true) { + node.font = {color: "#3d4d66"}; + } + }); + return nodes; + }, + + initTree: function (nodes, setting) { + var setting = setting || this._configSetting(); + this.nodes = $.fn.zTree.init(this.tree.element, setting, nodes); + }, + + destroy: function () { + BI.ListDisplayTree.superclass.destroy.apply(this, arguments); + } +}); +BI.ListDisplayTree.EVENT_CHANGE = "EVENT_CHANGE"; + +BI.shortcut("bi.list_display_tree", BI.ListDisplayTree); \ No newline at end of file diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.list.js b/src/component/treevaluechooser/abstract.treevaluechooser.list.js new file mode 100644 index 000000000..2d43295dd --- /dev/null +++ b/src/component/treevaluechooser/abstract.treevaluechooser.list.js @@ -0,0 +1,261 @@ +BI.AbstractListTreeValueChooser = BI.inherit(BI.AbstractTreeValueChooser, { + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = {}; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck([], this.tree.getRoot(), selectedValues); + + callback({ + items: BI.values(result) + }); + + function doCheck(parentValues, node, selected) { + BI.each(selected, function (idx, path) { + BI.each(path, function (id, value) { + var nodeValue = value; + var node = self._getTreeNode(path.slice(0, id), nodeValue); + // 找不到就是新增值 + if (BI.isNull(node)) { + createOneJson({ + id: BI.UUID(), + text: nodeValue, + value: nodeValue, + isLeaf: true + }, BI.UUID()); + } else { + if(!BI.has(result, node.id)) { + createOneJson(node, node.parent && node.parent.id); + } + result[node.id].isLeaf = id === path.length - 1; + } + }); + }); + } + + function createOneJson(node, pId, leaf) { + result[node.id] = { + id: node.id, + pId: pId, + text: node.text, + value: node.value, + open: true, + isLeaf: leaf + }; + } + }, + + _reqInitTreeNode: function (op, callback) { + var self = this; + var result = []; + var keyword = op.keyword || ""; + var selectedValues = op.selectedValues; + var lastSearchValue = op.lastSearchValue || ""; // 一次请求100个,但是搜索是拿全部的,lastSearchValue是上一次遍历到的节点索引 + var output = search(); + BI.nextTick(function () { + callback({ + hasNext: output.length > self._const.perPage, + items: result, + lastSearchValue: BI.last(output) + }); + }); + + function search() { + var children = self._getChildren([]); + var start = children.length; + if (lastSearchValue !== "") { + for (var j = 0, len = start; j < len; j++) { + if (children[j].value === lastSearchValue) { + start = j + 1; + break; + } + } + } else { + start = 0; + } + var output = []; + for (var i = start, len = children.length; i < len; i++) { + if (output.length < self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, result); + } else if (output.length === self._const.perPage) { + var find = nodeSearch(1, [], children[i].value, []); + } + if (find[0] === true) { + output.push(children[i].value); + } + if (output.length > self._const.perPage) { + break; + } + } + + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (op.times === 1) { + var nodes = self._getAddedValueNode([], selectedValues); + result = BI.concat(BI.filter(nodes, function (idx, node) { + var find = BI.Func.getSearchResult([node.text || node.value], keyword); + return find.find.length > 0 || find.match.length > 0; + }), result); + } + return output; + } + + function nodeSearch(deep, parentValues, current, result) { + if (self._isMatch(parentValues, current, keyword)) { + var checked = isSelected(current); + createOneJson(parentValues, current, false, checked, true, result); + return [true, checked]; + } + var newParents = BI.clone(parentValues); + newParents.push(current); + var children = self._getChildren(newParents); + + var can = false, checked = false; + + BI.each(children, function (i, child) { + var state = nodeSearch(deep + 1, newParents, child.value, result); + if (state[1] === true) { + checked = true; + } + if (state[0] === true) { + can = true; + } + }); + if (can === true) { + checked = isSelected(current); + createOneJson(parentValues, current, true, checked, false, result); + } + return [can, checked]; + } + + function createOneJson(parentValues, value, isOpen, checked, flag, result) { + var node = self._getTreeNode(parentValues, value); + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: node.getChildrenLength() > 0, + open: isOpen, + checked: checked, + halfCheck: false, + flag: flag + }); + } + + function isHalf(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && !BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isAllSelected(parentValues, value) { + var find = findSelectedObj(parentValues); + if (find == null) { + return null; + } + return BI.any(find, function (v, ob) { + if (v === value) { + if (ob != null && BI.isEmpty(ob)) { + return true; + } + } + }); + } + + function isSelected(value) { + return BI.any(selectedValues, function (idx, array) { + return BI.last(array) === value; + }); + } + + function findSelectedObj(parentValues) { + var find = selectedValues; + if (find == null) { + return null; + } + BI.every(parentValues, function (i, v) { + find = find[v]; + if (find == null) { + return false; + } + return true; + }); + return find; + } + }, + + _reqTreeNode: function (op, callback) { + var self = this; + var result = []; + var times = op.times; + var parentValues = op.parentValues || []; + var selectedValues = op.selectedValues || []; + var valueMap = dealWidthSelectedValue(selectedValues); + var nodes = this._getChildren(parentValues); + for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { + var checked = BI.has(valueMap, nodes[i].value); + result.push({ + id: nodes[i].id, + pId: nodes[i].pId, + value: nodes[i].value, + text: nodes[i].text, + times: 1, + isParent: nodes[i].getChildrenLength() > 0, + checked: checked, + halfCheck: false + }); + } + // 深层嵌套的比较麻烦,这边先实现的是在根节点添加 + if (parentValues.length === 0 && times === 1) { + result = BI.concat(self._getAddedValueNode(parentValues, selectedValues), result); + } + BI.nextTick(function () { + callback({ + items: result, + hasNext: nodes.length > times * self._const.perPage + }); + }); + + function dealWidthSelectedValue(selectedValues) { + var valueMap = {}; + BI.each(selectedValues, function (idx, v) { + valueMap[BI.last(v)] = [2, 0]; + }); + return valueMap; + } + }, + + _getAddedValueNode: function (parentValues, selectedValues) { + var nodes = this._getChildren(parentValues); + var values = BI.flatten(BI.filter(selectedValues, function (idx, array) { + return array.length === 1; + })); + return BI.map(BI.difference(values, BI.map(nodes, "value")), function (idx, v) { + return { + id: BI.UUID(), + pId: nodes.length > 0 ? nodes[0].pId : BI.UUID(), + value: v, + text: v, + times: 1, + isParent: false, + checked: true, + halfCheck: false + }; + }); + } +}); \ No newline at end of file diff --git a/src/component/treevaluechooser/combo.listtreevaluechooser.js b/src/component/treevaluechooser/combo.listtreevaluechooser.js new file mode 100644 index 000000000..0a1d327e4 --- /dev/null +++ b/src/component/treevaluechooser/combo.listtreevaluechooser.js @@ -0,0 +1,54 @@ +/** + * 简单的复选下拉树控件, 适用于数据量少的情况, 可以自增值 + * + * Created by GUY on 2015/10/29. + * @class BI.ListTreeValueChooserInsertCombo + * @extends BI.Widget + */ +BI.ListTreeValueChooserInsertCombo = BI.inherit(BI.AbstractListTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ListTreeValueChooserInsertCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-list-tree-value-chooser-insert-combo", + width: 200, + height: 24, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.ListTreeValueChooserInsertCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this._initData(o.items); + } + this.combo = BI.createWidget({ + type: "bi.multi_tree_list_combo", + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM); + }); + }, + + setValue: function (v) { + this.combo.setValue(v); + }, + + getValue: function () { + return this.combo.getValue(); + }, + + populate: function (items) { + this._initData(items); + this.combo.populate.apply(this.combo, arguments); + } +}); +BI.ListTreeValueChooserInsertCombo.EVENT_CONFIRM = "ListTreeValueChooserInsertCombo.EVENT_CONFIRM"; +BI.shortcut("bi.list_tree_value_chooser_insert_combo", BI.ListTreeValueChooserInsertCombo); \ No newline at end of file diff --git a/src/css/base/colorchooser/colorpicker/editor.css b/src/css/base/colorchooser/colorpicker/editor.css index 1d04d58c3..493b54450 100644 --- a/src/css/base/colorchooser/colorpicker/editor.css +++ b/src/css/base/colorchooser/colorpicker/editor.css @@ -51,8 +51,8 @@ _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -97,8 +97,8 @@ _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/src/css/base/tree/tree.css b/src/css/base/tree/tree.css index 9ae37a8a1..4ba2ec450 100644 --- a/src/css/base/tree/tree.css +++ b/src/css/base/tree/tree.css @@ -19,3 +19,18 @@ opacity: 1; filter: alpha(opacity=100); } + +.bi-list-display-tree .ztree li a, +.bi-list-display-tree .ztree li span { + cursor: default !important; +} +.bi-list-display-tree .ztree li a:hover { + text-decoration: none; +} +.bi-list-display-tree .ztree li a.curSelectedNode { + padding-top: 1px; + border: none; + background-color: inherit; + opacity: 1; + filter: alpha(opacity=100); +} diff --git a/src/css/resource/background.css b/src/css/resource/background.css index 128ccf2ab..788094caa 100644 --- a/src/css/resource/background.css +++ b/src/css/resource/background.css @@ -51,8 +51,8 @@ _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/half_selected.png'); + background: url('images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -97,8 +97,8 @@ _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/half_selected.png'); + background: url('images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/src/less/base/tree/tree.list.display.less b/src/less/base/tree/tree.list.display.less new file mode 100644 index 000000000..e58d3a5dd --- /dev/null +++ b/src/less/base/tree/tree.list.display.less @@ -0,0 +1,17 @@ +@import "../../index"; + +.bi-list-display-tree{ + + & .ztree li a, & .ztree li span{ + cursor: default !important; + } + & .ztree li a:hover{ + text-decoration: none; + } + & .ztree li a.curSelectedNode{ + padding-top: 1px; + border: none; + background-color: inherit; + .opacity(1); + } +} \ No newline at end of file diff --git a/src/less/resource/background.less b/src/less/resource/background.less index c6036b3ff..e1eb69d35 100644 --- a/src/less/resource/background.less +++ b/src/less/resource/background.less @@ -47,7 +47,7 @@ } .ztree li span.button.chk.checkbox_false_part { - .image2xPath(@icon-half-select); + .image2xPath(@icon-checkbox-normal); } .ztree li span.button.chk.checkbox_false_part_focus { @@ -79,7 +79,7 @@ } .ztree.hack li span.button.chk.checkbox_false_part { - .imagePath(@icon-half-select); + .imagePath(@icon-checkbox-normal); } .ztree.hack li span.button.chk.checkbox_false_part_focus { diff --git a/src/widget/multitree/check/multi.tree.check.pane.js b/src/widget/multitree/check/multi.tree.check.pane.js index b33b77daf..b73f8d1ec 100644 --- a/src/widget/multitree/check/multi.tree.check.pane.js +++ b/src/widget/multitree/check/multi.tree.check.pane.js @@ -14,7 +14,10 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { _defaultConfig: function () { return BI.extend(BI.MultiTreeCheckPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-multi-tree-check-pane bi-background", - onClickContinueSelect: BI.emptyFn + onClickContinueSelect: BI.emptyFn, + el: { + type: "bi.display_tree" + } }); }, @@ -56,7 +59,7 @@ BI.MultiTreeCheckPane = BI.inherit(BI.Pane, { }] }); - this.display = BI.createWidget({ + this.display = BI.createWidget(opts.el, { type: "bi.display_tree", cls: "bi-multi-tree-display", itemsCreator: function (op, callback) { diff --git a/src/widget/multitree/multi.tree.list.combo.js b/src/widget/multitree/multi.tree.list.combo.js new file mode 100644 index 000000000..8d7f2e9f0 --- /dev/null +++ b/src/widget/multitree/multi.tree.list.combo.js @@ -0,0 +1,295 @@ +/** + * 可以往当前选中节点下添加新值的下拉树 + * @class BI.MultiTreeListCombo + * @extends BI.Single + */ + +BI.MultiTreeListCombo = BI.inherit(BI.Single, { + + constants: { + offset: { + top: 0, + left: 0, + right: 0, + bottom: 25 + } + }, + + _defaultConfig: function () { + return BI.extend(BI.MultiTreeListCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-list-combo", + itemsCreator: BI.emptyFn, + valueFormatter: BI.emptyFn, + height: 24 + }); + }, + + _init: function () { + BI.MultiTreeListCombo.superclass._init.apply(this, arguments); + + var self = this, o = this.options; + + var isInit = false; + var want2showCounter = false; + + this.storeValue = {value: o.value || []}; + + this.trigger = BI.createWidget({ + type: "bi.multi_select_trigger", + height: o.height, + valueFormatter: o.valueFormatter, + // adapter: this.popup, + masker: { + offset: this.constants.offset + }, + searcher: { + type: "bi.multi_list_tree_searcher", + itemsCreator: o.itemsCreator, + popup: { + type: "bi.multi_tree_search_insert_pane", + el: { + type: "bi.list_part_tree" + }, + listeners: [{ + eventName: BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, + action: function () { + self.storeValue.value.unshift([self.trigger.getSearcher().getKeyword()]); + self._assertShowValue(); + // setValue以更新paras.value, 之后从search popup中拿到的就能有add的值了 + self.combo.setValue(self.storeValue); + self.trigger.stopEditing(); + } + }] + } + }, + switcher: { + el: { + type: "bi.multi_tree_check_selected_button" + }, + popup: { + type: "bi.multi_tree_check_pane", + el: { + type: "bi.list_display_tree" + }, + itemsCreator: o.itemsCreator + } + }, + value: {value: o.value || {}} + + }); + + this.combo = BI.createWidget({ + type: "bi.combo", + toggle: false, + container: o.container, + el: this.trigger, + adjustLength: 1, + popup: { + type: "bi.multi_tree_popup_view", + ref: function () { + self.popup = this; + self.trigger.setAdapter(this); + }, + el: { + type: "bi.list_async_tree" + }, + listeners: [{ + eventName: BI.MultiTreePopup.EVENT_AFTERINIT, + action: function () { + self.trigger.getCounter().adjustView(); + isInit = true; + if (want2showCounter === true) { + showCounter(); + } + } + }, { + eventName: BI.MultiTreePopup.EVENT_CHANGE, + action: function () { + change = true; + var val = { + type: BI.Selection.Multi, + value: this.hasChecked() ? this.getValue() : [] + }; + self.trigger.getSearcher().setState(val); + self.trigger.getCounter().setButtonChecked(val); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CONFIRM, + action: function () { + self.combo.hideView(); + } + }, { + eventName: BI.MultiTreePopup.EVENT_CLICK_CLEAR, + action: function () { + clear = true; + self.setValue(); + self._defaultState(); + } + }], + itemsCreator: o.itemsCreator, + onLoaded: function () { + BI.nextTick(function () { + self.trigger.getCounter().adjustView(); + self.trigger.getSearcher().adjustView(); + }); + } + }, + value: {value: o.value || {}}, + hideChecker: function (e) { + return triggerBtn.element.find(e.target).length === 0; + } + }); + + var change = false; + var clear = false; // 标识当前是否点击了清空 + + var isSearching = function () { + return self.trigger.getSearcher().isSearching(); + }; + + var isPopupView = function () { + return self.combo.isViewVisible(); + }; + + this.trigger.on(BI.MultiSelectTrigger.EVENT_START, function () { + self.storeValue = {value: self.combo.getValue()}; + this.setValue(self.storeValue); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_STOP, function () { + self.storeValue = {value: this.getValue()}; + self.combo.setValue(self.storeValue); + BI.nextTick(function () { + if (isPopupView()) { + self.combo.populate(); + } + }); + }); + + function showCounter () { + if (isSearching()) { + self.storeValue = {value: self.trigger.getValue()}; + } else if (isPopupView()) { + self.storeValue = {value: self.combo.getValue()}; + } + self.trigger.setValue(self.storeValue); + } + + this.trigger.on(BI.MultiSelectTrigger.EVENT_BEFORE_COUNTER_POPUPVIEW, function () { + if (want2showCounter === false) { + want2showCounter = true; + } + if (isInit === true) { + want2showCounter = null; + showCounter(); + } + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_TRIGGER_CLICK, function () { + self.combo.toggle(); + }); + this.trigger.on(BI.MultiSelectTrigger.EVENT_COUNTER_CLICK, function () { + if (!self.combo.isViewVisible()) { + self.combo.showView(); + } + }); + + this.trigger.on(BI.MultiSelectTrigger.EVENT_CHANGE, function () { + var checked = this.getSearcher().hasChecked(); + var val = { + type: BI.Selection.Multi, + value: checked ? {1: 1} : {} + }; + this.getSearcher().setState(checked ? BI.Selection.Multi : BI.Selection.None); + this.getCounter().setButtonChecked(val); + }); + + this.combo.on(BI.Combo.EVENT_BEFORE_POPUPVIEW, function () { + if (isSearching()) { + return; + } + if (change === true) { + self.storeValue = {value: self.combo.getValue()}; + change = false; + } + self.combo.setValue(self.storeValue); + self.populate(); + + }); + this.combo.on(BI.Combo.EVENT_BEFORE_HIDEVIEW, function () { + if (isSearching()) { + self.trigger.stopEditing(); + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } else { + if (isPopupView()) { + self.trigger.stopEditing(); + self.storeValue = {value: self.combo.getValue()}; + if (clear === true) { + self.storeValue = {value: []}; + } + self.fireEvent(BI.MultiTreeListCombo.EVENT_CONFIRM); + } + } + clear = false; + change = false; + }); + + var triggerBtn = BI.createWidget({ + type: "bi.trigger_icon_button", + width: o.height, + height: o.height, + cls: "multi-select-trigger-icon-button" + }); + triggerBtn.on(BI.TriggerIconButton.EVENT_CHANGE, function () { + self.trigger.getCounter().hideView(); + if (self.combo.isViewVisible()) { + self.combo.hideView(); + } else { + self.combo.showView(); + } + }); + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: this.combo, + left: 0, + right: 0, + top: 0, + bottom: 0 + }, { + el: triggerBtn, + right: 0, + top: 0, + bottom: 0 + }] + }); + }, + + _assertShowValue: function () { + this.trigger.getSearcher().setState(this.storeValue); + this.trigger.getCounter().setButtonChecked(this.storeValue); + }, + + _defaultState: function () { + this.trigger.stopEditing(); + this.combo.hideView(); + }, + + setValue: function (v) { + this.storeValue.value = v || []; + this.combo.setValue({ + value: v || [] + }); + }, + + getValue: function () { + return this.storeValue.value; + }, + + populate: function () { + this.combo.populate.apply(this.combo, arguments); + } +}); + +BI.MultiTreeListCombo.EVENT_CONFIRM = "MultiTreeListCombo.EVENT_CONFIRM"; + +BI.shortcut("bi.multi_tree_list_combo", BI.MultiTreeListCombo); \ No newline at end of file diff --git a/src/widget/multitree/multi.tree.popup.js b/src/widget/multitree/multi.tree.popup.js index 7a38c7beb..64d54d66b 100644 --- a/src/widget/multitree/multi.tree.popup.js +++ b/src/widget/multitree/multi.tree.popup.js @@ -11,24 +11,27 @@ BI.MultiTreePopup = BI.inherit(BI.Pane, { maxWidth: "auto", minWidth: 100, maxHeight: 400, - onLoaded: BI.emptyFn + onLoaded: BI.emptyFn, + el: { + type: "bi.async_tree" + } }); }, _init: function () { BI.MultiTreePopup.superclass._init.apply(this, arguments); - var self = this, opts = this.options; + var self = this, opts = this.options, v = opts.value; this.selectedValues = {}; - this.tree = BI.createWidget({ + this.tree = BI.createWidget(opts.el, { type: "bi.async_tree", height: 400, cls: "popup-view-tree", itemsCreator: opts.itemsCreator, onLoaded: opts.onLoaded, - value: opts.value || {} + value: v.value || {} }); this.popupView = BI.createWidget({ diff --git a/src/widget/multitree/trigger/multi.tree.search.insert.pane.js b/src/widget/multitree/trigger/multi.tree.search.insert.pane.js index ccad8fede..cc5bff3c9 100644 --- a/src/widget/multitree/trigger/multi.tree.search.insert.pane.js +++ b/src/widget/multitree/trigger/multi.tree.search.insert.pane.js @@ -14,52 +14,65 @@ BI.MultiTreeSearchInsertPane = BI.inherit(BI.Widget, { props: { baseCls: "bi-multi-tree-search-insert-pane bi-card", itemsCreator: BI.emptyFn, - keywordGetter: BI.emptyFn + keywordGetter: BI.emptyFn, + el: { + type: "bi.part_tree" + } }, render: function () { var self = this, opts = this.options; return { - type: "bi.vertical", + type: "bi.absolute", items: [{ - type: "bi.text_button", - invisible: true, - ref: function (_ref) { - self.addTip = _ref; + el: { + type: "bi.text_button", + invisible: true, + ref: function (_ref) { + self.addTip = _ref; + }, + text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), + height: this.constants.height, + cls: "bi-high-light", + handler: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); + } }, - text: BI.i18nText("BI-Basic_Click_To_Add_Text", ""), - height: this.constants.height, - cls: "bi-high-light", - hgap: 5, - handler: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_ADD_ITEM, opts.keywordGetter()); - } + top: 5, + left: 0, + right: 0 }, { - type: "bi.part_tree", - tipText: BI.i18nText("BI-No_Select"), - itemsCreator: function (op, callback) { - op.keyword = opts.keywordGetter(); - opts.itemsCreator(op, function (res) { - callback(res); - self.setKeyword(opts.keywordGetter(), res.items); - }); - }, - ref: function (_ref) { - self.partTree = _ref; - }, - value: opts.value, - listeners: [{ - eventName: BI.Controller.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); - } - }, { - eventName: BI.TreeView.EVENT_CHANGE, - action: function () { - self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); - } - }] + el: BI.extend({ + type: "bi.part_tree", + tipText: BI.i18nText("BI-No_Select"), + itemsCreator: function (op, callback) { + op.keyword = opts.keywordGetter(); + opts.itemsCreator(op, function (res) { + callback(res); + self.setKeyword(opts.keywordGetter(), res.items); + }); + }, + ref: function (_ref) { + self.partTree = _ref; + }, + value: opts.value, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); + } + }, { + eventName: BI.TreeView.EVENT_CHANGE, + action: function () { + self.fireEvent(BI.MultiTreeSearchInsertPane.EVENT_CHANGE); + } + }] + }, opts.el), + left: 0, + top: 0, + bottom: 0, + right: 0 }] }; }, diff --git a/src/widget/multitree/multi.tree.search.pane.js b/src/widget/multitree/trigger/multi.tree.search.pane.js similarity index 100% rename from src/widget/multitree/multi.tree.search.pane.js rename to src/widget/multitree/trigger/multi.tree.search.pane.js diff --git a/src/widget/multitree/trigger/searcher.list.multi.tree.js b/src/widget/multitree/trigger/searcher.list.multi.tree.js new file mode 100644 index 000000000..acfe1cf45 --- /dev/null +++ b/src/widget/multitree/trigger/searcher.list.multi.tree.js @@ -0,0 +1,158 @@ +/** + * searcher + * Created by guy on 15/11/3. + * @class BI.MultiListTreeSearcher + * @extends Widget + */ +BI.MultiListTreeSearcher = BI.inherit(BI.Widget, { + + _defaultConfig: function () { + return BI.extend(BI.MultiListTreeSearcher.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-multi-tree-searcher", + itemsCreator: BI.emptyFn, + valueFormatter: function (v) { + return v; + }, + popup: {}, + + adapter: null, + masker: {} + }); + }, + + _init: function () { + BI.MultiListTreeSearcher.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.editor = BI.createWidget({ + type: "bi.multi_select_editor", + height: o.height, + el: { + type: "bi.simple_state_editor", + height: o.height + } + }); + + this.searcher = BI.createWidget({ + type: "bi.searcher", + element: this, + isAutoSearch: false, + isAutoSync: false, + onSearch: function (op, callback) { + callback({ + keyword: self.editor.getValue() + }); + }, + el: this.editor, + + popup: BI.extend({ + type: "bi.multi_tree_search_pane", + keywordGetter: function () { + return self.editor.getValue(); + }, + itemsCreator: function (op, callback) { + op.keyword = self.editor.getValue(); + o.itemsCreator(op, callback); + }, + value: o.value + }, o.popup), + + adapter: o.adapter, + masker: o.masker + }); + this.searcher.on(BI.Searcher.EVENT_START, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_START); + }); + this.searcher.on(BI.Searcher.EVENT_PAUSE, function () { + if (this.hasMatched()) { + + } + self.fireEvent(BI.MultiListTreeSearcher.EVENT_PAUSE); + }); + this.searcher.on(BI.Searcher.EVENT_STOP, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_STOP); + }); + this.searcher.on(BI.Searcher.EVENT_CHANGE, function () { + self.fireEvent(BI.MultiListTreeSearcher.EVENT_CHANGE, arguments); + }); + if (BI.isNotNull(o.value)) { + this.setState(o.value); + } + }, + + adjustView: function () { + this.searcher.adjustView(); + }, + + setAdapter: function (adapter) { + this.searcher.setAdapter(adapter); + }, + + isSearching: function () { + return this.searcher.isSearching(); + }, + + stopSearch: function () { + this.searcher.stopSearch(); + }, + + getKeyword: function () { + return this.editor.getValue(); + }, + + hasMatched: function () { + return this.searcher.hasMatched(); + }, + + hasChecked: function () { + return this.searcher.getView() && this.searcher.getView().hasChecked(); + }, + + setState: function (ob) { + var o = this.options; + ob || (ob = {}); + ob.value || (ob.value = []); + var count = 0; + if (BI.isNumber(ob)) { + this.editor.setState(ob); + } else if (BI.size(ob.value) === 0) { + this.editor.setState(BI.Selection.None); + } else { + var text = ""; + BI.each(ob.value, function (idx, path) { + var childValue = BI.last(path); + text += (o.valueFormatter(childValue + "") || childValue) + "; "; + count++; + }); + + if (count > 20) { + this.editor.setState(BI.Selection.Multi); + } else { + this.editor.setState(text); + } + } + }, + + setValue: function (ob) { + this.setState(ob); + this.searcher.setValue(ob); + }, + + getKey: function () { + return this.editor.getValue(); + }, + + getValue: function () { + return this.searcher.getValue(); + }, + + populate: function (items) { + this.searcher.populate.apply(this.searcher, arguments); + } +}); + +BI.MultiListTreeSearcher.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; +BI.MultiListTreeSearcher.EVENT_CHANGE = "EVENT_CHANGE"; +BI.MultiListTreeSearcher.EVENT_START = "EVENT_START"; +BI.MultiListTreeSearcher.EVENT_STOP = "EVENT_STOP"; +BI.MultiListTreeSearcher.EVENT_PAUSE = "EVENT_PAUSE"; +BI.shortcut("bi.multi_list_tree_searcher", BI.MultiListTreeSearcher); \ No newline at end of file diff --git a/ui/css/background.css b/ui/css/background.css index c03b30dc3..98501eb71 100644 --- a/ui/css/background.css +++ b/ui/css/background.css @@ -51,8 +51,8 @@ _background: none; } .ztree li span.button.chk.checkbox_false_part { - background: url('resources?path=/com/fr/web/ui/images/2x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/2x/icon/half_selected.png'); + background: url('resources?path=/com/fr/web/ui/images/2x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/2x/icon/check_box_normal.png'); background-size: contain; _background: none; } @@ -97,8 +97,8 @@ _background: none; } .ztree.hack li span.button.chk.checkbox_false_part { - background: url('resources?path=/com/fr/web/ui/images/1x/icon/half_selected.png') no-repeat center center; - _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/1x/icon/half_selected.png'); + background: url('resources?path=/com/fr/web/ui/images/1x/icon/check_box_normal.png') no-repeat center center; + _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='resources?path=/com/fr/web/ui/images/1x/icon/check_box_normal.png'); _background: none; } .ztree.hack li span.button.chk.checkbox_false_part_focus {