From a0b32e433bca2a26754b1fef7d9f7c37a631ec6d Mon Sep 17 00:00:00 2001 From: young Date: Sat, 20 May 2017 10:15:27 +0800 Subject: [PATCH 01/27] multiTree updateValue --- src/widget/multiselecttree/multiselecttree.js | 8 ++++++++ src/widget/multiselecttree/multiselecttree.popup.js | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/widget/multiselecttree/multiselecttree.js b/src/widget/multiselecttree/multiselecttree.js index 4475e433e2..45bcbded5e 100644 --- a/src/widget/multiselecttree/multiselecttree.js +++ b/src/widget/multiselecttree/multiselecttree.js @@ -142,6 +142,14 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }); }, + stopSearch: function () { + this.trigger.stopSearch(); + }, + + updateValue: function (v) { + this.adapter.updateValue(v); + }, + getValue: function () { return this.storeValue.value; }, diff --git a/src/widget/multiselecttree/multiselecttree.popup.js b/src/widget/multiselecttree/multiselecttree.popup.js index 8f8ee61b2e..10906311f0 100644 --- a/src/widget/multiselecttree/multiselecttree.popup.js +++ b/src/widget/multiselecttree/multiselecttree.popup.js @@ -38,6 +38,11 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { this.popup.setValue(v.value); }, + updateValue: function (v) { + this.popup.updateValue(v); + this.popup.refresh(); + }, + populate: function (config) { this.popup.stroke(config); } From eebb79b1ac48d251ce43ad722ebddb527ba99fea Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 15:20:57 +0800 Subject: [PATCH 02/27] add --- bi/base.js | 12 ++++++------ docs/base.js | 12 ++++++------ src/base/collection/collection.js | 4 ++-- src/base/grid/grid.js | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bi/base.js b/bi/base.js index 165a9b0259..728e5fd04f 100644 --- a/bi/base.js +++ b/bi/base.js @@ -2532,8 +2532,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, @@ -14673,16 +14673,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, rowHeightGetter: BI.emptyFn, columnWidthGetter: BI.emptyFn, - estimatedColumnSize: 100, - estimatedRowSize: 30, + // estimatedColumnSize: 100, + // estimatedRowSize: 30, scrollLeft: 0, scrollTop: 0, items: [] diff --git a/docs/base.js b/docs/base.js index 165a9b0259..728e5fd04f 100644 --- a/docs/base.js +++ b/docs/base.js @@ -2532,8 +2532,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, @@ -14673,16 +14673,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, rowHeightGetter: BI.emptyFn, columnWidthGetter: BI.emptyFn, - estimatedColumnSize: 100, - estimatedRowSize: 30, + // estimatedColumnSize: 100, + // estimatedRowSize: 30, scrollLeft: 0, scrollTop: 0, items: [] diff --git a/src/base/collection/collection.js b/src/base/collection/collection.js index d359668a56..ab942f7bcf 100644 --- a/src/base/collection/collection.js +++ b/src/base/collection/collection.js @@ -9,8 +9,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, diff --git a/src/base/grid/grid.js b/src/base/grid/grid.js index c76f354c75..3ff3ff30fd 100644 --- a/src/base/grid/grid.js +++ b/src/base/grid/grid.js @@ -9,16 +9,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - width: 400, - height: 300, + // width: 400, + // height: 300, overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, rowHeightGetter: BI.emptyFn, columnWidthGetter: BI.emptyFn, - estimatedColumnSize: 100, - estimatedRowSize: 30, + // estimatedColumnSize: 100, + // estimatedRowSize: 30, scrollLeft: 0, scrollTop: 0, items: [] From e15c61b6e4e9c0baa007c4e6b02b0ab0e7f79ed2 Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 17:19:43 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=A0=91=E3=80=81?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bi/widget.js | 402 +++++++++---- ...ooser.js => demo.treevaluechoosercombo.js} | 6 +- .../js/component/demo.treevaluechooserpane.js | 34 ++ ...uechooser.js => demo.valuechoosercombo.js} | 0 demo/js/component/demo.valuechooserpane.js | 15 + demo/js/config/component.js | 10 +- docs/demo.js | 66 ++- docs/widget.js | 402 +++++++++---- .../abstract.allvaluechooser.js | 79 +++ .../allvaluechooser/combo.allvaluechooser.js | 62 +- .../allvaluechooser/pane.allvaluechooser.js | 62 ++ .../abstract.treevaluechooser.js | 555 ++++++++++++++++++ .../combo.treevaluechooser.js | 550 +---------------- .../treevaluechooser/pane.treevaluechooser.js | 49 ++ .../valuechooser/abstract.valuechooser.js | 89 +++ .../valuechooser/combo.valuechooser.js | 72 +-- .../valuechooser/pane.valuechooser.js | 58 ++ src/widget/multiselectlist/multiselectlist.js | 7 +- src/widget/multiselecttree/multiselecttree.js | 8 +- .../multiselecttree/multiselecttree.popup.js | 1 - 20 files changed, 1629 insertions(+), 898 deletions(-) rename demo/js/component/{demo.treevaluechooser.js => demo.treevaluechoosercombo.js} (85%) create mode 100644 demo/js/component/demo.treevaluechooserpane.js rename demo/js/component/{demo.valuechooser.js => demo.valuechoosercombo.js} (100%) create mode 100644 demo/js/component/demo.valuechooserpane.js create mode 100644 src/component/allvaluechooser/abstract.allvaluechooser.js create mode 100644 src/component/allvaluechooser/pane.allvaluechooser.js create mode 100644 src/component/treevaluechooser/abstract.treevaluechooser.js create mode 100644 src/component/treevaluechooser/pane.treevaluechooser.js create mode 100644 src/component/valuechooser/abstract.valuechooser.js create mode 100644 src/component/valuechooser/pane.valuechooser.js diff --git a/bi/widget.js b/bi/widget.js index 55d86a401e..7e9bde29b8 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -10962,8 +10962,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { return BI.extend(BI.MultiSelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-list', itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - el: {} + valueFormatter: BI.emptyFn }) }, _init: function () { @@ -11096,8 +11095,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -11109,8 +11106,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, @@ -11307,8 +11302,7 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectTree.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-tree', - itemsCreator: BI.emptyFn, - height: 25 + itemsCreator: BI.emptyFn }) }, @@ -11354,7 +11348,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }, adapter: this.adapter, popup: this.searcherPane, - height: 200, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, @@ -11394,8 +11387,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -11407,8 +11398,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, @@ -11469,7 +11458,6 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { var self = this, o = this.options; this.popup = BI.createWidget({ type: "bi.async_tree", - height: 400, element: this, itemsCreator: o.itemsCreator }); @@ -16978,14 +16966,14 @@ BI.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo);/** * @class BI.AllValueChooserCombo * @extends BI.Widget */ -BI.AllValueChooserCombo = BI.inherit(BI.Widget, { +BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { _const: { - perPage: 10 + perPage: 100 }, + _defaultConfig: function () { return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-all-value-chooser-combo", width: 200, height: 30, items: null, @@ -16994,35 +16982,17 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { }); }, - _init: function () { - BI.AllValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: 'bi.multi_select_combo', - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; } - return text; - }, - width: o.width, - height: o.height - }); - - this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); - }); + }); + } + return text; }, _itemsCreator: function (options, callback) { @@ -17065,6 +17035,46 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { hasNext: false }); } + } +});/** + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.AllValueChooserCombo + * @extends BI.AbstractAllValueChooser + */ +BI.AllValueChooserCombo = BI.inherit(BI.AbstractAllValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-all-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.AllValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_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.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17088,44 +17098,76 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { }); BI.AllValueChooserCombo.EVENT_CONFIRM = "AllValueChooserCombo.EVENT_CONFIRM"; BI.shortcut('bi.all_value_chooser_combo', BI.AllValueChooserCombo);/** - * 简单的复选下拉树控件, 适用于数据量少的情况 + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.TreeValueChooserCombo - * @extends BI.Widget + * @class BI.AllValueChooserPane + * @extends BI.AbstractAllValueChooser */ -BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { - - _const: { - perPage: 10 - }, +BI.AllValueChooserPane = BI.inherit(BI.AbstractAllValueChooser, { _defaultConfig: function () { - return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-value-chooser-combo", + return BI.extend(BI.AllValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-all-value-chooser-pane", width: 200, height: 30, items: null, - itemsCreator: BI.emptyFn + itemsCreator: BI.emptyFn, + cache: true }); }, _init: function () { - BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); + BI.AllValueChooserPane.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { - this._initData(o.items); + this.items = o.items; } - this.combo = BI.createWidget({ - type: 'bi.multi_tree_combo', + this.list = BI.createWidget({ + type: 'bi.multi_select_list', 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.TreeValueChooserCombo.EVENT_CONFIRM); + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.AllValueChooserPane.EVENT_CHANGE); + }); + }, + + setValue: function (v) { + this.list.setValue({ + type: BI.Selection.Multi, + value: v || [] + }); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + if (val.type === BI.Selection.All) { + return val.assist; + } + return val.value || []; + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.AllValueChooserPane.EVENT_CHANGE = "AllValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { + + _const: { + perPage: 100 + }, + + _defaultConfig: function () { + return BI.extend(BI.AbstractTreeValueChooser.superclass._defaultConfig.apply(this, arguments), { + items: null, + itemsCreator: BI.emptyFn }); }, @@ -17669,6 +17711,43 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; + } +});/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserCombo + * @extends BI.Widget + */ +BI.TreeValueChooserCombo = BI.inherit(BI.AbstractTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserCombo.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_combo', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17680,63 +17759,91 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { }, populate: function () { - this.combo.populate.apply(this, arguments); + this.combo.populate.apply(this.combo, arguments); } }); BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; BI.shortcut('bi.tree_value_chooser_combo', BI.TreeValueChooserCombo);/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserPane + * @extends BI.AbstractTreeValueChooser + */ +BI.TreeValueChooserPane = BI.inherit(BI.AbstractTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-pane", + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.pane = BI.createWidget({ + type: 'bi.multi_select_tree', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this) + }); + + this.pane.on(BI.MultiSelectTree.EVENT_CHANGE, function () { + self.fireEvent(BI.TreeValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this._initData(o.items); + this.populate(); + } + }, + + setValue: function (v) { + this.pane.setValue(v); + }, + + getValue: function () { + return this.pane.getValue(); + }, + + populate: function () { + this.pane.populate.apply(this.pane, arguments); + } +}); +BI.TreeValueChooserPane.EVENT_CHANGE = "TreeValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.tree_value_chooser_pane', BI.TreeValueChooserPane);/** * 简单的复选下拉框控件, 适用于数据量少的情况 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.ValueChooserCombo + * @class BI.AbstractValueChooser * @extends BI.Widget */ -BI.ValueChooserCombo = BI.inherit(BI.Widget, { +BI.AbstractValueChooser = BI.inherit(BI.Widget, { _const: { - perPage: 10 + perPage: 100 }, + _defaultConfig: function () { - return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-value-chooser-combo", - width: 200, - height: 30, + return BI.extend(BI.AbstractValueChooser.superclass._defaultConfig.apply(this, arguments), { items: null, itemsCreator: BI.emptyFn, cache: true }); }, - _init: function () { - BI.ValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: 'bi.multi_select_combo', - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; } - return text; - }, - width: o.width, - height: o.height - }); - - this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); - }); + }); + } + return text; }, _getItemsByTimes: function (items, times) { @@ -17791,6 +17898,46 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { hasNext: self._hasNextByTimes(items, options.times) }); } + } +});/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserCombo + * @extends BI.Widget + */ +BI.ValueChooserCombo = BI.inherit(BI.AbstractValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_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.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17810,4 +17957,61 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { } }); BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; -BI.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo); \ No newline at end of file +BI.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo);/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserPane + * @extends BI.Widget + */ +BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-pane", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.list = BI.createWidget({ + type: 'bi.multi_select_list', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this) + }); + + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.ValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this.items = o.items; + this.populate(); + } + }, + + setValue: function (v) { + this.list.setValue(v); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + return { + type: val.type, + value: val.value + } + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.ValueChooserPane.EVENT_CHANGE = "ValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.value_chooser_pane', BI.ValueChooserPane); \ No newline at end of file diff --git a/demo/js/component/demo.treevaluechooser.js b/demo/js/component/demo.treevaluechoosercombo.js similarity index 85% rename from demo/js/component/demo.treevaluechooser.js rename to demo/js/component/demo.treevaluechoosercombo.js index dcbcc8c4b2..5de2bcdeb7 100644 --- a/demo/js/component/demo.treevaluechooser.js +++ b/demo/js/component/demo.treevaluechoosercombo.js @@ -1,11 +1,11 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { props: { - baseCls: "demo-tree-value-chooser" + baseCls: "demo-tree-value-chooser-combo" }, render: function () { var tree = []; - for (var i = 0; i < 21; i++) { + for (var i = 0; i < 221; i++) { tree.push({ value: "" + i + "", text: "" + i + "", @@ -37,4 +37,4 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }; } }); -BI.shortcut("demo.tree_value_chooser", Demo.TreeValueChooser); +BI.shortcut("demo.tree_value_chooser_combo", Demo.TreeValueChooser); diff --git a/demo/js/component/demo.treevaluechooserpane.js b/demo/js/component/demo.treevaluechooserpane.js new file mode 100644 index 0000000000..e74caac7e7 --- /dev/null +++ b/demo/js/component/demo.treevaluechooserpane.js @@ -0,0 +1,34 @@ +Demo.TreeValueChooser = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-tree-value-chooser" + }, + render: function () { + + var tree = []; + for (var i = 0; i < 221; i++) { + tree.push({ + value: "" + i + "", + text: "" + i + "", + id: i + "", + pId: null + }); + for (var j = 0; j < 9; j++) { + tree.push({ + value: i + "-" + j, + text: j + "", + id: i + "-" + j, + pId: i + "" + }) + } + } + return { + type: "bi.tree_value_chooser_pane", + width: 300, + items: tree, + itemsCreator: function (op, callback) { + callback(tree); + } + }; + } +}); +BI.shortcut("demo.tree_value_chooser_pane", Demo.TreeValueChooser); diff --git a/demo/js/component/demo.valuechooser.js b/demo/js/component/demo.valuechoosercombo.js similarity index 100% rename from demo/js/component/demo.valuechooser.js rename to demo/js/component/demo.valuechoosercombo.js diff --git a/demo/js/component/demo.valuechooserpane.js b/demo/js/component/demo.valuechooserpane.js new file mode 100644 index 0000000000..f2ff3ba7e6 --- /dev/null +++ b/demo/js/component/demo.valuechooserpane.js @@ -0,0 +1,15 @@ +Demo.ValueChooserPane = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-value-chooser-pane" + }, + render: function () { + return { + type: "bi.value_chooser_pane", + items: BI.deepClone(Demo.CONSTANTS.ITEMS), + itemsCreator: function (op, callback) { + callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); + } + }; + } +}); +BI.shortcut("demo.value_chooser_pane", Demo.ValueChooserPane); \ No newline at end of file diff --git a/demo/js/config/component.js b/demo/js/config/component.js index b797e09f3c..1815ca70a0 100644 --- a/demo/js/config/component.js +++ b/demo/js/config/component.js @@ -8,8 +8,16 @@ Demo.COMPONENT_CONFIG = [{ pId: 5, text: "bi.value_chooser_combo", value: "demo.value_chooser_combo" +}, { + pId: 5, + text: "bi.value_chooser_pane", + value: "demo.value_chooser_pane" }, { pId: 5, text: "bi.tree_value_chooser_combo", - value: "demo.tree_value_chooser" + value: "demo.tree_value_chooser_combo" +}, { + pId: 5, + text: "bi.tree_value_chooser_pane", + value: "demo.tree_value_chooser_pane" }]; \ No newline at end of file diff --git a/docs/demo.js b/docs/demo.js index f1787c8f12..7cec4c55d6 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -2620,12 +2620,12 @@ BI.shortcut("demo.center", Demo.Center);Demo.Func = BI.inherit(BI.Widget, { BI.shortcut("demo.axis_chart", Demo.Func); Demo.TreeValueChooser = BI.inherit(BI.Widget, { props: { - baseCls: "demo-tree-value-chooser" + baseCls: "demo-tree-value-chooser-combo" }, render: function () { var tree = []; - for (var i = 0; i < 21; i++) { + for (var i = 0; i < 221; i++) { tree.push({ value: "" + i + "", text: "" + i + "", @@ -2657,7 +2657,41 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }; } }); -BI.shortcut("demo.tree_value_chooser", Demo.TreeValueChooser); +BI.shortcut("demo.tree_value_chooser_combo", Demo.TreeValueChooser); +Demo.TreeValueChooser = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-tree-value-chooser" + }, + render: function () { + + var tree = []; + for (var i = 0; i < 221; i++) { + tree.push({ + value: "" + i + "", + text: "" + i + "", + id: i + "", + pId: null + }); + for (var j = 0; j < 9; j++) { + tree.push({ + value: i + "-" + j, + text: j + "", + id: i + "-" + j, + pId: i + "" + }) + } + } + return { + type: "bi.tree_value_chooser_pane", + width: 300, + items: tree, + itemsCreator: function (op, callback) { + callback(tree); + } + }; + } +}); +BI.shortcut("demo.tree_value_chooser_pane", Demo.TreeValueChooser); Demo.ValueChooserCombo = BI.inherit(BI.Widget, { props: { baseCls: "demo-value-chooser-combo" @@ -2677,7 +2711,21 @@ Demo.ValueChooserCombo = BI.inherit(BI.Widget, { }; } }); -BI.shortcut("demo.value_chooser_combo", Demo.ValueChooserCombo);Demo.BASE_CONFIG = [{ +BI.shortcut("demo.value_chooser_combo", Demo.ValueChooserCombo);Demo.ValueChooserPane = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-value-chooser-pane" + }, + render: function () { + return { + type: "bi.value_chooser_pane", + items: BI.deepClone(Demo.CONSTANTS.ITEMS), + itemsCreator: function (op, callback) { + callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); + } + }; + } +}); +BI.shortcut("demo.value_chooser_pane", Demo.ValueChooserPane);Demo.BASE_CONFIG = [{ id: 2, text: "基础控件", open: true @@ -2906,10 +2954,18 @@ Demo.COMPONENT_CONFIG = [{ pId: 5, text: "bi.value_chooser_combo", value: "demo.value_chooser_combo" +}, { + pId: 5, + text: "bi.value_chooser_pane", + value: "demo.value_chooser_pane" }, { pId: 5, text: "bi.tree_value_chooser_combo", - value: "demo.tree_value_chooser" + value: "demo.tree_value_chooser_combo" +}, { + pId: 5, + text: "bi.tree_value_chooser_pane", + value: "demo.tree_value_chooser_pane" }];Demo.CORE_CONFIG = [{ id: 1, text: "核心控件", diff --git a/docs/widget.js b/docs/widget.js index 55d86a401e..7e9bde29b8 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -10962,8 +10962,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { return BI.extend(BI.MultiSelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-list', itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - el: {} + valueFormatter: BI.emptyFn }) }, _init: function () { @@ -11096,8 +11095,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -11109,8 +11106,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, @@ -11307,8 +11302,7 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectTree.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-tree', - itemsCreator: BI.emptyFn, - height: 25 + itemsCreator: BI.emptyFn }) }, @@ -11354,7 +11348,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }, adapter: this.adapter, popup: this.searcherPane, - height: 200, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, @@ -11394,8 +11387,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -11407,8 +11398,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, @@ -11469,7 +11458,6 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { var self = this, o = this.options; this.popup = BI.createWidget({ type: "bi.async_tree", - height: 400, element: this, itemsCreator: o.itemsCreator }); @@ -16978,14 +16966,14 @@ BI.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo);/** * @class BI.AllValueChooserCombo * @extends BI.Widget */ -BI.AllValueChooserCombo = BI.inherit(BI.Widget, { +BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { _const: { - perPage: 10 + perPage: 100 }, + _defaultConfig: function () { return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-all-value-chooser-combo", width: 200, height: 30, items: null, @@ -16994,35 +16982,17 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { }); }, - _init: function () { - BI.AllValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: 'bi.multi_select_combo', - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; } - return text; - }, - width: o.width, - height: o.height - }); - - this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); - }); + }); + } + return text; }, _itemsCreator: function (options, callback) { @@ -17065,6 +17035,46 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { hasNext: false }); } + } +});/** + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.AllValueChooserCombo + * @extends BI.AbstractAllValueChooser + */ +BI.AllValueChooserCombo = BI.inherit(BI.AbstractAllValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-all-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.AllValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_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.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.AllValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17088,44 +17098,76 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { }); BI.AllValueChooserCombo.EVENT_CONFIRM = "AllValueChooserCombo.EVENT_CONFIRM"; BI.shortcut('bi.all_value_chooser_combo', BI.AllValueChooserCombo);/** - * 简单的复选下拉树控件, 适用于数据量少的情况 + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.TreeValueChooserCombo - * @extends BI.Widget + * @class BI.AllValueChooserPane + * @extends BI.AbstractAllValueChooser */ -BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { - - _const: { - perPage: 10 - }, +BI.AllValueChooserPane = BI.inherit(BI.AbstractAllValueChooser, { _defaultConfig: function () { - return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-tree-value-chooser-combo", + return BI.extend(BI.AllValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-all-value-chooser-pane", width: 200, height: 30, items: null, - itemsCreator: BI.emptyFn + itemsCreator: BI.emptyFn, + cache: true }); }, _init: function () { - BI.TreeValueChooserCombo.superclass._init.apply(this, arguments); + BI.AllValueChooserPane.superclass._init.apply(this, arguments); var self = this, o = this.options; if (BI.isNotNull(o.items)) { - this._initData(o.items); + this.items = o.items; } - this.combo = BI.createWidget({ - type: 'bi.multi_tree_combo', + this.list = BI.createWidget({ + type: 'bi.multi_select_list', 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.TreeValueChooserCombo.EVENT_CONFIRM); + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.AllValueChooserPane.EVENT_CHANGE); + }); + }, + + setValue: function (v) { + this.list.setValue({ + type: BI.Selection.Multi, + value: v || [] + }); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + if (val.type === BI.Selection.All) { + return val.assist; + } + return val.value || []; + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.AllValueChooserPane.EVENT_CHANGE = "AllValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { + + _const: { + perPage: 100 + }, + + _defaultConfig: function () { + return BI.extend(BI.AbstractTreeValueChooser.superclass._defaultConfig.apply(this, arguments), { + items: null, + itemsCreator: BI.emptyFn }); }, @@ -17669,6 +17711,43 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { _getChildCount: function (parentValues) { return this._getChildren(parentValues).length; + } +});/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserCombo + * @extends BI.Widget + */ +BI.TreeValueChooserCombo = BI.inherit(BI.AbstractTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserCombo.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_combo', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + width: o.width, + height: o.height + }); + + this.combo.on(BI.MultiTreeCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.TreeValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17680,63 +17759,91 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { }, populate: function () { - this.combo.populate.apply(this, arguments); + this.combo.populate.apply(this.combo, arguments); } }); BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; BI.shortcut('bi.tree_value_chooser_combo', BI.TreeValueChooserCombo);/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserPane + * @extends BI.AbstractTreeValueChooser + */ +BI.TreeValueChooserPane = BI.inherit(BI.AbstractTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-pane", + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.pane = BI.createWidget({ + type: 'bi.multi_select_tree', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this) + }); + + this.pane.on(BI.MultiSelectTree.EVENT_CHANGE, function () { + self.fireEvent(BI.TreeValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this._initData(o.items); + this.populate(); + } + }, + + setValue: function (v) { + this.pane.setValue(v); + }, + + getValue: function () { + return this.pane.getValue(); + }, + + populate: function () { + this.pane.populate.apply(this.pane, arguments); + } +}); +BI.TreeValueChooserPane.EVENT_CHANGE = "TreeValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.tree_value_chooser_pane', BI.TreeValueChooserPane);/** * 简单的复选下拉框控件, 适用于数据量少的情况 * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.ValueChooserCombo + * @class BI.AbstractValueChooser * @extends BI.Widget */ -BI.ValueChooserCombo = BI.inherit(BI.Widget, { +BI.AbstractValueChooser = BI.inherit(BI.Widget, { _const: { - perPage: 10 + perPage: 100 }, + _defaultConfig: function () { - return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-value-chooser-combo", - width: 200, - height: 30, + return BI.extend(BI.AbstractValueChooser.superclass._defaultConfig.apply(this, arguments), { items: null, itemsCreator: BI.emptyFn, cache: true }); }, - _init: function () { - BI.ValueChooserCombo.superclass._init.apply(this, arguments); - var self = this, o = this.options; - if (BI.isNotNull(o.items)) { - this.items = o.items; - } - this.combo = BI.createWidget({ - type: 'bi.multi_select_combo', - element: this, - itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; } - return text; - }, - width: o.width, - height: o.height - }); - - this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { - self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); - }); + }); + } + return text; }, _getItemsByTimes: function (items, times) { @@ -17791,6 +17898,46 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { hasNext: self._hasNextByTimes(items, options.times) }); } + } +});/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserCombo + * @extends BI.Widget + */ +BI.ValueChooserCombo = BI.inherit(BI.AbstractValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-combo", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserCombo.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.combo = BI.createWidget({ + type: 'bi.multi_select_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.MultiSelectCombo.EVENT_CONFIRM, function () { + self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); + }); }, setValue: function (v) { @@ -17810,4 +17957,61 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { } }); BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; -BI.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo); \ No newline at end of file +BI.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo);/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserPane + * @extends BI.Widget + */ +BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-pane", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.list = BI.createWidget({ + type: 'bi.multi_select_list', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this) + }); + + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.ValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this.items = o.items; + this.populate(); + } + }, + + setValue: function (v) { + this.list.setValue(v); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + return { + type: val.type, + value: val.value + } + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.ValueChooserPane.EVENT_CHANGE = "ValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.value_chooser_pane', BI.ValueChooserPane); \ No newline at end of file diff --git a/src/component/allvaluechooser/abstract.allvaluechooser.js b/src/component/allvaluechooser/abstract.allvaluechooser.js new file mode 100644 index 0000000000..fadfd6d3f8 --- /dev/null +++ b/src/component/allvaluechooser/abstract.allvaluechooser.js @@ -0,0 +1,79 @@ +/** + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.AllValueChooserCombo + * @extends BI.Widget + */ +BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { + + _const: { + perPage: 100 + }, + + _defaultConfig: function () { + return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; + } + }); + } + return text; + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, function (items) { + self.items = items; + call(items); + }); + } else { + call(this.items); + } + function call(items) { + var keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + BI.each(keywords, function (i, kw) { + var search = BI.Func.getSearchResult(items, kw); + items = search.matched.concat(search.finded); + }); + if (options.selectedValues) {//过滤 + var filter = BI.makeObject(options.selectedValues, true); + items = BI.filter(items, function (i, ob) { + return !filter[ob.value]; + }); + } + if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: items + }); + return; + } + if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({count: items.length}); + return; + } + callback({ + items: items, + hasNext: false + }); + } + } +}); \ No newline at end of file diff --git a/src/component/allvaluechooser/combo.allvaluechooser.js b/src/component/allvaluechooser/combo.allvaluechooser.js index 25d797533b..908da7ec95 100644 --- a/src/component/allvaluechooser/combo.allvaluechooser.js +++ b/src/component/allvaluechooser/combo.allvaluechooser.js @@ -4,13 +4,10 @@ * * Created by GUY on 2015/10/29. * @class BI.AllValueChooserCombo - * @extends BI.Widget + * @extends BI.AbstractAllValueChooser */ -BI.AllValueChooserCombo = BI.inherit(BI.Widget, { +BI.AllValueChooserCombo = BI.inherit(BI.AbstractAllValueChooser, { - _const: { - perPage: 10 - }, _defaultConfig: function () { return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-all-value-chooser-combo", @@ -32,18 +29,7 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { type: 'bi.multi_select_combo', element: this, itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); - } - return text; - }, + valueFormatter: BI.bind(this._valueFormatter, this), width: o.width, height: o.height }); @@ -53,48 +39,6 @@ BI.AllValueChooserCombo = BI.inherit(BI.Widget, { }); }, - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!o.cache || !this.items) { - o.itemsCreator({}, function (items) { - self.items = items; - call(items); - }); - } else { - call(this.items); - } - function call(items) { - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.matched.concat(search.finded); - }); - if (options.selectedValues) {//过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - callback({ - items: items, - hasNext: false - }); - } - }, - setValue: function (v) { this.combo.setValue({ type: BI.Selection.Multi, diff --git a/src/component/allvaluechooser/pane.allvaluechooser.js b/src/component/allvaluechooser/pane.allvaluechooser.js new file mode 100644 index 0000000000..4d9a1f4086 --- /dev/null +++ b/src/component/allvaluechooser/pane.allvaluechooser.js @@ -0,0 +1,62 @@ +/** + * 简单的复选下拉框控件, 适用于数据量少的情况, 与valuechooser的区别是allvaluechooser setValue和getValue返回的是所有值 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.AllValueChooserPane + * @extends BI.AbstractAllValueChooser + */ +BI.AllValueChooserPane = BI.inherit(BI.AbstractAllValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.AllValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-all-value-chooser-pane", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.AllValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + if (BI.isNotNull(o.items)) { + this.items = o.items; + } + this.list = BI.createWidget({ + type: 'bi.multi_select_list', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this), + width: o.width, + height: o.height + }); + + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.AllValueChooserPane.EVENT_CHANGE); + }); + }, + + setValue: function (v) { + this.list.setValue({ + type: BI.Selection.Multi, + value: v || [] + }); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + if (val.type === BI.Selection.All) { + return val.assist; + } + return val.value || []; + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.AllValueChooserPane.EVENT_CHANGE = "AllValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane); \ No newline at end of file diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.js b/src/component/treevaluechooser/abstract.treevaluechooser.js new file mode 100644 index 0000000000..ea539c1508 --- /dev/null +++ b/src/component/treevaluechooser/abstract.treevaluechooser.js @@ -0,0 +1,555 @@ +BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { + + _const: { + perPage: 100 + }, + + _defaultConfig: function () { + return BI.extend(BI.AbstractTreeValueChooser.superclass._defaultConfig.apply(this, arguments), { + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _initData: function (items) { + this.items = items; + var nodes = BI.Tree.transformToTreeFormat(items); + this.tree = new BI.Tree(); + this.tree.initTree(nodes); + this._initMap(); + this._initFloors(); + }, + + _initMap: function () { + var map = this.map = {}; + BI.each(this.items, function (i, item) { + map[item.value] = item; + }); + }, + + _initFloors: function () { + this.floors = -1; + var root = this.tree.getRoot(); + while (root) { + this.floors++; + root = root.getChildren()[0]; + } + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!this.items) { + o.itemsCreator({}, function (items) { + self._initData(items); + call(); + }); + } else { + call(); + } + function call() { + switch (options.type) { + case BI.TreeView.REQ_TYPE_INIT_DATA: + self._reqInitTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_ADJUST_DATA: + self._reqAdjustTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_SELECT_DATA: + self._reqSelectedTreeNode(options, callback); + break; + case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: + self._reqDisplayTreeNode(options, callback); + break; + default : + self._reqTreeNode(options, callback); + break; + } + } + }, + + _reqDisplayTreeNode: function (op, callback) { + var self = this; + var result = []; + var selectedValues = op.selectedValues; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + doCheck(0, [], this.tree.getRoot(), selectedValues); + + callback({ + items: result + }); + + function doCheck(floor, parentValues, node, selected) { + if (floor >= self.floors) { + return; + } + if (selected == null || BI.isEmpty(selected)) { + BI.each(node.getChildren(), function (i, child) { + var newParents = BI.clone(parentValues); + newParents.push(child.value); + var llen = self._getChildCount(newParents); + createOneJson(child, node.id, llen); + doCheck(floor + 1, newParents, child, {}); + }); + return; + } + BI.each(selected, function (k) { + var node = self._getNode(k); + var newParents = BI.clone(parentValues); + newParents.push(node.value); + createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); + doCheck(floor + 1, newParents, node, selected[k]); + }) + } + + function getCount(jo, parentValues) { + if (jo == null) { + return 0; + } + if (BI.isEmpty(jo)) { + return self._getChildCount(parentValues); + } + + return BI.size(jo); + } + + function createOneJson(node, pId, llen) { + result.push({ + id: node.id, + pId: pId, + text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), + value: node.value, + open: true + }); + } + }, + + _reqSelectedTreeNode: function (op, callback) { + var self = this; + var selectedValues = op.selectedValues; + var notSelectedValue = op.notSelectedValue || {}; + var keyword = op.keyword || ""; + var parentValues = op.parentValues || []; + + if (selectedValues == null || BI.isEmpty(selectedValues)) { + callback({}); + return; + } + + dealWithSelectedValues(selectedValues); + callback(selectedValues); + + + function dealWithSelectedValues(selectedValues) { + var p = BI.clone(parentValues); + p.push(notSelectedValue); + + if (isChild(selectedValues, p)) { + var result = []; + var finded = search(parentValues.length + 1, parentValues, notSelectedValue, result); + + if (finded === true) { + var next = selectedValues; + BI.each(p, function (i, v) { + var t = next[v]; + if (t == null) { + if (BI.isEmpty(next)) { + var split = p.slice(0, i); + var expanded = self._getChildren(split); + BI.each(expanded, function (m, child) { + if (i === p.length - 1 && child.value === notSelectedValue) { + return true; + } + next[child.value] = {}; + }); + next = next[v]; + } else { + next = {}; + next[v] = {}; + } + } else { + next = t; + } + }); + + if (result.length > 0) { + BI.each(result, function (i, strs) { + self._buildTree(selectedValues, strs); + }) + } + } + } + + } + + function search(deep, parents, current, result) { + var newParents = BI.clone(parents); + newParents.push(current); + if (self._isMatch(current, keyword)) { + return true; + } + if (deep >= self.floors) { + return false; + } + + var children = self._getChildren(newParents); + + var notSearch = []; + var can = false; + + BI.each(children, function (i, child) { + if (search(deep + 1, newParents, child.value, result)) { + can = true; + } else { + notSearch.push(child.value); + } + }); + if (can === true) { + BI.each(notSearch, function (i, v) { + var next = BI.clone(newParents); + next.push(v); + result.push(next); + }); + } + return can; + } + + function isChild(selectedValues, parents) { + var t = selectedValues; + for (var i = 0; i < parents.length; i++) { + var v = parents[i]; + if (!BI.has(t, v)) { + return false; + } + t = t[v]; + if (t == null || BI.isEmpty(t)) { + return true; + } + } + return true; + } + }, + + _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 || ""; + 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; + } + } + return output; + } + + function nodeSearch(deep, parentValues, current, isAllSelect, result) { + if (self._isMatch(current, keyword)) { + var checked = isAllSelect || isSelected(parentValues, current); + createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); + return [true, checked]; + } + if (deep >= self.floors) { + return [false, false]; + } + 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.map[value]; + result.push({ + id: node.id, + pId: node.pId, + text: node.text, + value: node.value, + title: node.title, + isParent: parentValues.length + 1 < self.floors, + 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: parentValues.length + 1 < this.floors, + checked: state[0], + halfCheck: state[1] + }) + } + 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 hasChild = parentValues.length + 1 < self.floors; + var tempCheck = false, halfCheck = false; + if (BI.has(valueMap, current)) { + //可能是半选 + if (valueMap[current][0] === 1) { + var values = BI.clone(parentValues); + values.push(current); + if (hasChild && self._getChildCount(values) !== 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]; + } + }, + + + _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 (value, keyword) { + var finded = BI.Func.getSearchResult([value], keyword); + return finded.finded.length > 0 || finded.matched.length > 0; + }, + + _getNode: function (v) { + return this.tree.search(v, "value"); + }, + + _getChildren: function (parentValues) { + if (parentValues.length > 0) { + var value = BI.last(parentValues); + var parent = this.tree.search(value, "value"); + } else { + var parent = this.tree.getRoot(); + } + return parent.getChildren(); + }, + + _getChildCount: function (parentValues) { + return this._getChildren(parentValues).length; + } +}); \ No newline at end of file diff --git a/src/component/treevaluechooser/combo.treevaluechooser.js b/src/component/treevaluechooser/combo.treevaluechooser.js index 1a35109144..5a7fa64ac0 100644 --- a/src/component/treevaluechooser/combo.treevaluechooser.js +++ b/src/component/treevaluechooser/combo.treevaluechooser.js @@ -5,11 +5,7 @@ * @class BI.TreeValueChooserCombo * @extends BI.Widget */ -BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { - - _const: { - perPage: 10 - }, +BI.TreeValueChooserCombo = BI.inherit(BI.AbstractTreeValueChooser, { _defaultConfig: function () { return BI.extend(BI.TreeValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { @@ -40,548 +36,6 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { }); }, - _initData: function (items) { - this.items = items; - var nodes = BI.Tree.transformToTreeFormat(items); - this.tree = new BI.Tree(); - this.tree.initTree(nodes); - this._initMap(); - this._initFloors(); - }, - - _initMap: function () { - var map = this.map = {}; - BI.each(this.items, function (i, item) { - map[item.value] = item; - }); - }, - - _initFloors: function () { - this.floors = -1; - var root = this.tree.getRoot(); - while (root) { - this.floors++; - root = root.getChildren()[0]; - } - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!this.items) { - o.itemsCreator({}, function (items) { - self._initData(items); - call(); - }); - } else { - call(); - } - function call() { - switch (options.type) { - case BI.TreeView.REQ_TYPE_INIT_DATA: - self._reqInitTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_ADJUST_DATA: - self._reqAdjustTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_SELECT_DATA: - self._reqSelectedTreeNode(options, callback); - break; - case BI.TreeView.REQ_TYPE_GET_SELECTED_DATA: - self._reqDisplayTreeNode(options, callback); - break; - default : - self._reqTreeNode(options, callback); - break; - } - } - }, - - _reqDisplayTreeNode: function (op, callback) { - var self = this; - var result = []; - var selectedValues = op.selectedValues; - - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - - doCheck(0, [], this.tree.getRoot(), selectedValues); - - callback({ - items: result - }); - - function doCheck(floor, parentValues, node, selected) { - if (floor >= self.floors) { - return; - } - if (selected == null || BI.isEmpty(selected)) { - BI.each(node.getChildren(), function (i, child) { - var newParents = BI.clone(parentValues); - newParents.push(child.value); - var llen = self._getChildCount(newParents); - createOneJson(child, node.id, llen); - doCheck(floor + 1, newParents, child, {}); - }); - return; - } - BI.each(selected, function (k) { - var node = self._getNode(k); - var newParents = BI.clone(parentValues); - newParents.push(node.value); - createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); - doCheck(floor + 1, newParents, node, selected[k]); - }) - } - - function getCount(jo, parentValues) { - if (jo == null) { - return 0; - } - if (BI.isEmpty(jo)) { - return self._getChildCount(parentValues); - } - - return BI.size(jo); - } - - function createOneJson(node, pId, llen) { - result.push({ - id: node.id, - pId: pId, - text: node.text + (llen > 0 ? ("(" + BI.i18nText("BI-Basic_Altogether") + llen + BI.i18nText("BI-Basic_Count") + ")") : ""), - value: node.value, - open: true - }); - } - }, - - _reqSelectedTreeNode: function (op, callback) { - var self = this; - var selectedValues = op.selectedValues; - var notSelectedValue = op.notSelectedValue || {}; - var keyword = op.keyword || ""; - var parentValues = op.parentValues || []; - - if (selectedValues == null || BI.isEmpty(selectedValues)) { - callback({}); - return; - } - - dealWithSelectedValues(selectedValues); - callback(selectedValues); - - - function dealWithSelectedValues(selectedValues) { - var p = BI.clone(parentValues); - p.push(notSelectedValue); - - if (isChild(selectedValues, p)) { - var result = []; - var finded = search(parentValues.length + 1, parentValues, notSelectedValue, result); - - if (finded === true) { - var next = selectedValues; - BI.each(p, function (i, v) { - var t = next[v]; - if (t == null) { - if (BI.isEmpty(next)) { - var split = p.slice(0, i); - var expanded = self._getChildren(split); - BI.each(expanded, function (m, child) { - if (i === p.length - 1 && child.value === notSelectedValue) { - return true; - } - next[child.value] = {}; - }); - next = next[v]; - } else { - next = {}; - next[v] = {}; - } - } else { - next = t; - } - }); - - if (result.length > 0) { - BI.each(result, function (i, strs) { - self._buildTree(selectedValues, strs); - }) - } - } - } - - } - - function search(deep, parents, current, result) { - var newParents = BI.clone(parents); - newParents.push(current); - if (self._isMatch(current, keyword)) { - return true; - } - if (deep >= self.floors) { - return false; - } - - var children = self._getChildren(newParents); - - var notSearch = []; - var can = false; - - BI.each(children, function (i, child) { - if (search(deep + 1, newParents, child.value, result)) { - can = true; - } else { - notSearch.push(child.value); - } - }); - if (can === true) { - BI.each(notSearch, function (i, v) { - var next = BI.clone(newParents); - next.push(v); - result.push(next); - }); - } - return can; - } - - function isChild(selectedValues, parents) { - var t = selectedValues; - for (var i = 0; i < parents.length; i++) { - var v = parents[i]; - if (!BI.has(t, v)) { - return false; - } - t = t[v]; - if (t == null || BI.isEmpty(t)) { - return true; - } - } - return true; - } - }, - - _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 || ""; - 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; - } - } - return output; - } - - function nodeSearch(deep, parentValues, current, isAllSelect, result) { - if (self._isMatch(current, keyword)) { - var checked = isAllSelect || isSelected(parentValues, current); - createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); - return [true, checked]; - } - if (deep >= self.floors) { - return [false, false]; - } - 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.map[value]; - result.push({ - id: node.id, - pId: node.pId, - text: node.text, - value: node.value, - title: node.title, - isParent: parentValues.length + 1 < self.floors, - 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: parentValues.length + 1 < this.floors, - checked: state[0], - halfCheck: state[1] - }) - } - 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 hasChild = parentValues.length + 1 < self.floors; - var tempCheck = false, halfCheck = false; - if (BI.has(valueMap, current)) { - //可能是半选 - if (valueMap[current][0] === 1) { - var values = BI.clone(parentValues); - values.push(current); - if (hasChild && self._getChildCount(values) !== 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]; - } - }, - - - _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 (value, keyword) { - var finded = BI.Func.getSearchResult([value], keyword); - return finded.finded.length > 0 || finded.matched.length > 0; - }, - - _getNode: function (v) { - return this.tree.search(v, "value"); - }, - - _getChildren: function (parentValues) { - if (parentValues.length > 0) { - var value = BI.last(parentValues); - var parent = this.tree.search(value, "value"); - } else { - var parent = this.tree.getRoot(); - } - return parent.getChildren(); - }, - - _getChildCount: function (parentValues) { - return this._getChildren(parentValues).length; - }, - setValue: function (v) { this.combo.setValue(v); }, @@ -591,7 +45,7 @@ BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { }, populate: function () { - this.combo.populate.apply(this, arguments); + this.combo.populate.apply(this.combo, arguments); } }); BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; diff --git a/src/component/treevaluechooser/pane.treevaluechooser.js b/src/component/treevaluechooser/pane.treevaluechooser.js new file mode 100644 index 0000000000..dd924c925d --- /dev/null +++ b/src/component/treevaluechooser/pane.treevaluechooser.js @@ -0,0 +1,49 @@ +/** + * 简单的复选下拉树控件, 适用于数据量少的情况 + * + * Created by GUY on 2015/10/29. + * @class BI.TreeValueChooserPane + * @extends BI.AbstractTreeValueChooser + */ +BI.TreeValueChooserPane = BI.inherit(BI.AbstractTreeValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.TreeValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-tree-value-chooser-pane", + items: null, + itemsCreator: BI.emptyFn + }); + }, + + _init: function () { + BI.TreeValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.pane = BI.createWidget({ + type: 'bi.multi_select_tree', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this) + }); + + this.pane.on(BI.MultiSelectTree.EVENT_CHANGE, function () { + self.fireEvent(BI.TreeValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this._initData(o.items); + this.populate(); + } + }, + + setValue: function (v) { + this.pane.setValue(v); + }, + + getValue: function () { + return this.pane.getValue(); + }, + + populate: function () { + this.pane.populate.apply(this.pane, arguments); + } +}); +BI.TreeValueChooserPane.EVENT_CHANGE = "TreeValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.tree_value_chooser_pane', BI.TreeValueChooserPane); \ No newline at end of file diff --git a/src/component/valuechooser/abstract.valuechooser.js b/src/component/valuechooser/abstract.valuechooser.js new file mode 100644 index 0000000000..9b96e1ab51 --- /dev/null +++ b/src/component/valuechooser/abstract.valuechooser.js @@ -0,0 +1,89 @@ +/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.AbstractValueChooser + * @extends BI.Widget + */ +BI.AbstractValueChooser = BI.inherit(BI.Widget, { + + _const: { + perPage: 100 + }, + + _defaultConfig: function () { + return BI.extend(BI.AbstractValueChooser.superclass._defaultConfig.apply(this, arguments), { + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _valueFormatter: function (v) { + var text = v; + if (BI.isNotNull(this.items)) { + BI.some(this.items, function (i, item) { + if (item.value === v) { + text = item.text; + return true; + } + }); + } + return text; + }, + + _getItemsByTimes: function (items, times) { + var res = []; + for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { + res.push(items[i]); + } + return res; + }, + + _hasNextByTimes: function (items, times) { + return times * this._const.perPage < items.length; + }, + + _itemsCreator: function (options, callback) { + var self = this, o = this.options; + if (!o.cache || !this.items) { + o.itemsCreator({}, function (items) { + self.items = items; + call(items); + }); + } else { + call(this.items); + } + function call(items) { + var keywords = (options.keywords || []).slice(); + if (options.keyword) { + keywords.push(options.keyword); + } + BI.each(keywords, function (i, kw) { + var search = BI.Func.getSearchResult(items, kw); + items = search.matched.concat(search.finded); + }); + if (options.selectedValues) {//过滤 + var filter = BI.makeObject(options.selectedValues, true); + items = BI.filter(items, function (i, ob) { + return !filter[ob.value]; + }); + } + if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { + callback({ + items: items + }); + return; + } + if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { + callback({count: items.length}); + return; + } + callback({ + items: self._getItemsByTimes(items, options.times), + hasNext: self._hasNextByTimes(items, options.times) + }); + } + } +}); \ No newline at end of file diff --git a/src/component/valuechooser/combo.valuechooser.js b/src/component/valuechooser/combo.valuechooser.js index 778865ffbc..2f88d21281 100644 --- a/src/component/valuechooser/combo.valuechooser.js +++ b/src/component/valuechooser/combo.valuechooser.js @@ -6,11 +6,8 @@ * @class BI.ValueChooserCombo * @extends BI.Widget */ -BI.ValueChooserCombo = BI.inherit(BI.Widget, { +BI.ValueChooserCombo = BI.inherit(BI.AbstractValueChooser, { - _const: { - perPage: 10 - }, _defaultConfig: function () { return BI.extend(BI.ValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-combo", @@ -32,18 +29,7 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { type: 'bi.multi_select_combo', element: this, itemsCreator: BI.bind(this._itemsCreator, this), - valueFormatter: function (v) { - var text = v; - if (BI.isNotNull(self.items)) { - BI.some(self.items, function (i, item) { - if (item.value === v) { - text = item.text; - return true; - } - }); - } - return text; - }, + valueFormatter: BI.bind(this._valueFormatter, this), width: o.width, height: o.height }); @@ -53,60 +39,6 @@ BI.ValueChooserCombo = BI.inherit(BI.Widget, { }); }, - _getItemsByTimes: function (items, times) { - var res = []; - for (var i = (times - 1) * this._const.perPage; items[i] && i < times * this._const.perPage; i++) { - res.push(items[i]); - } - return res; - }, - - _hasNextByTimes: function (items, times) { - return times * this._const.perPage < items.length; - }, - - _itemsCreator: function (options, callback) { - var self = this, o = this.options; - if (!o.cache || !this.items) { - o.itemsCreator({}, function (items) { - self.items = items; - call(items); - }); - } else { - call(this.items); - } - function call(items) { - var keywords = (options.keywords || []).slice(); - if (options.keyword) { - keywords.push(options.keyword); - } - BI.each(keywords, function (i, kw) { - var search = BI.Func.getSearchResult(items, kw); - items = search.matched.concat(search.finded); - }); - if (options.selectedValues) {//过滤 - var filter = BI.makeObject(options.selectedValues, true); - items = BI.filter(items, function (i, ob) { - return !filter[ob.value]; - }); - } - if (options.type === BI.MultiSelectCombo.REQ_GET_ALL_DATA) { - callback({ - items: items - }); - return; - } - if (options.type === BI.MultiSelectCombo.REQ_GET_DATA_LENGTH) { - callback({count: items.length}); - return; - } - callback({ - items: self._getItemsByTimes(items, options.times), - hasNext: self._hasNextByTimes(items, options.times) - }); - } - }, - setValue: function (v) { this.combo.setValue(v); }, diff --git a/src/component/valuechooser/pane.valuechooser.js b/src/component/valuechooser/pane.valuechooser.js new file mode 100644 index 0000000000..67ef9cab98 --- /dev/null +++ b/src/component/valuechooser/pane.valuechooser.js @@ -0,0 +1,58 @@ +/** + * 简单的复选下拉框控件, 适用于数据量少的情况 + * 封装了字段处理逻辑 + * + * Created by GUY on 2015/10/29. + * @class BI.ValueChooserPane + * @extends BI.Widget + */ +BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { + + _defaultConfig: function () { + return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-value-chooser-pane", + width: 200, + height: 30, + items: null, + itemsCreator: BI.emptyFn, + cache: true + }); + }, + + _init: function () { + BI.ValueChooserPane.superclass._init.apply(this, arguments); + var self = this, o = this.options; + this.list = BI.createWidget({ + type: 'bi.multi_select_list', + element: this, + itemsCreator: BI.bind(this._itemsCreator, this), + valueFormatter: BI.bind(this._valueFormatter, this) + }); + + this.list.on(BI.MultiSelectList.EVENT_CHANGE, function () { + self.fireEvent(BI.ValueChooserPane.EVENT_CHANGE); + }); + if (BI.isNotNull(o.items)) { + this.items = o.items; + this.populate(); + } + }, + + setValue: function (v) { + this.list.setValue(v); + }, + + getValue: function () { + var val = this.list.getValue() || {}; + return { + type: val.type, + value: val.value + } + }, + + populate: function () { + this.list.populate.apply(this.list, arguments); + } +}); +BI.ValueChooserPane.EVENT_CHANGE = "ValueChooserPane.EVENT_CHANGE"; +BI.shortcut('bi.value_chooser_pane', BI.ValueChooserPane); \ No newline at end of file diff --git a/src/widget/multiselectlist/multiselectlist.js b/src/widget/multiselectlist/multiselectlist.js index 4913c7e410..aaf5239436 100644 --- a/src/widget/multiselectlist/multiselectlist.js +++ b/src/widget/multiselectlist/multiselectlist.js @@ -6,8 +6,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { return BI.extend(BI.MultiSelectList.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-list', itemsCreator: BI.emptyFn, - valueFormatter: BI.emptyFn, - el: {} + valueFormatter: BI.emptyFn }) }, _init: function () { @@ -140,8 +139,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -153,8 +150,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, diff --git a/src/widget/multiselecttree/multiselecttree.js b/src/widget/multiselecttree/multiselecttree.js index 4475e433e2..0fc868b97f 100644 --- a/src/widget/multiselecttree/multiselecttree.js +++ b/src/widget/multiselecttree/multiselecttree.js @@ -5,8 +5,7 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.MultiSelectTree.superclass._defaultConfig.apply(this, arguments), { baseCls: 'bi-multi-select-tree', - itemsCreator: BI.emptyFn, - height: 25 + itemsCreator: BI.emptyFn }) }, @@ -52,7 +51,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }, adapter: this.adapter, popup: this.searcherPane, - height: 200, masker: false, listeners: [{ eventName: BI.Searcher.EVENT_START, @@ -92,8 +90,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.vtape", element: this, - height: "100%", - width: "100%", items: [{ el: this.trigger, height: 30 @@ -105,8 +101,6 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { BI.createWidget({ type: "bi.absolute", element: this, - height: "100%", - width: "100%", items: [{ el: this.searcherPane, top: 30, diff --git a/src/widget/multiselecttree/multiselecttree.popup.js b/src/widget/multiselecttree/multiselecttree.popup.js index 8f8ee61b2e..f461f87877 100644 --- a/src/widget/multiselecttree/multiselecttree.popup.js +++ b/src/widget/multiselecttree/multiselecttree.popup.js @@ -13,7 +13,6 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { var self = this, o = this.options; this.popup = BI.createWidget({ type: "bi.async_tree", - height: 400, element: this, itemsCreator: o.itemsCreator }); From 1795bcbfac872de8937a67e9bb47e66a22b9a603 Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 21:30:59 +0800 Subject: [PATCH 04/27] bug --- bi/base.js | 18 ++--- bi/core.js | 67 ++++++++++++++----- bi/widget.js | 42 +++++++----- demo/config.js | 5 +- .../component/demo.treevaluechoosercombo.js | 21 +----- .../js/component/demo.treevaluechooserpane.js | 26 ++----- demo/js/component/demo.valuechooserpane.js | 6 +- docs/base.js | 18 ++--- docs/core.js | 67 ++++++++++++++----- docs/demo.js | 58 ++++------------ docs/widget.js | 42 +++++++----- src/base/tree/asynctree.js | 2 +- src/base/tree/parttree.js | 2 +- src/base/tree/treeview.js | 14 ++-- .../abstract.treevaluechooser.js | 40 +++++++---- .../valuechooser/pane.valuechooser.js | 2 - src/core/base.js | 16 ++--- src/core/utils/tree.js | 51 +++++++++++--- 18 files changed, 276 insertions(+), 221 deletions(-) diff --git a/bi/base.js b/bi/base.js index 728e5fd04f..47d72dbfbe 100644 --- a/bi/base.js +++ b/bi/base.js @@ -1710,7 +1710,7 @@ BI.TreeView = BI.inherit(BI.Pane, { _getNodeValue: function (node) { //去除标红 - return node.value || node.text.replace(/<[^>]+>/g, ""); + return node.value == null ? node.text.replace(/<[^>]+>/g, "") : node.value; }, //获取半选框值 @@ -1802,6 +1802,7 @@ BI.TreeView = BI.inherit(BI.Pane, { var self = this, o = this.options; var ns = BI.Tree.arrayFormat(nodes); BI.each(ns, function (i, n) { + n.title = n.title || n.text || n.value; //处理标红 if (BI.isKey(o.paras.keyword)) { n.text = $("
").__textKeywordMarked__(n.text, o.paras.keyword, n.py).html(); @@ -1944,7 +1945,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }, setSelectedValue: function (value) { - this.options.paras.selectedValues = value || {}; + this.options.paras.selectedValues = BI.deepClone(value) || {}; this.selectedValues = BI.deepClone(value) || {}; }, @@ -1963,7 +1964,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function(){ + getExpandedValue: function () { if (!this.nodes) { return null; } @@ -1980,14 +1981,9 @@ BI.TreeView = BI.inherit(BI.Pane, { return this._getSelectedValues(); }, - empty: function () { - BI.isNotNull(this.nodes) && this.nodes.destroy(); - }, - - destroy: function () { + destroyed: function () { this.stop(); this.nodes && this.nodes.destroy(); - BI.TreeView.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.TreeView, { @@ -2190,7 +2186,7 @@ BI.AsyncTree = BI.inherit(BI.TreeView, { } var checkedValues = this._getSelectedValues(); if (BI.isEmpty(checkedValues)) { - return this.selectedValues; + return BI.deepClone(this.selectedValues); } if (BI.isEmpty(this.selectedValues)) { return checkedValues; @@ -2257,7 +2253,7 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); } else { o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA, + type: BI.TreeView.REQ_TYPE_SELECT_DATA, selectedValues: this.selectedValues, notSelectedValue: name, parentValues: parentValues diff --git a/bi/core.js b/bi/core.js index 56eb536657..de5f6d5d1f 100644 --- a/bi/core.js +++ b/bi/core.js @@ -2352,15 +2352,15 @@ if (!window.BI) { }, has: function (obj, keys) { - if (BI.isKey(keys)) { - return _.has.apply(_, arguments); - } - if (!keys || BI.isEmpty(keys)) { - return false; + if (BI.isArray(keys)) { + if (keys.length === 0) { + return false; + } + return BI.every(keys, function (i, key) { + return _.has(obj, key); + }); } - return BI.every(keys, function (i, key) { - return _.has(obj, key); - }); + return _.has.apply(_, arguments); }, //数字和字符串可以作为key @@ -9990,7 +9990,7 @@ $.extend(BI, { }, isRoot: function (node) { - return node === this.root || node.id === this.root.id; + return node === this.root; }, getRoot: function () { @@ -10367,7 +10367,7 @@ $.extend(BI, { if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = BI.clone(nodes[i]); - node.pId = pId; + node.pId = node.pId == null ? pId : node.pId; delete node.children; r.push(node); if (nodes[i]["children"]) { @@ -10376,7 +10376,7 @@ $.extend(BI, { } } else { var newNodes = BI.clone(nodes); - newNodes.pId = pId; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; delete newNodes.children; r.push(newNodes); if (nodes["children"]) { @@ -10387,21 +10387,25 @@ $.extend(BI, { }, arrayFormat: function (nodes, pId) { - if (!nodes) return []; + if (!nodes) { + return []; + } var r = []; if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; + node.pId = node.pId == null ? pId : node.pId; r.push(node); if (nodes[i]["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes[i]["children"], node.id)); + r = r.concat(BI.Tree.arrayFormat(nodes[i]["children"], node.id)); } } } else { var newNodes = nodes; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; r.push(newNodes); if (nodes["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes["children"], newNodes.id)); + r = r.concat(BI.Tree.arrayFormat(nodes["children"], newNodes.id)); } } return r; @@ -10417,13 +10421,13 @@ $.extend(BI, { var r = []; var tmpMap = []; for (i = 0, l = sNodes.length; i < l; i++) { - if(BI.isNull(sNodes[i].id)) { + if (BI.isNull(sNodes[i].id)) { return sNodes; } tmpMap[sNodes[i].id] = BI.clone(sNodes[i]); } for (i = 0, l = sNodes.length; i < l; i++) { - if (tmpMap[sNodes[i].pId] && sNodes[i].id != sNodes[i].pId) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { if (!tmpMap[sNodes[i].pId].children) { tmpMap[sNodes[i].pId].children = []; } @@ -10439,6 +10443,37 @@ $.extend(BI, { } }, + treeFormat: function (sNodes) { + var i, l; + if (!sNodes) { + return []; + } + + if (BI.isArray(sNodes)) { + var r = []; + var tmpMap = []; + for (i = 0, l = sNodes.length; i < l; i++) { + if (BI.isNull(sNodes[i].id)) { + return sNodes; + } + tmpMap[sNodes[i].id] = sNodes[i]; + } + for (i = 0, l = sNodes.length; i < l; i++) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { + if (!tmpMap[sNodes[i].pId].children) { + tmpMap[sNodes[i].pId].children = []; + } + tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); + } else { + r.push(tmpMap[sNodes[i].id]); + } + } + return r; + } else { + return [sNodes]; + } + }, + traversal: function (array, callback) { if (BI.isNull(array)) { return; diff --git a/bi/widget.js b/bi/widget.js index 7e9bde29b8..a90a7500f1 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -17173,20 +17173,12 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree _initData: function (items) { this.items = items; - var nodes = BI.Tree.transformToTreeFormat(items); + var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initMap(); this._initFloors(); }, - _initMap: function () { - var map = this.map = {}; - BI.each(this.items, function (i, item) { - map[item.value] = item; - }); - }, - _initFloors: function () { this.floors = -1; var root = this.tree.getRoot(); @@ -17258,7 +17250,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return; } BI.each(selected, function (k) { - var node = self._getNode(k); + var node = self._getNode(parentValues, k); var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); @@ -17517,7 +17509,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree } function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { - var node = self.map[value]; + var node = self._getNode(parentValues, value) result.push({ id: node.id, pId: node.pId, @@ -17695,14 +17687,34 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return finded.finded.length > 0 || finded.matched.length > 0; }, - _getNode: function (v) { - return this.tree.search(v, "value"); + _getNode: function (parentValues, v) { + var self = this; + var findedParentNode; + 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) { + findedParentNode = node; + return false; + } + if (node.value === parentValues[index]) { + index++; + return; + } + return true; + }); + return findedParentNode; }, _getChildren: function (parentValues) { if (parentValues.length > 0) { var value = BI.last(parentValues); - var parent = this.tree.search(value, "value"); + var parent = this._getNode(parentValues.slice(0, parentValues.length - 1), value); } else { var parent = this.tree.getRoot(); } @@ -17970,8 +17982,6 @@ BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { _defaultConfig: function () { return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-pane", - width: 200, - height: 30, items: null, itemsCreator: BI.emptyFn, cache: true diff --git a/demo/config.js b/demo/config.js index 41ec565c75..e1c8645cad 100644 --- a/demo/config.js +++ b/demo/config.js @@ -1,6 +1,5 @@ Demo.CONFIG = Demo.CORE_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG).concat(Demo.COMPONENT_CONFIG).concat(Demo.CHART_CONFIG); - Demo.CONSTANTS = { ITEMS: BI.map("柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 ".match(/[^\s]+/g), function (i, v) { return { @@ -8,5 +7,7 @@ Demo.CONSTANTS = { value: v, title: v } - }) + }), + TREEITEMS: [{"pId":"0","id":"0_0","text":"( 共25个 )","value":"","open":true},{"pId":"0_0","id":"0_0_0","text":"安徽省( 共1个 )","value":"安徽省","open":true},{"pId":"0_0_0","id":"0_0_0_0","text":"芜湖市","value":"芜湖市","open":true},{"pId":"0_0","id":"0_0_1","text":"北京市( 共6个 )","value":"北京市","open":true},{"pId":"0_0_1","id":"0_0_1_0","text":"北京市区","value":"北京市区","open":true},{"pId":"0_0_1","id":"0_0_1_1","text":"朝阳区","value":"朝阳区","open":true},{"pId":"0_0_1","id":"0_0_1_2","text":"东城区","value":"东城区","open":true},{"pId":"0_0_1","id":"0_0_1_3","text":"海淀区4内","value":"海淀区4内","open":true},{"pId":"0_0_1","id":"0_0_1_4","text":"海淀区4外","value":"海淀区4外","open":true},{"pId":"0_0_1","id":"0_0_1_5","text":"石景山区","value":"石景山区","open":true},{"pId":"0_0","id":"0_0_2","text":"福建省( 共2个 )","value":"福建省","open":true},{"pId":"0_0_2","id":"0_0_2_0","text":"莆田市","value":"莆田市","open":true},{"pId":"0_0_2","id":"0_0_2_1","text":"泉州市","value":"泉州市","open":true},{"pId":"0_0","id":"0_0_3","text":"甘肃省( 共1个 )","value":"甘肃省","open":true},{"pId":"0_0_3","id":"0_0_3_0","text":"兰州市","value":"兰州市","open":true},{"pId":"0_0","id":"0_0_4","text":"广东省( 共5个 )","value":"广东省","open":true},{"pId":"0_0_4","id":"0_0_4_0","text":"东莞市","value":"东莞市","open":true},{"pId":"0_0_4","id":"0_0_4_1","text":"广州市","value":"广州市","open":true},{"pId":"0_0_4","id":"0_0_4_2","text":"惠州市","value":"惠州市","open":true},{"pId":"0_0_4","id":"0_0_4_3","text":"深圳市","value":"深圳市","open":true},{"pId":"0_0_4","id":"0_0_4_4","text":"珠海市","value":"珠海市","open":true},{"pId":"0_0","id":"0_0_5","text":"广西壮族自治区( 共1个 )","value":"广西壮族自治区","open":true},{"pId":"0_0_5","id":"0_0_5_0","text":"南宁市","value":"南宁市","open":true},{"pId":"0_0","id":"0_0_6","text":"河北省( 共2个 )","value":"河北省","open":true},{"pId":"0_0_6","id":"0_0_6_0","text":"保定市","value":"保定市","open":true},{"pId":"0_0_6","id":"0_0_6_1","text":"邢台市","value":"邢台市","open":true},{"pId":"0_0","id":"0_0_7","text":"河南省( 共1个 )","value":"河南省","open":true},{"pId":"0_0_7","id":"0_0_7_0","text":"郑州市","value":"郑州市","open":true},{"pId":"0_0","id":"0_0_8","text":"黑龙江省( 共7个 )","value":"黑龙江省","open":true},{"pId":"0_0_8","id":"0_0_8_0","text":"大庆市","value":"大庆市","open":true},{"pId":"0_0_8","id":"0_0_8_1","text":"哈尔滨市","value":"哈尔滨市","open":true},{"pId":"0_0_8","id":"0_0_8_2","text":"鸡西市","value":"鸡西市","open":true},{"pId":"0_0_8","id":"0_0_8_3","text":"佳木斯市","value":"佳木斯市","open":true},{"pId":"0_0_8","id":"0_0_8_4","text":"牡丹江市","value":"牡丹江市","open":true},{"pId":"0_0_8","id":"0_0_8_5","text":"齐齐哈尔市","value":"齐齐哈尔市","open":true},{"pId":"0_0_8","id":"0_0_8_6","text":"双鸭山市","value":"双鸭山市","open":true},{"pId":"0_0","id":"0_0_9","text":"湖北省( 共1个 )","value":"湖北省","open":true},{"pId":"0_0_9","id":"0_0_9_0","text":"武汉市","value":"武汉市","open":true},{"pId":"0_0","id":"0_0_10","text":"湖南省( 共3个 )","value":"湖南省","open":true},{"pId":"0_0_10","id":"0_0_10_0","text":"常德市","value":"常德市","open":true},{"pId":"0_0_10","id":"0_0_10_1","text":"长沙市","value":"长沙市","open":true},{"pId":"0_0_10","id":"0_0_10_2","text":"邵阳市","value":"邵阳市","open":true},{"pId":"0_0","id":"0_0_11","text":"吉林省( 共4个 )","value":"吉林省","open":true},{"pId":"0_0_11","id":"0_0_11_0","text":"白山市","value":"白山市","open":true},{"pId":"0_0_11","id":"0_0_11_1","text":"长春市","value":"长春市","open":true},{"pId":"0_0_11","id":"0_0_11_2","text":"松原市","value":"松原市","open":true},{"pId":"0_0_11","id":"0_0_11_3","text":"通化市","value":"通化市","open":true},{"pId":"0_0","id":"0_0_12","text":"江苏省( 共8个 )","value":"江苏省","open":true},{"pId":"0_0_12","id":"0_0_12_0","text":"常州市","value":"常州市","open":true},{"pId":"0_0_12","id":"0_0_12_1","text":"南京市","value":"南京市","open":true},{"pId":"0_0_12","id":"0_0_12_2","text":"南通市","value":"南通市","open":true},{"pId":"0_0_12","id":"0_0_12_3","text":"苏州市","value":"苏州市","open":true},{"pId":"0_0_12","id":"0_0_12_4","text":"宿迁市","value":"宿迁市","open":true},{"pId":"0_0_12","id":"0_0_12_5","text":"泰州市","value":"泰州市","open":true},{"pId":"0_0_12","id":"0_0_12_6","text":"无锡市","value":"无锡市","open":true},{"pId":"0_0_12","id":"0_0_12_7","text":"盐城市","value":"盐城市","open":true},{"pId":"0_0","id":"0_0_13","text":"辽宁省( 共11个 )","value":"辽宁省","open":true},{"pId":"0_0_13","id":"0_0_13_0","text":"鞍山市","value":"鞍山市","open":true},{"pId":"0_0_13","id":"0_0_13_1","text":"本溪市","value":"本溪市","open":true},{"pId":"0_0_13","id":"0_0_13_2","text":"朝阳市","value":"朝阳市","open":true},{"pId":"0_0_13","id":"0_0_13_3","text":"大连市","value":"大连市","open":true},{"pId":"0_0_13","id":"0_0_13_4","text":"抚顺市","value":"抚顺市","open":true},{"pId":"0_0_13","id":"0_0_13_5","text":"葫芦岛市","value":"葫芦岛市","open":true},{"pId":"0_0_13","id":"0_0_13_6","text":"锦州市","value":"锦州市","open":true},{"pId":"0_0_13","id":"0_0_13_7","text":"辽阳市","value":"辽阳市","open":true},{"pId":"0_0_13","id":"0_0_13_8","text":"盘锦市","value":"盘锦市","open":true},{"pId":"0_0_13","id":"0_0_13_9","text":"沈阳市","value":"沈阳市","open":true},{"pId":"0_0_13","id":"0_0_13_10","text":"营口市","value":"营口市","open":true},{"pId":"0_0","id":"0_0_14","text":"内蒙古( 共1个 )","value":"内蒙古","open":true},{"pId":"0_0_14","id":"0_0_14_0","text":"鄂尔多斯市","value":"鄂尔多斯市","open":true},{"pId":"0_0","id":"0_0_15","text":"宁夏回族自治区( 共1个 )","value":"宁夏回族自治区","open":true},{"pId":"0_0_15","id":"0_0_15_0","text":"银川市","value":"银川市","open":true},{"pId":"0_0","id":"0_0_16","text":"山东省( 共7个 )","value":"山东省","open":true},{"pId":"0_0_16","id":"0_0_16_0","text":"济南市","value":"济南市","open":true},{"pId":"0_0_16","id":"0_0_16_1","text":"济宁市","value":"济宁市","open":true},{"pId":"0_0_16","id":"0_0_16_2","text":"聊城市","value":"聊城市","open":true},{"pId":"0_0_16","id":"0_0_16_3","text":"临沂市","value":"临沂市","open":true},{"pId":"0_0_16","id":"0_0_16_4","text":"青岛市","value":"青岛市","open":true},{"pId":"0_0_16","id":"0_0_16_5","text":"烟台市","value":"烟台市","open":true},{"pId":"0_0_16","id":"0_0_16_6","text":"枣庄市","value":"枣庄市","open":true},{"pId":"0_0","id":"0_0_17","text":"山西省( 共1个 )","value":"山西省","open":true},{"pId":"0_0_17","id":"0_0_17_0","text":"太原市","value":"太原市","open":true},{"pId":"0_0","id":"0_0_18","text":"陕西省( 共1个 )","value":"陕西省","open":true},{"pId":"0_0_18","id":"0_0_18_0","text":"西安市","value":"西安市","open":true},{"pId":"0_0","id":"0_0_19","text":"上海市( 共1个 )","value":"上海市","open":true},{"pId":"0_0_19","id":"0_0_19_0","text":"上海市区","value":"上海市区","open":true},{"pId":"0_0","id":"0_0_20","text":"四川省( 共1个 )","value":"四川省","open":true},{"pId":"0_0_20","id":"0_0_20_0","text":"成都市","value":"成都市","open":true},{"pId":"0_0","id":"0_0_21","text":"新疆维吾尔族自治区( 共2个 )","value":"新疆维吾尔族自治区","open":true},{"pId":"0_0_21","id":"0_0_21_0","text":"吐鲁番地区","value":"吐鲁番地区","open":true},{"pId":"0_0_21","id":"0_0_21_1","text":"乌鲁木齐","value":"乌鲁木齐","open":true},{"pId":"0_0","id":"0_0_22","text":"云南省( 共1个 )","value":"云南省","open":true},{"pId":"0_0_22","id":"0_0_22_0","text":"昆明市","value":"昆明市","open":true},{"pId":"0_0","id":"0_0_23","text":"浙江省( 共5个 )","value":"浙江省","open":true},{"pId":"0_0_23","id":"0_0_23_0","text":"杭州市","value":"杭州市","open":true},{"pId":"0_0_23","id":"0_0_23_1","text":"湖州市","value":"湖州市","open":true},{"pId":"0_0_23","id":"0_0_23_2","text":"嘉兴市","value":"嘉兴市","open":true},{"pId":"0_0_23","id":"0_0_23_3","text":"宁波市","value":"宁波市","open":true},{"pId":"0_0_23","id":"0_0_23_4","text":"绍兴市","value":"绍兴市","open":true},{"pId":"0_0","id":"0_0_24","text":"重庆市( 共1个 )","value":"重庆市","open":true},{"pId":"0_0_24","id":"0_0_24_0","text":"重庆市区","value":"重庆市区","open":true},{"pId":"0","id":"0_1","text":"中国( 共34个 )","value":"中国","open":true},{"pId":"0_1","id":"0_1_0","text":"安徽省( 共19个 )","value":"安徽省","open":true},{"pId":"0_1_0","id":"0_1_0_0","text":"安庆市","value":"安庆市","open":true},{"pId":"0_1_0","id":"0_1_0_1","text":"蚌埠市","value":"蚌埠市","open":true},{"pId":"0_1_0","id":"0_1_0_2","text":"亳州市","value":"亳州市","open":true},{"pId":"0_1_0","id":"0_1_0_3","text":"巢湖市","value":"巢湖市","open":true},{"pId":"0_1_0","id":"0_1_0_4","text":"池州市","value":"池州市","open":true},{"pId":"0_1_0","id":"0_1_0_5","text":"滁州市","value":"滁州市","open":true},{"pId":"0_1_0","id":"0_1_0_6","text":"阜阳市","value":"阜阳市","open":true},{"pId":"0_1_0","id":"0_1_0_7","text":"毫州市","value":"毫州市","open":true},{"pId":"0_1_0","id":"0_1_0_8","text":"合肥市","value":"合肥市","open":true},{"pId":"0_1_0","id":"0_1_0_9","text":"淮北市","value":"淮北市","open":true},{"pId":"0_1_0","id":"0_1_0_10","text":"淮南市","value":"淮南市","open":true},{"pId":"0_1_0","id":"0_1_0_11","text":"黄山市","value":"黄山市","open":true},{"pId":"0_1_0","id":"0_1_0_12","text":"六安市","value":"六安市","open":true},{"pId":"0_1_0","id":"0_1_0_13","text":"马鞍山市","value":"马鞍山市","open":true},{"pId":"0_1_0","id":"0_1_0_14","text":"濮阳市","value":"濮阳市","open":true},{"pId":"0_1_0","id":"0_1_0_15","text":"宿州市","value":"宿州市","open":true},{"pId":"0_1_0","id":"0_1_0_16","text":"铜陵市","value":"铜陵市","open":true},{"pId":"0_1_0","id":"0_1_0_17","text":"芜湖市","value":"芜湖市","open":true},{"pId":"0_1_0","id":"0_1_0_18","text":"宣城市","value":"宣城市","open":true},{"pId":"0_1","id":"0_1_1","text":"澳门特别行政区( 共1个 )","value":"澳门特别行政区","open":true},{"pId":"0_1_1","id":"0_1_1_0","text":"澳门","value":"澳门","open":true},{"pId":"0_1","id":"0_1_2","text":"北京市( 共17个 )","value":"北京市","open":true},{"pId":"0_1_2","id":"0_1_2_0","text":"北京市区","value":"北京市区","open":true},{"pId":"0_1_2","id":"0_1_2_1","text":"昌平区","value":"昌平区","open":true},{"pId":"0_1_2","id":"0_1_2_2","text":"朝阳区","value":"朝阳区","open":true},{"pId":"0_1_2","id":"0_1_2_3","text":"大兴区","value":"大兴区","open":true},{"pId":"0_1_2","id":"0_1_2_4","text":"东城区","value":"东城区","open":true},{"pId":"0_1_2","id":"0_1_2_5","text":"房山区","value":"房山区","open":true},{"pId":"0_1_2","id":"0_1_2_6","text":"丰台区","value":"丰台区","open":true},{"pId":"0_1_2","id":"0_1_2_7","text":"海淀区","value":"海淀区","open":true},{"pId":"0_1_2","id":"0_1_2_8","text":"海淀区4内","value":"海淀区4内","open":true},{"pId":"0_1_2","id":"0_1_2_9","text":"海淀区4外","value":"海淀区4外","open":true},{"pId":"0_1_2","id":"0_1_2_10","text":"门头沟区","value":"门头沟区","open":true},{"pId":"0_1_2","id":"0_1_2_11","text":"平谷区","value":"平谷区","open":true},{"pId":"0_1_2","id":"0_1_2_12","text":"石景山区","value":"石景山区","open":true},{"pId":"0_1_2","id":"0_1_2_13","text":"顺义区","value":"顺义区","open":true},{"pId":"0_1_2","id":"0_1_2_14","text":"通州区","value":"通州区","open":true},{"pId":"0_1_2","id":"0_1_2_15","text":"西城区","value":"西城区","open":true},{"pId":"0_1_2","id":"0_1_2_16","text":"西城区 ","value":"西城区 ","open":true},{"pId":"0_1","id":"0_1_3","text":"福建省( 共9个 )","value":"福建省","open":true},{"pId":"0_1_3","id":"0_1_3_0","text":"福州市","value":"福州市","open":true},{"pId":"0_1_3","id":"0_1_3_1","text":"龙岩市","value":"龙岩市","open":true},{"pId":"0_1_3","id":"0_1_3_2","text":"南平市","value":"南平市","open":true},{"pId":"0_1_3","id":"0_1_3_3","text":"宁德市","value":"宁德市","open":true},{"pId":"0_1_3","id":"0_1_3_4","text":"莆田市","value":"莆田市","open":true},{"pId":"0_1_3","id":"0_1_3_5","text":"泉州市","value":"泉州市","open":true},{"pId":"0_1_3","id":"0_1_3_6","text":"三明市","value":"三明市","open":true},{"pId":"0_1_3","id":"0_1_3_7","text":"厦门市","value":"厦门市","open":true},{"pId":"0_1_3","id":"0_1_3_8","text":"漳州市","value":"漳州市","open":true},{"pId":"0_1","id":"0_1_4","text":"甘肃省( 共12个 )","value":"甘肃省","open":true},{"pId":"0_1_4","id":"0_1_4_0","text":"白银市","value":"白银市","open":true},{"pId":"0_1_4","id":"0_1_4_1","text":"嘉峪关市","value":"嘉峪关市","open":true},{"pId":"0_1_4","id":"0_1_4_2","text":"金昌市","value":"金昌市","open":true},{"pId":"0_1_4","id":"0_1_4_3","text":"酒泉市","value":"酒泉市","open":true},{"pId":"0_1_4","id":"0_1_4_4","text":"兰州市","value":"兰州市","open":true},{"pId":"0_1_4","id":"0_1_4_5","text":"陇南市","value":"陇南市","open":true},{"pId":"0_1_4","id":"0_1_4_6","text":"平凉市","value":"平凉市","open":true},{"pId":"0_1_4","id":"0_1_4_7","text":"庆阳市","value":"庆阳市","open":true},{"pId":"0_1_4","id":"0_1_4_8","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1_4","id":"0_1_4_9","text":"天水市","value":"天水市","open":true},{"pId":"0_1_4","id":"0_1_4_10","text":"武威市","value":"武威市","open":true},{"pId":"0_1_4","id":"0_1_4_11","text":"张掖市","value":"张掖市","open":true},{"pId":"0_1","id":"0_1_5","text":"广东省( 共21个 )","value":"广东省","open":true},{"pId":"0_1_5","id":"0_1_5_0","text":"潮州市","value":"潮州市","open":true},{"pId":"0_1_5","id":"0_1_5_1","text":"东莞市","value":"东莞市","open":true},{"pId":"0_1_5","id":"0_1_5_2","text":"佛山市","value":"佛山市","open":true},{"pId":"0_1_5","id":"0_1_5_3","text":"广州市","value":"广州市","open":true},{"pId":"0_1_5","id":"0_1_5_4","text":"河源市","value":"河源市","open":true},{"pId":"0_1_5","id":"0_1_5_5","text":"惠州市","value":"惠州市","open":true},{"pId":"0_1_5","id":"0_1_5_6","text":"江门市","value":"江门市","open":true},{"pId":"0_1_5","id":"0_1_5_7","text":"揭阳市","value":"揭阳市","open":true},{"pId":"0_1_5","id":"0_1_5_8","text":"茂名市","value":"茂名市","open":true},{"pId":"0_1_5","id":"0_1_5_9","text":"梅州市","value":"梅州市","open":true},{"pId":"0_1_5","id":"0_1_5_10","text":"清远市","value":"清远市","open":true},{"pId":"0_1_5","id":"0_1_5_11","text":"汕头市","value":"汕头市","open":true},{"pId":"0_1_5","id":"0_1_5_12","text":"汕尾市","value":"汕尾市","open":true},{"pId":"0_1_5","id":"0_1_5_13","text":"韶关市","value":"韶关市","open":true},{"pId":"0_1_5","id":"0_1_5_14","text":"深圳市","value":"深圳市","open":true},{"pId":"0_1_5","id":"0_1_5_15","text":"阳江市","value":"阳江市","open":true},{"pId":"0_1_5","id":"0_1_5_16","text":"云浮市","value":"云浮市","open":true},{"pId":"0_1_5","id":"0_1_5_17","text":"湛江市","value":"湛江市","open":true},{"pId":"0_1_5","id":"0_1_5_18","text":"肇庆市","value":"肇庆市","open":true},{"pId":"0_1_5","id":"0_1_5_19","text":"中山市","value":"中山市","open":true},{"pId":"0_1_5","id":"0_1_5_20","text":"珠海市","value":"珠海市","open":true},{"pId":"0_1","id":"0_1_6","text":"广西壮族自治区( 共14个 )","value":"广西壮族自治区","open":true},{"pId":"0_1_6","id":"0_1_6_0","text":"百色市","value":"百色市","open":true},{"pId":"0_1_6","id":"0_1_6_1","text":"北海市","value":"北海市","open":true},{"pId":"0_1_6","id":"0_1_6_2","text":"崇左市","value":"崇左市","open":true},{"pId":"0_1_6","id":"0_1_6_3","text":"防城港市","value":"防城港市","open":true},{"pId":"0_1_6","id":"0_1_6_4","text":"桂林市","value":"桂林市","open":true},{"pId":"0_1_6","id":"0_1_6_5","text":"贵港市","value":"贵港市","open":true},{"pId":"0_1_6","id":"0_1_6_6","text":"河池市","value":"河池市","open":true},{"pId":"0_1_6","id":"0_1_6_7","text":"贺州市","value":"贺州市","open":true},{"pId":"0_1_6","id":"0_1_6_8","text":"来宾市","value":"来宾市","open":true},{"pId":"0_1_6","id":"0_1_6_9","text":"柳州市","value":"柳州市","open":true},{"pId":"0_1_6","id":"0_1_6_10","text":"南宁市","value":"南宁市","open":true},{"pId":"0_1_6","id":"0_1_6_11","text":"钦州市","value":"钦州市","open":true},{"pId":"0_1_6","id":"0_1_6_12","text":"梧州市","value":"梧州市","open":true},{"pId":"0_1_6","id":"0_1_6_13","text":"玉林市","value":"玉林市","open":true},{"pId":"0_1","id":"0_1_7","text":"贵州省( 共9个 )","value":"贵州省","open":true},{"pId":"0_1_7","id":"0_1_7_0","text":"安顺市","value":"安顺市","open":true},{"pId":"0_1_7","id":"0_1_7_1","text":"毕节地区","value":"毕节地区","open":true},{"pId":"0_1_7","id":"0_1_7_2","text":"贵阳市","value":"贵阳市","open":true},{"pId":"0_1_7","id":"0_1_7_3","text":"六盘水市","value":"六盘水市","open":true},{"pId":"0_1_7","id":"0_1_7_4","text":"黔东南州","value":"黔东南州","open":true},{"pId":"0_1_7","id":"0_1_7_5","text":"黔南州","value":"黔南州","open":true},{"pId":"0_1_7","id":"0_1_7_6","text":"黔西南市","value":"黔西南市","open":true},{"pId":"0_1_7","id":"0_1_7_7","text":"铜仁地区","value":"铜仁地区","open":true},{"pId":"0_1_7","id":"0_1_7_8","text":"遵义市","value":"遵义市","open":true},{"pId":"0_1","id":"0_1_8","text":"海南省( 共2个 )","value":"海南省","open":true},{"pId":"0_1_8","id":"0_1_8_0","text":"海口市","value":"海口市","open":true},{"pId":"0_1_8","id":"0_1_8_1","text":"三亚市","value":"三亚市","open":true},{"pId":"0_1","id":"0_1_9","text":"河北省( 共12个 )","value":"河北省","open":true},{"pId":"0_1_9","id":"0_1_9_0","text":"保定市","value":"保定市","open":true},{"pId":"0_1_9","id":"0_1_9_1","text":"沧州市","value":"沧州市","open":true},{"pId":"0_1_9","id":"0_1_9_2","text":"承德市","value":"承德市","open":true},{"pId":"0_1_9","id":"0_1_9_3","text":"邯郸市","value":"邯郸市","open":true},{"pId":"0_1_9","id":"0_1_9_4","text":"衡水市","value":"衡水市","open":true},{"pId":"0_1_9","id":"0_1_9_5","text":"廊坊市","value":"廊坊市","open":true},{"pId":"0_1_9","id":"0_1_9_6","text":"秦皇岛市","value":"秦皇岛市","open":true},{"pId":"0_1_9","id":"0_1_9_7","text":"石家庄市","value":"石家庄市","open":true},{"pId":"0_1_9","id":"0_1_9_8","text":"唐山市","value":"唐山市","open":true},{"pId":"0_1_9","id":"0_1_9_9","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1_9","id":"0_1_9_10","text":"邢台市","value":"邢台市","open":true},{"pId":"0_1_9","id":"0_1_9_11","text":"张家口市","value":"张家口市","open":true},{"pId":"0_1","id":"0_1_10","text":"河南省( 共19个 )","value":"河南省","open":true},{"pId":"0_1_10","id":"0_1_10_0","text":"安阳市","value":"安阳市","open":true},{"pId":"0_1_10","id":"0_1_10_1","text":"鹤壁市","value":"鹤壁市","open":true},{"pId":"0_1_10","id":"0_1_10_2","text":"济源市","value":"济源市","open":true},{"pId":"0_1_10","id":"0_1_10_3","text":"焦作市","value":"焦作市","open":true},{"pId":"0_1_10","id":"0_1_10_4","text":"开封市","value":"开封市","open":true},{"pId":"0_1_10","id":"0_1_10_5","text":"廊坊市","value":"廊坊市","open":true},{"pId":"0_1_10","id":"0_1_10_6","text":"洛阳市","value":"洛阳市","open":true},{"pId":"0_1_10","id":"0_1_10_7","text":"漯河市","value":"漯河市","open":true},{"pId":"0_1_10","id":"0_1_10_8","text":"南阳市","value":"南阳市","open":true},{"pId":"0_1_10","id":"0_1_10_9","text":"平顶山市","value":"平顶山市","open":true},{"pId":"0_1_10","id":"0_1_10_10","text":"濮阳市","value":"濮阳市","open":true},{"pId":"0_1_10","id":"0_1_10_11","text":"三门峡市","value":"三门峡市","open":true},{"pId":"0_1_10","id":"0_1_10_12","text":"商丘市","value":"商丘市","open":true},{"pId":"0_1_10","id":"0_1_10_13","text":"新乡市","value":"新乡市","open":true},{"pId":"0_1_10","id":"0_1_10_14","text":"信阳市","value":"信阳市","open":true},{"pId":"0_1_10","id":"0_1_10_15","text":"许昌市","value":"许昌市","open":true},{"pId":"0_1_10","id":"0_1_10_16","text":"郑州市","value":"郑州市","open":true},{"pId":"0_1_10","id":"0_1_10_17","text":"周口市","value":"周口市","open":true},{"pId":"0_1_10","id":"0_1_10_18","text":"驻马店市","value":"驻马店市","open":true},{"pId":"0_1","id":"0_1_11","text":"黑龙江省( 共13个 )","value":"黑龙江省","open":true},{"pId":"0_1_11","id":"0_1_11_0","text":"大庆市","value":"大庆市","open":true},{"pId":"0_1_11","id":"0_1_11_1","text":"大兴安岭地区","value":"大兴安岭地区","open":true},{"pId":"0_1_11","id":"0_1_11_2","text":"大兴安岭市","value":"大兴安岭市","open":true},{"pId":"0_1_11","id":"0_1_11_3","text":"哈尔滨市","value":"哈尔滨市","open":true},{"pId":"0_1_11","id":"0_1_11_4","text":"鹤港市","value":"鹤港市","open":true},{"pId":"0_1_11","id":"0_1_11_5","text":"黑河市","value":"黑河市","open":true},{"pId":"0_1_11","id":"0_1_11_6","text":"佳木斯市","value":"佳木斯市","open":true},{"pId":"0_1_11","id":"0_1_11_7","text":"牡丹江市","value":"牡丹江市","open":true},{"pId":"0_1_11","id":"0_1_11_8","text":"七台河市","value":"七台河市","open":true},{"pId":"0_1_11","id":"0_1_11_9","text":"齐齐哈尔市","value":"齐齐哈尔市","open":true},{"pId":"0_1_11","id":"0_1_11_10","text":"双鸭山市","value":"双鸭山市","open":true},{"pId":"0_1_11","id":"0_1_11_11","text":"绥化市","value":"绥化市","open":true},{"pId":"0_1_11","id":"0_1_11_12","text":"伊春市","value":"伊春市","open":true},{"pId":"0_1","id":"0_1_12","text":"湖北省( 共16个 )","value":"湖北省","open":true},{"pId":"0_1_12","id":"0_1_12_0","text":"鄂州市","value":"鄂州市","open":true},{"pId":"0_1_12","id":"0_1_12_1","text":"恩施土家族苗族自治州","value":"恩施土家族苗族自治州","open":true},{"pId":"0_1_12","id":"0_1_12_2","text":"黄冈市","value":"黄冈市","open":true},{"pId":"0_1_12","id":"0_1_12_3","text":"黄石市","value":"黄石市","open":true},{"pId":"0_1_12","id":"0_1_12_4","text":"荆门市","value":"荆门市","open":true},{"pId":"0_1_12","id":"0_1_12_5","text":"荆州市","value":"荆州市","open":true},{"pId":"0_1_12","id":"0_1_12_6","text":"神农架市","value":"神农架市","open":true},{"pId":"0_1_12","id":"0_1_12_7","text":"十堰市","value":"十堰市","open":true},{"pId":"0_1_12","id":"0_1_12_8","text":"随州市","value":"随州市","open":true},{"pId":"0_1_12","id":"0_1_12_9","text":"天门市","value":"天门市","open":true},{"pId":"0_1_12","id":"0_1_12_10","text":"武汉市","value":"武汉市","open":true},{"pId":"0_1_12","id":"0_1_12_11","text":"咸宁市","value":"咸宁市","open":true},{"pId":"0_1_12","id":"0_1_12_12","text":"襄樊市","value":"襄樊市","open":true},{"pId":"0_1_12","id":"0_1_12_13","text":"襄阳市","value":"襄阳市","open":true},{"pId":"0_1_12","id":"0_1_12_14","text":"孝感市","value":"孝感市","open":true},{"pId":"0_1_12","id":"0_1_12_15","text":"宜昌市","value":"宜昌市","open":true},{"pId":"0_1","id":"0_1_13","text":"湖南省( 共15个 )","value":"湖南省","open":true},{"pId":"0_1_13","id":"0_1_13_0","text":"常德市","value":"常德市","open":true},{"pId":"0_1_13","id":"0_1_13_1","text":"长沙市","value":"长沙市","open":true},{"pId":"0_1_13","id":"0_1_13_2","text":"郴州市","value":"郴州市","open":true},{"pId":"0_1_13","id":"0_1_13_3","text":"衡阳市","value":"衡阳市","open":true},{"pId":"0_1_13","id":"0_1_13_4","text":"怀化市","value":"怀化市","open":true},{"pId":"0_1_13","id":"0_1_13_5","text":"娄底市","value":"娄底市","open":true},{"pId":"0_1_13","id":"0_1_13_6","text":"邵阳市","value":"邵阳市","open":true},{"pId":"0_1_13","id":"0_1_13_7","text":"湘潭市","value":"湘潭市","open":true},{"pId":"0_1_13","id":"0_1_13_8","text":"湘西市","value":"湘西市","open":true},{"pId":"0_1_13","id":"0_1_13_9","text":"湘西土家族苗族自治州","value":"湘西土家族苗族自治州","open":true},{"pId":"0_1_13","id":"0_1_13_10","text":"益阳市","value":"益阳市","open":true},{"pId":"0_1_13","id":"0_1_13_11","text":"永州市","value":"永州市","open":true},{"pId":"0_1_13","id":"0_1_13_12","text":"岳阳市","value":"岳阳市","open":true},{"pId":"0_1_13","id":"0_1_13_13","text":"张家界市","value":"张家界市","open":true},{"pId":"0_1_13","id":"0_1_13_14","text":"株洲市","value":"株洲市","open":true},{"pId":"0_1","id":"0_1_14","text":"吉林省( 共10个 )","value":"吉林省","open":true},{"pId":"0_1_14","id":"0_1_14_0","text":"白城市","value":"白城市","open":true},{"pId":"0_1_14","id":"0_1_14_1","text":"白山市","value":"白山市","open":true},{"pId":"0_1_14","id":"0_1_14_2","text":"长春市","value":"长春市","open":true},{"pId":"0_1_14","id":"0_1_14_3","text":"大庆市","value":"大庆市","open":true},{"pId":"0_1_14","id":"0_1_14_4","text":"吉林市","value":"吉林市","open":true},{"pId":"0_1_14","id":"0_1_14_5","text":"辽源市","value":"辽源市","open":true},{"pId":"0_1_14","id":"0_1_14_6","text":"四平市","value":"四平市","open":true},{"pId":"0_1_14","id":"0_1_14_7","text":"松原市","value":"松原市","open":true},{"pId":"0_1_14","id":"0_1_14_8","text":"通化市","value":"通化市","open":true},{"pId":"0_1_14","id":"0_1_14_9","text":"延边朝鲜族自治州","value":"延边朝鲜族自治州","open":true},{"pId":"0_1","id":"0_1_15","text":"江苏省( 共13个 )","value":"江苏省","open":true},{"pId":"0_1_15","id":"0_1_15_0","text":"常州市","value":"常州市","open":true},{"pId":"0_1_15","id":"0_1_15_1","text":"淮安市","value":"淮安市","open":true},{"pId":"0_1_15","id":"0_1_15_2","text":"连云港市","value":"连云港市","open":true},{"pId":"0_1_15","id":"0_1_15_3","text":"南京市","value":"南京市","open":true},{"pId":"0_1_15","id":"0_1_15_4","text":"南通市","value":"南通市","open":true},{"pId":"0_1_15","id":"0_1_15_5","text":"苏州市","value":"苏州市","open":true},{"pId":"0_1_15","id":"0_1_15_6","text":"宿迁市","value":"宿迁市","open":true},{"pId":"0_1_15","id":"0_1_15_7","text":"泰州市","value":"泰州市","open":true},{"pId":"0_1_15","id":"0_1_15_8","text":"无锡市","value":"无锡市","open":true},{"pId":"0_1_15","id":"0_1_15_9","text":"徐州市","value":"徐州市","open":true},{"pId":"0_1_15","id":"0_1_15_10","text":"盐城市","value":"盐城市","open":true},{"pId":"0_1_15","id":"0_1_15_11","text":"扬州市","value":"扬州市","open":true},{"pId":"0_1_15","id":"0_1_15_12","text":"镇江市","value":"镇江市","open":true},{"pId":"0_1","id":"0_1_16","text":"江西省( 共10个 )","value":"江西省","open":true},{"pId":"0_1_16","id":"0_1_16_0","text":"抚州市","value":"抚州市","open":true},{"pId":"0_1_16","id":"0_1_16_1","text":"赣州市","value":"赣州市","open":true},{"pId":"0_1_16","id":"0_1_16_2","text":"景德镇市","value":"景德镇市","open":true},{"pId":"0_1_16","id":"0_1_16_3","text":"九江市","value":"九江市","open":true},{"pId":"0_1_16","id":"0_1_16_4","text":"南昌市","value":"南昌市","open":true},{"pId":"0_1_16","id":"0_1_16_5","text":"萍乡市","value":"萍乡市","open":true},{"pId":"0_1_16","id":"0_1_16_6","text":"上饶市","value":"上饶市","open":true},{"pId":"0_1_16","id":"0_1_16_7","text":"新余市","value":"新余市","open":true},{"pId":"0_1_16","id":"0_1_16_8","text":"宜春市","value":"宜春市","open":true},{"pId":"0_1_16","id":"0_1_16_9","text":"鹰潭市","value":"鹰潭市","open":true},{"pId":"0_1","id":"0_1_17","text":"辽宁省( 共14个 )","value":"辽宁省","open":true},{"pId":"0_1_17","id":"0_1_17_0","text":"鞍山市","value":"鞍山市","open":true},{"pId":"0_1_17","id":"0_1_17_1","text":"本溪市","value":"本溪市","open":true},{"pId":"0_1_17","id":"0_1_17_2","text":"朝阳市","value":"朝阳市","open":true},{"pId":"0_1_17","id":"0_1_17_3","text":"大连市","value":"大连市","open":true},{"pId":"0_1_17","id":"0_1_17_4","text":"丹东市","value":"丹东市","open":true},{"pId":"0_1_17","id":"0_1_17_5","text":"抚顺市","value":"抚顺市","open":true},{"pId":"0_1_17","id":"0_1_17_6","text":"阜新市","value":"阜新市","open":true},{"pId":"0_1_17","id":"0_1_17_7","text":"葫芦岛市","value":"葫芦岛市","open":true},{"pId":"0_1_17","id":"0_1_17_8","text":"锦州市","value":"锦州市","open":true},{"pId":"0_1_17","id":"0_1_17_9","text":"辽阳市","value":"辽阳市","open":true},{"pId":"0_1_17","id":"0_1_17_10","text":"盘锦市","value":"盘锦市","open":true},{"pId":"0_1_17","id":"0_1_17_11","text":"沈阳市","value":"沈阳市","open":true},{"pId":"0_1_17","id":"0_1_17_12","text":"铁岭市","value":"铁岭市","open":true},{"pId":"0_1_17","id":"0_1_17_13","text":"营口市","value":"营口市","open":true},{"pId":"0_1","id":"0_1_18","text":"内蒙古( 共10个 )","value":"内蒙古","open":true},{"pId":"0_1_18","id":"0_1_18_0","text":"包头市","value":"包头市","open":true},{"pId":"0_1_18","id":"0_1_18_1","text":"赤峰市","value":"赤峰市","open":true},{"pId":"0_1_18","id":"0_1_18_2","text":"鄂尔多斯市","value":"鄂尔多斯市","open":true},{"pId":"0_1_18","id":"0_1_18_3","text":"呼和浩特市","value":"呼和浩特市","open":true},{"pId":"0_1_18","id":"0_1_18_4","text":"呼伦贝尔市","value":"呼伦贝尔市","open":true},{"pId":"0_1_18","id":"0_1_18_5","text":"通辽市","value":"通辽市","open":true},{"pId":"0_1_18","id":"0_1_18_6","text":"乌海市","value":"乌海市","open":true},{"pId":"0_1_18","id":"0_1_18_7","text":"锡林郭勒市","value":"锡林郭勒市","open":true},{"pId":"0_1_18","id":"0_1_18_8","text":"兴安市","value":"兴安市","open":true},{"pId":"0_1_18","id":"0_1_18_9","text":"运城市","value":"运城市","open":true},{"pId":"0_1","id":"0_1_19","text":"宁夏回族自治区( 共5个 )","value":"宁夏回族自治区","open":true},{"pId":"0_1_19","id":"0_1_19_0","text":"固原市","value":"固原市","open":true},{"pId":"0_1_19","id":"0_1_19_1","text":"石嘴山市","value":"石嘴山市","open":true},{"pId":"0_1_19","id":"0_1_19_2","text":"吴忠市","value":"吴忠市","open":true},{"pId":"0_1_19","id":"0_1_19_3","text":"银川市","value":"银川市","open":true},{"pId":"0_1_19","id":"0_1_19_4","text":"中卫市","value":"中卫市","open":true},{"pId":"0_1","id":"0_1_20","text":"青海省( 共4个 )","value":"青海省","open":true},{"pId":"0_1_20","id":"0_1_20_0","text":"海东地区","value":"海东地区","open":true},{"pId":"0_1_20","id":"0_1_20_1","text":"海南藏族自治州","value":"海南藏族自治州","open":true},{"pId":"0_1_20","id":"0_1_20_2","text":"海西蒙古族藏族自治州","value":"海西蒙古族藏族自治州","open":true},{"pId":"0_1_20","id":"0_1_20_3","text":"西宁市","value":"西宁市","open":true},{"pId":"0_1","id":"0_1_21","text":"山东省( 共17个 )","value":"山东省","open":true},{"pId":"0_1_21","id":"0_1_21_0","text":"滨州市","value":"滨州市","open":true},{"pId":"0_1_21","id":"0_1_21_1","text":"德州市","value":"德州市","open":true},{"pId":"0_1_21","id":"0_1_21_2","text":"东营市","value":"东营市","open":true},{"pId":"0_1_21","id":"0_1_21_3","text":"菏泽市","value":"菏泽市","open":true},{"pId":"0_1_21","id":"0_1_21_4","text":"济南市","value":"济南市","open":true},{"pId":"0_1_21","id":"0_1_21_5","text":"济宁市","value":"济宁市","open":true},{"pId":"0_1_21","id":"0_1_21_6","text":"莱芜市","value":"莱芜市","open":true},{"pId":"0_1_21","id":"0_1_21_7","text":"聊城市","value":"聊城市","open":true},{"pId":"0_1_21","id":"0_1_21_8","text":"临沂市","value":"临沂市","open":true},{"pId":"0_1_21","id":"0_1_21_9","text":"青岛市","value":"青岛市","open":true},{"pId":"0_1_21","id":"0_1_21_10","text":"日照市","value":"日照市","open":true},{"pId":"0_1_21","id":"0_1_21_11","text":"泰安市","value":"泰安市","open":true},{"pId":"0_1_21","id":"0_1_21_12","text":"威海市","value":"威海市","open":true},{"pId":"0_1_21","id":"0_1_21_13","text":"潍坊市","value":"潍坊市","open":true},{"pId":"0_1_21","id":"0_1_21_14","text":"烟台市","value":"烟台市","open":true},{"pId":"0_1_21","id":"0_1_21_15","text":"枣庄市","value":"枣庄市","open":true},{"pId":"0_1_21","id":"0_1_21_16","text":"淄博市","value":"淄博市","open":true},{"pId":"0_1","id":"0_1_22","text":"山西省( 共12个 )","value":"山西省","open":true},{"pId":"0_1_22","id":"0_1_22_0","text":"长治市","value":"长治市","open":true},{"pId":"0_1_22","id":"0_1_22_1","text":"大同市","value":"大同市","open":true},{"pId":"0_1_22","id":"0_1_22_2","text":"晋城市","value":"晋城市","open":true},{"pId":"0_1_22","id":"0_1_22_3","text":"晋中市","value":"晋中市","open":true},{"pId":"0_1_22","id":"0_1_22_4","text":"临汾市","value":"临汾市","open":true},{"pId":"0_1_22","id":"0_1_22_5","text":"吕梁市","value":"吕梁市","open":true},{"pId":"0_1_22","id":"0_1_22_6","text":"青岛市","value":"青岛市","open":true},{"pId":"0_1_22","id":"0_1_22_7","text":"朔州市","value":"朔州市","open":true},{"pId":"0_1_22","id":"0_1_22_8","text":"太原市","value":"太原市","open":true},{"pId":"0_1_22","id":"0_1_22_9","text":"忻州市","value":"忻州市","open":true},{"pId":"0_1_22","id":"0_1_22_10","text":"阳泉市","value":"阳泉市","open":true},{"pId":"0_1_22","id":"0_1_22_11","text":"运城市","value":"运城市","open":true},{"pId":"0_1","id":"0_1_23","text":"陕西省( 共9个 )","value":"陕西省","open":true},{"pId":"0_1_23","id":"0_1_23_0","text":"安康市","value":"安康市","open":true},{"pId":"0_1_23","id":"0_1_23_1","text":"宝鸡市","value":"宝鸡市","open":true},{"pId":"0_1_23","id":"0_1_23_2","text":"汉中市","value":"汉中市","open":true},{"pId":"0_1_23","id":"0_1_23_3","text":"商洛市","value":"商洛市","open":true},{"pId":"0_1_23","id":"0_1_23_4","text":"渭南市","value":"渭南市","open":true},{"pId":"0_1_23","id":"0_1_23_5","text":"西安市","value":"西安市","open":true},{"pId":"0_1_23","id":"0_1_23_6","text":"咸阳市","value":"咸阳市","open":true},{"pId":"0_1_23","id":"0_1_23_7","text":"延安市","value":"延安市","open":true},{"pId":"0_1_23","id":"0_1_23_8","text":"榆林市","value":"榆林市","open":true},{"pId":"0_1","id":"0_1_24","text":"上海市( 共19个 )","value":"上海市","open":true},{"pId":"0_1_24","id":"0_1_24_0","text":"宝山区","value":"宝山区","open":true},{"pId":"0_1_24","id":"0_1_24_1","text":"长宁区","value":"长宁区","open":true},{"pId":"0_1_24","id":"0_1_24_2","text":"崇明县","value":"崇明县","open":true},{"pId":"0_1_24","id":"0_1_24_3","text":"奉贤区","value":"奉贤区","open":true},{"pId":"0_1_24","id":"0_1_24_4","text":"虹口区","value":"虹口区","open":true},{"pId":"0_1_24","id":"0_1_24_5","text":"黄浦区","value":"黄浦区","open":true},{"pId":"0_1_24","id":"0_1_24_6","text":"嘉定区","value":"嘉定区","open":true},{"pId":"0_1_24","id":"0_1_24_7","text":"金山区","value":"金山区","open":true},{"pId":"0_1_24","id":"0_1_24_8","text":"静安区","value":"静安区","open":true},{"pId":"0_1_24","id":"0_1_24_9","text":"昆明市","value":"昆明市","open":true},{"pId":"0_1_24","id":"0_1_24_10","text":"闵行区","value":"闵行区","open":true},{"pId":"0_1_24","id":"0_1_24_11","text":"普陀区","value":"普陀区","open":true},{"pId":"0_1_24","id":"0_1_24_12","text":"浦东新区","value":"浦东新区","open":true},{"pId":"0_1_24","id":"0_1_24_13","text":"青浦区","value":"青浦区","open":true},{"pId":"0_1_24","id":"0_1_24_14","text":"上海市区","value":"上海市区","open":true},{"pId":"0_1_24","id":"0_1_24_15","text":"松江区","value":"松江区","open":true},{"pId":"0_1_24","id":"0_1_24_16","text":"徐汇区","value":"徐汇区","open":true},{"pId":"0_1_24","id":"0_1_24_17","text":"杨浦区","value":"杨浦区","open":true},{"pId":"0_1_24","id":"0_1_24_18","text":"闸北区","value":"闸北区","open":true},{"pId":"0_1","id":"0_1_25","text":"四川省( 共21个 )","value":"四川省","open":true},{"pId":"0_1_25","id":"0_1_25_0","text":"阿坝藏族羌族自治州","value":"阿坝藏族羌族自治州","open":true},{"pId":"0_1_25","id":"0_1_25_1","text":"巴中市","value":"巴中市","open":true},{"pId":"0_1_25","id":"0_1_25_2","text":"成都市","value":"成都市","open":true},{"pId":"0_1_25","id":"0_1_25_3","text":"达州市","value":"达州市","open":true},{"pId":"0_1_25","id":"0_1_25_4","text":"德阳市","value":"德阳市","open":true},{"pId":"0_1_25","id":"0_1_25_5","text":"甘孜市","value":"甘孜市","open":true},{"pId":"0_1_25","id":"0_1_25_6","text":"广安市","value":"广安市","open":true},{"pId":"0_1_25","id":"0_1_25_7","text":"广元市","value":"广元市","open":true},{"pId":"0_1_25","id":"0_1_25_8","text":"乐山市","value":"乐山市","open":true},{"pId":"0_1_25","id":"0_1_25_9","text":"凉山市","value":"凉山市","open":true},{"pId":"0_1_25","id":"0_1_25_10","text":"泸州市","value":"泸州市","open":true},{"pId":"0_1_25","id":"0_1_25_11","text":"眉山市","value":"眉山市","open":true},{"pId":"0_1_25","id":"0_1_25_12","text":"绵阳市","value":"绵阳市","open":true},{"pId":"0_1_25","id":"0_1_25_13","text":"南充市","value":"南充市","open":true},{"pId":"0_1_25","id":"0_1_25_14","text":"内江市","value":"内江市","open":true},{"pId":"0_1_25","id":"0_1_25_15","text":"攀枝花市","value":"攀枝花市","open":true},{"pId":"0_1_25","id":"0_1_25_16","text":"遂宁市","value":"遂宁市","open":true},{"pId":"0_1_25","id":"0_1_25_17","text":"雅安市","value":"雅安市","open":true},{"pId":"0_1_25","id":"0_1_25_18","text":"宜宾市","value":"宜宾市","open":true},{"pId":"0_1_25","id":"0_1_25_19","text":"资阳市","value":"资阳市","open":true},{"pId":"0_1_25","id":"0_1_25_20","text":"自贡市","value":"自贡市","open":true},{"pId":"0_1","id":"0_1_26","text":"台湾( 共1个 )","value":"台湾","open":true},{"pId":"0_1_26","id":"0_1_26_0","text":"台北市","value":"台北市","open":true},{"pId":"0_1","id":"0_1_27","text":"天津市( 共1个 )","value":"天津市","open":true},{"pId":"0_1_27","id":"0_1_27_0","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1","id":"0_1_28","text":"西藏自治区( 共2个 )","value":"西藏自治区","open":true},{"pId":"0_1_28","id":"0_1_28_0","text":"阿里市","value":"阿里市","open":true},{"pId":"0_1_28","id":"0_1_28_1","text":"日喀则市","value":"日喀则市","open":true},{"pId":"0_1","id":"0_1_29","text":"香港特别行政区( 共1个 )","value":"香港特别行政区","open":true},{"pId":"0_1_29","id":"0_1_29_0","text":"香港","value":"香港","open":true},{"pId":"0_1","id":"0_1_30","text":"新疆维吾尔族自治区( 共11个 )","value":"新疆维吾尔族自治区","open":true},{"pId":"0_1_30","id":"0_1_30_0","text":"巴音郭楞市","value":"巴音郭楞市","open":true},{"pId":"0_1_30","id":"0_1_30_1","text":"哈密市","value":"哈密市","open":true},{"pId":"0_1_30","id":"0_1_30_2","text":"和田市","value":"和田市","open":true},{"pId":"0_1_30","id":"0_1_30_3","text":"喀什地区","value":"喀什地区","open":true},{"pId":"0_1_30","id":"0_1_30_4","text":"克拉玛依市","value":"克拉玛依市","open":true},{"pId":"0_1_30","id":"0_1_30_5","text":"克孜勒苏柯州","value":"克孜勒苏柯州","open":true},{"pId":"0_1_30","id":"0_1_30_6","text":"石河子市","value":"石河子市","open":true},{"pId":"0_1_30","id":"0_1_30_7","text":"塔城市","value":"塔城市","open":true},{"pId":"0_1_30","id":"0_1_30_8","text":"吐鲁番地区","value":"吐鲁番地区","open":true},{"pId":"0_1_30","id":"0_1_30_9","text":"乌鲁木齐","value":"乌鲁木齐","open":true},{"pId":"0_1_30","id":"0_1_30_10","text":"伊犁市","value":"伊犁市","open":true},{"pId":"0_1","id":"0_1_31","text":"云南省( 共12个 )","value":"云南省","open":true},{"pId":"0_1_31","id":"0_1_31_0","text":"保山市","value":"保山市","open":true},{"pId":"0_1_31","id":"0_1_31_1","text":"楚雄彝族自治州","value":"楚雄彝族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_2","text":"大理白族自治州","value":"大理白族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_3","text":"红河哈尼族彝族自治州","value":"红河哈尼族彝族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_4","text":"昆明市","value":"昆明市","open":true},{"pId":"0_1_31","id":"0_1_31_5","text":"丽江市","value":"丽江市","open":true},{"pId":"0_1_31","id":"0_1_31_6","text":"临沧市","value":"临沧市","open":true},{"pId":"0_1_31","id":"0_1_31_7","text":"曲靖市","value":"曲靖市","open":true},{"pId":"0_1_31","id":"0_1_31_8","text":"思茅市","value":"思茅市","open":true},{"pId":"0_1_31","id":"0_1_31_9","text":"文山市","value":"文山市","open":true},{"pId":"0_1_31","id":"0_1_31_10","text":"玉溪市","value":"玉溪市","open":true},{"pId":"0_1_31","id":"0_1_31_11","text":"昭通市","value":"昭通市","open":true},{"pId":"0_1","id":"0_1_32","text":"浙江省( 共12个 )","value":"浙江省","open":true},{"pId":"0_1_32","id":"0_1_32_0","text":"杭州市","value":"杭州市","open":true},{"pId":"0_1_32","id":"0_1_32_1","text":"湖州市","value":"湖州市","open":true},{"pId":"0_1_32","id":"0_1_32_2","text":"嘉兴市","value":"嘉兴市","open":true},{"pId":"0_1_32","id":"0_1_32_3","text":"金华市","value":"金华市","open":true},{"pId":"0_1_32","id":"0_1_32_4","text":"丽水市","value":"丽水市","open":true},{"pId":"0_1_32","id":"0_1_32_5","text":"宁波市","value":"宁波市","open":true},{"pId":"0_1_32","id":"0_1_32_6","text":"衢州市","value":"衢州市","open":true},{"pId":"0_1_32","id":"0_1_32_7","text":"绍兴市","value":"绍兴市","open":true},{"pId":"0_1_32","id":"0_1_32_8","text":"台州市","value":"台州市","open":true},{"pId":"0_1_32","id":"0_1_32_9","text":"温州市","value":"温州市","open":true},{"pId":"0_1_32","id":"0_1_32_10","text":"浙江省","value":"浙江省","open":true},{"pId":"0_1_32","id":"0_1_32_11","text":"舟山市","value":"舟山市","open":true},{"pId":"0_1","id":"0_1_33","text":"重庆市( 共1个 )","value":"重庆市","open":true},{"pId":"0_1_33","id":"0_1_33_0","text":"重庆市区","value":"重庆市区","open":true}] }; + diff --git a/demo/js/component/demo.treevaluechoosercombo.js b/demo/js/component/demo.treevaluechoosercombo.js index 5de2bcdeb7..8fa557ee1e 100644 --- a/demo/js/component/demo.treevaluechoosercombo.js +++ b/demo/js/component/demo.treevaluechoosercombo.js @@ -4,29 +4,12 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }, render: function () { - var tree = []; - for (var i = 0; i < 221; i++) { - tree.push({ - value: "" + i + "", - text: "" + i + "", - id: i + "", - pId: null - }); - for (var j = 0; j < 9; j++) { - tree.push({ - value: i + "-" + j, - text: j + "", - id: i + "-" + j, - pId: i + "" - }) - } - } var widget = BI.createWidget({ type: "bi.tree_value_chooser_combo", width: 300, - items: tree, + // items: BI.deepClone(Demo.CONSTANTS.TREEITEMS), itemsCreator: function (op, callback) { - callback(tree); + callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); } }); return { diff --git a/demo/js/component/demo.treevaluechooserpane.js b/demo/js/component/demo.treevaluechooserpane.js index e74caac7e7..afe969c4bb 100644 --- a/demo/js/component/demo.treevaluechooserpane.js +++ b/demo/js/component/demo.treevaluechooserpane.js @@ -4,30 +4,12 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }, render: function () { - var tree = []; - for (var i = 0; i < 221; i++) { - tree.push({ - value: "" + i + "", - text: "" + i + "", - id: i + "", - pId: null - }); - for (var j = 0; j < 9; j++) { - tree.push({ - value: i + "-" + j, - text: j + "", - id: i + "-" + j, - pId: i + "" - }) - } - } return { type: "bi.tree_value_chooser_pane", - width: 300, - items: tree, - itemsCreator: function (op, callback) { - callback(tree); - } + items: BI.deepClone(Demo.CONSTANTS.TREEITEMS), + // itemsCreator: function (op, callback) { + // callback(tree); + // } }; } }); diff --git a/demo/js/component/demo.valuechooserpane.js b/demo/js/component/demo.valuechooserpane.js index f2ff3ba7e6..4ed6c2cc05 100644 --- a/demo/js/component/demo.valuechooserpane.js +++ b/demo/js/component/demo.valuechooserpane.js @@ -6,9 +6,9 @@ Demo.ValueChooserPane = BI.inherit(BI.Widget, { return { type: "bi.value_chooser_pane", items: BI.deepClone(Demo.CONSTANTS.ITEMS), - itemsCreator: function (op, callback) { - callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); - } + // itemsCreator: function (op, callback) { + // callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); + // } }; } }); diff --git a/docs/base.js b/docs/base.js index 728e5fd04f..47d72dbfbe 100644 --- a/docs/base.js +++ b/docs/base.js @@ -1710,7 +1710,7 @@ BI.TreeView = BI.inherit(BI.Pane, { _getNodeValue: function (node) { //去除标红 - return node.value || node.text.replace(/<[^>]+>/g, ""); + return node.value == null ? node.text.replace(/<[^>]+>/g, "") : node.value; }, //获取半选框值 @@ -1802,6 +1802,7 @@ BI.TreeView = BI.inherit(BI.Pane, { var self = this, o = this.options; var ns = BI.Tree.arrayFormat(nodes); BI.each(ns, function (i, n) { + n.title = n.title || n.text || n.value; //处理标红 if (BI.isKey(o.paras.keyword)) { n.text = $("
").__textKeywordMarked__(n.text, o.paras.keyword, n.py).html(); @@ -1944,7 +1945,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }, setSelectedValue: function (value) { - this.options.paras.selectedValues = value || {}; + this.options.paras.selectedValues = BI.deepClone(value) || {}; this.selectedValues = BI.deepClone(value) || {}; }, @@ -1963,7 +1964,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function(){ + getExpandedValue: function () { if (!this.nodes) { return null; } @@ -1980,14 +1981,9 @@ BI.TreeView = BI.inherit(BI.Pane, { return this._getSelectedValues(); }, - empty: function () { - BI.isNotNull(this.nodes) && this.nodes.destroy(); - }, - - destroy: function () { + destroyed: function () { this.stop(); this.nodes && this.nodes.destroy(); - BI.TreeView.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.TreeView, { @@ -2190,7 +2186,7 @@ BI.AsyncTree = BI.inherit(BI.TreeView, { } var checkedValues = this._getSelectedValues(); if (BI.isEmpty(checkedValues)) { - return this.selectedValues; + return BI.deepClone(this.selectedValues); } if (BI.isEmpty(this.selectedValues)) { return checkedValues; @@ -2257,7 +2253,7 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); } else { o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA, + type: BI.TreeView.REQ_TYPE_SELECT_DATA, selectedValues: this.selectedValues, notSelectedValue: name, parentValues: parentValues diff --git a/docs/core.js b/docs/core.js index 0867958c94..4b80066049 100644 --- a/docs/core.js +++ b/docs/core.js @@ -13494,15 +13494,15 @@ if (!window.BI) { }, has: function (obj, keys) { - if (BI.isKey(keys)) { - return _.has.apply(_, arguments); - } - if (!keys || BI.isEmpty(keys)) { - return false; + if (BI.isArray(keys)) { + if (keys.length === 0) { + return false; + } + return BI.every(keys, function (i, key) { + return _.has(obj, key); + }); } - return BI.every(keys, function (i, key) { - return _.has(obj, key); - }); + return _.has.apply(_, arguments); }, //数字和字符串可以作为key @@ -18448,7 +18448,7 @@ $.extend(BI, { }, isRoot: function (node) { - return node === this.root || node.id === this.root.id; + return node === this.root; }, getRoot: function () { @@ -18825,7 +18825,7 @@ $.extend(BI, { if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = BI.clone(nodes[i]); - node.pId = pId; + node.pId = node.pId == null ? pId : node.pId; delete node.children; r.push(node); if (nodes[i]["children"]) { @@ -18834,7 +18834,7 @@ $.extend(BI, { } } else { var newNodes = BI.clone(nodes); - newNodes.pId = pId; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; delete newNodes.children; r.push(newNodes); if (nodes["children"]) { @@ -18845,21 +18845,25 @@ $.extend(BI, { }, arrayFormat: function (nodes, pId) { - if (!nodes) return []; + if (!nodes) { + return []; + } var r = []; if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; + node.pId = node.pId == null ? pId : node.pId; r.push(node); if (nodes[i]["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes[i]["children"], node.id)); + r = r.concat(BI.Tree.arrayFormat(nodes[i]["children"], node.id)); } } } else { var newNodes = nodes; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; r.push(newNodes); if (nodes["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes["children"], newNodes.id)); + r = r.concat(BI.Tree.arrayFormat(nodes["children"], newNodes.id)); } } return r; @@ -18875,13 +18879,13 @@ $.extend(BI, { var r = []; var tmpMap = []; for (i = 0, l = sNodes.length; i < l; i++) { - if(BI.isNull(sNodes[i].id)) { + if (BI.isNull(sNodes[i].id)) { return sNodes; } tmpMap[sNodes[i].id] = BI.clone(sNodes[i]); } for (i = 0, l = sNodes.length; i < l; i++) { - if (tmpMap[sNodes[i].pId] && sNodes[i].id != sNodes[i].pId) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { if (!tmpMap[sNodes[i].pId].children) { tmpMap[sNodes[i].pId].children = []; } @@ -18897,6 +18901,37 @@ $.extend(BI, { } }, + treeFormat: function (sNodes) { + var i, l; + if (!sNodes) { + return []; + } + + if (BI.isArray(sNodes)) { + var r = []; + var tmpMap = []; + for (i = 0, l = sNodes.length; i < l; i++) { + if (BI.isNull(sNodes[i].id)) { + return sNodes; + } + tmpMap[sNodes[i].id] = sNodes[i]; + } + for (i = 0, l = sNodes.length; i < l; i++) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { + if (!tmpMap[sNodes[i].pId].children) { + tmpMap[sNodes[i].pId].children = []; + } + tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); + } else { + r.push(tmpMap[sNodes[i].id]); + } + } + return r; + } else { + return [sNodes]; + } + }, + traversal: function (array, callback) { if (BI.isNull(array)) { return; diff --git a/docs/demo.js b/docs/demo.js index 7cec4c55d6..e7fa71450f 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -2624,29 +2624,12 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }, render: function () { - var tree = []; - for (var i = 0; i < 221; i++) { - tree.push({ - value: "" + i + "", - text: "" + i + "", - id: i + "", - pId: null - }); - for (var j = 0; j < 9; j++) { - tree.push({ - value: i + "-" + j, - text: j + "", - id: i + "-" + j, - pId: i + "" - }) - } - } var widget = BI.createWidget({ type: "bi.tree_value_chooser_combo", width: 300, - items: tree, + // items: BI.deepClone(Demo.CONSTANTS.TREEITEMS), itemsCreator: function (op, callback) { - callback(tree); + callback(BI.deepClone(Demo.CONSTANTS.TREEITEMS)); } }); return { @@ -2664,30 +2647,12 @@ Demo.TreeValueChooser = BI.inherit(BI.Widget, { }, render: function () { - var tree = []; - for (var i = 0; i < 221; i++) { - tree.push({ - value: "" + i + "", - text: "" + i + "", - id: i + "", - pId: null - }); - for (var j = 0; j < 9; j++) { - tree.push({ - value: i + "-" + j, - text: j + "", - id: i + "-" + j, - pId: i + "" - }) - } - } return { type: "bi.tree_value_chooser_pane", - width: 300, - items: tree, - itemsCreator: function (op, callback) { - callback(tree); - } + items: BI.deepClone(Demo.CONSTANTS.TREEITEMS), + // itemsCreator: function (op, callback) { + // callback(tree); + // } }; } }); @@ -2719,9 +2684,9 @@ BI.shortcut("demo.value_chooser_combo", Demo.ValueChooserCombo);Demo.ValueChoose return { type: "bi.value_chooser_pane", items: BI.deepClone(Demo.CONSTANTS.ITEMS), - itemsCreator: function (op, callback) { - callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); - } + // itemsCreator: function (op, callback) { + // callback(BI.deepClone(Demo.CONSTANTS.ITEMS)); + // } }; } }); @@ -6856,7 +6821,6 @@ Demo.MultiSelectCombo = BI.inherit(BI.Widget, { }); BI.shortcut("demo.multilayer_select_tree_combo", Demo.MultiSelectCombo);Demo.CONFIG = Demo.CORE_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG).concat(Demo.COMPONENT_CONFIG).concat(Demo.CHART_CONFIG); - Demo.CONSTANTS = { ITEMS: BI.map("柳州市城贸金属材料有限责任公司 柳州市建福房屋租赁有限公司 柳州市迅昌数码办公设备有限责任公司 柳州市河海贸易有限责任公司 柳州市花篮制衣厂 柳州市兴溪物资有限公司 柳州市针织总厂 柳州市衡管物资有限公司 柳州市琪成机电设备有限公司 柳州市松林工程机械修理厂 柳州市积玉贸易有限公司 柳州市福运来贸易有限责任公司 柳州市钢义物资有限公司 柳州市洋力化工有限公司 柳州市悦盛贸易有限公司 柳州市雁城钢管物资有限公司 柳州市恒瑞钢材经营部 柳州市科拓电子有限公司 柳州市九方电子有限公司 柳州市桂龙汽车配件厂 柳州市制鞋工厂 柳州市炜力科贸有限公司 柳州市希翼贸易有限公司 柳州市兆金物资有限公司 柳州市和润电子科技有限责任公司 柳州市汇凯贸易有限公司 柳州市好机汇商贸有限公司 柳州市泛源商贸经营部 柳州市利汇达物资有限公司 广西全民药业有限责任公司 柳州超凡物资贸易有限责任公司 柳州市贵宏物资有限责任公司 柳州昊恒贸易有限责任公司 柳州市浦联物资有限公司 柳州市广通园林绿化工程有限责任公司 柳州市松发物资贸易有限责任公司 柳州市奥士达办公设备有限责任公司 柳州市海泰物资有限公司 柳州市金三环针织厂 柳州市钢贸物资有限公司 柳州市明阳纺织有限公司 柳州市世科科技发展有限公司 柳州市禄羊贸易有限公司 柳州市金兆阳商贸有限公司 柳州市汇昌物资经营部 柳州市林泰金属物资供应站 柳州市自来水管道材料设备公司 柳州市丹柳铝板有限公司 柳州市桂冶物资有限公司 柳州市宸业物资经营部 柳州市耀成贸易有限公司 柳州奥易自动化科技有限公司 柳州市萃丰科技有限责任公司 柳州市华储贸易有限责任公司 柳州市黄颜钢材有限责任公司 柳州市银盛物资有限责任公司 柳州市新仪化玻供应站 柳州市晶凯化工有限公司 广西柳州市柳江包装纸厂 柳州市志新物资有限责任公司 柳州市兆钢物资有限公司 柳州市友方科技发展有限责任公司 柳州市缝纫机台板家具总厂 柳州市晖海数码办公设备有限责任公司 柳州市富兰特服饰有限责任公司 柳州市柳北区富兴物资经营部 柳州市柳锌福利厂 柳州市海泉印刷有限责任公司 柳州市乾亨贸易有限公司 柳州市悦宁物资贸易有限公司 柳州市昊天贸易有限公司 广西惠字钢铁有限公司 柳州市名青物资有限公司 柳州市林郝物资有限公司 柳州市民政服装厂 柳州市多维劳保用品厂 柳州市轻工物资供应公司 柳州市程源物资有限责任公司 柳州市寿丰物资贸易有限责任公司 柳州市凯凡物资有限公司 柳州市利晖物资经营部 柳州市恒茂金属物资供应站 柳州市中储物资经营部 柳州市第二医疗器械厂 柳州市来鑫物资经营部 柳州市钢鑫物资贸易有限责任公司 柳州市双合袜业有限责任公司 柳州市茂松经贸有限责任公司 柳州市行行物资贸易有限公司 柳州市方一物资有限公司 柳州成异钢管销售有限公司 柳州广惠佳电脑有限公司 桂林市圣泽鑫物资有限公司柳州分公司 柳州市砼基建材贸易有限公司 柳州市海燕针织厂 上海浦光仪表厂柳州销售处 柳州市能电工贸有限责任公司 柳州市广贸物资有限公司 柳州市柳北区大昌电工灯饰经营部 柳州市金龙印务有限公司 柳州市奇缘婚典服务有限公司 柳州市盛博物资经营部 柳州市项元钢铁贸易有限公司 柳州市虞美人化妆品经营部 柳州市俊彦鞋厂 柳州市聚源特钢有限公司 柳州市迅龙科贸有限责任公司 柳州市恒飞电子有限责任公司 柳州市蓝正现代办公设备有限责任公司 柳州地区农业生产资料公司 柳州华菱钢管销售有限公司 柳州融通物资有限公司 柳州市可仁广告策划有限责任公司 柳州市鸟鑫物资有限责任公司 柳州市五丰钢材供应站 柳州市金江不锈钢有限公司 柳州市美日物资设备有限责任公司 柳州市鑫东物资贸易有限责任公司 柳州地区日用杂品公司 柳州市华纳物资贸易有限公司 柳州乾利金虹物资贸易有限责任公司 柳州市新迈计算机有限公司 柳州市富丽实业发展公司 柳州市石钢金属材料有限公司 柳州市力志传真机销售有限公司 广西宝森投资有限公司 柳州市嵘基商贸有限公司 柳州市景民商贸有限责任公司 柳州市银桥化玻有限责任公司 柳州市宏文糖烟店 柳州市科苑电脑网络有限公司 柳州市两面针旅游用品厂 柳州市立早室内装璜有限责任公司 柳州地化建材有限公司 柳州市涛达贸易有限公司 柳州市兰丰档案服务中心 柳州市惠贸物资有限责任公司 柳州市立文物资有限责任公司 柳州市致和商贸经营部 柳州市金色阳光信息咨询有限公司 柳州市赛利钢材经销部 柳州市日用化工厂 柳州市昆廷物资有限责任公司 柳州市邦盛贸易有限公司 柳州市济华贸易有限公司 柳州昕威橡塑化工经营部 柳州市联业贸易有限公司 柳州市兰钢贸易有限公司 柳州市子欣科技有限公司 柳州市狄龙机电设备有限公司 柳州市方真物资贸易有限公司 柳州市银鸥废旧回收中心 柳州市冠宝贸易有限公司 柳州市鑫盛德商务咨询有限责任公司 柳州市泰汇银通经贸有限公司 广西瀚维智测科技有限公司 柳州市钓鱼郎制衣有限责任公司 柳州溪水物资有限公司 柳州市融峰物资有限责任公司 广西新地科技有限责任公司 柳州市纺织装饰公司 柳州市粤翔冶金炉料有限公司 柳州市远腾贸易有限公司 柳州市东鸿城市改造有限公司 广西丛欣实业有限公司 柳州市服装厂 柳州市立安联合刀片有限公司 广西国扬投资有限责任公司 柳州市铭泰办公设备公司 柳州市桂钢物资供应站 柳州市昱升物资有限责任公司 柳州市鹰飞灿科贸有限公司 柳州市先导科贸有限公司 柳州市金秋建材物资经营部 柳州市童装厂 柳州市民泽物资有限公司 柳州市恒先物资贸易有限公司 柳州市银夏冷气工程有限责任公司 柳州粮食批发有限责任公司 柳州市金银华窗纱制造有限责任公司 柳州市三方贸易有限公司 柳州市丰涛商贸有限责任公司 柳州华智企业管理咨询有限责任公司 柳州市诚正建筑工程施工图审查有限公司 柳州市今科电讯设备营销中心 柳州市闽德电子有限公司 柳州市鑫虹针织厂 柳州市畅通通讯器材有限责任公司 柳州市正钢物资经营部 柳州市新柳饲料有限责任公司 柳州市黄村油库 柳州市天泰电力装饰工程有限公司 柳州市兆吉物资有限责任公司 柳州市八龙纸制品有限责任公司 柳州市巨佳电脑网络科技有限公司 ".match(/[^\s]+/g), function (i, v) { return { @@ -6864,5 +6828,7 @@ Demo.CONSTANTS = { value: v, title: v } - }) + }), + TREEITEMS: [{"pId":"0","id":"0_0","text":"( 共25个 )","value":"","open":true},{"pId":"0_0","id":"0_0_0","text":"安徽省( 共1个 )","value":"安徽省","open":true},{"pId":"0_0_0","id":"0_0_0_0","text":"芜湖市","value":"芜湖市","open":true},{"pId":"0_0","id":"0_0_1","text":"北京市( 共6个 )","value":"北京市","open":true},{"pId":"0_0_1","id":"0_0_1_0","text":"北京市区","value":"北京市区","open":true},{"pId":"0_0_1","id":"0_0_1_1","text":"朝阳区","value":"朝阳区","open":true},{"pId":"0_0_1","id":"0_0_1_2","text":"东城区","value":"东城区","open":true},{"pId":"0_0_1","id":"0_0_1_3","text":"海淀区4内","value":"海淀区4内","open":true},{"pId":"0_0_1","id":"0_0_1_4","text":"海淀区4外","value":"海淀区4外","open":true},{"pId":"0_0_1","id":"0_0_1_5","text":"石景山区","value":"石景山区","open":true},{"pId":"0_0","id":"0_0_2","text":"福建省( 共2个 )","value":"福建省","open":true},{"pId":"0_0_2","id":"0_0_2_0","text":"莆田市","value":"莆田市","open":true},{"pId":"0_0_2","id":"0_0_2_1","text":"泉州市","value":"泉州市","open":true},{"pId":"0_0","id":"0_0_3","text":"甘肃省( 共1个 )","value":"甘肃省","open":true},{"pId":"0_0_3","id":"0_0_3_0","text":"兰州市","value":"兰州市","open":true},{"pId":"0_0","id":"0_0_4","text":"广东省( 共5个 )","value":"广东省","open":true},{"pId":"0_0_4","id":"0_0_4_0","text":"东莞市","value":"东莞市","open":true},{"pId":"0_0_4","id":"0_0_4_1","text":"广州市","value":"广州市","open":true},{"pId":"0_0_4","id":"0_0_4_2","text":"惠州市","value":"惠州市","open":true},{"pId":"0_0_4","id":"0_0_4_3","text":"深圳市","value":"深圳市","open":true},{"pId":"0_0_4","id":"0_0_4_4","text":"珠海市","value":"珠海市","open":true},{"pId":"0_0","id":"0_0_5","text":"广西壮族自治区( 共1个 )","value":"广西壮族自治区","open":true},{"pId":"0_0_5","id":"0_0_5_0","text":"南宁市","value":"南宁市","open":true},{"pId":"0_0","id":"0_0_6","text":"河北省( 共2个 )","value":"河北省","open":true},{"pId":"0_0_6","id":"0_0_6_0","text":"保定市","value":"保定市","open":true},{"pId":"0_0_6","id":"0_0_6_1","text":"邢台市","value":"邢台市","open":true},{"pId":"0_0","id":"0_0_7","text":"河南省( 共1个 )","value":"河南省","open":true},{"pId":"0_0_7","id":"0_0_7_0","text":"郑州市","value":"郑州市","open":true},{"pId":"0_0","id":"0_0_8","text":"黑龙江省( 共7个 )","value":"黑龙江省","open":true},{"pId":"0_0_8","id":"0_0_8_0","text":"大庆市","value":"大庆市","open":true},{"pId":"0_0_8","id":"0_0_8_1","text":"哈尔滨市","value":"哈尔滨市","open":true},{"pId":"0_0_8","id":"0_0_8_2","text":"鸡西市","value":"鸡西市","open":true},{"pId":"0_0_8","id":"0_0_8_3","text":"佳木斯市","value":"佳木斯市","open":true},{"pId":"0_0_8","id":"0_0_8_4","text":"牡丹江市","value":"牡丹江市","open":true},{"pId":"0_0_8","id":"0_0_8_5","text":"齐齐哈尔市","value":"齐齐哈尔市","open":true},{"pId":"0_0_8","id":"0_0_8_6","text":"双鸭山市","value":"双鸭山市","open":true},{"pId":"0_0","id":"0_0_9","text":"湖北省( 共1个 )","value":"湖北省","open":true},{"pId":"0_0_9","id":"0_0_9_0","text":"武汉市","value":"武汉市","open":true},{"pId":"0_0","id":"0_0_10","text":"湖南省( 共3个 )","value":"湖南省","open":true},{"pId":"0_0_10","id":"0_0_10_0","text":"常德市","value":"常德市","open":true},{"pId":"0_0_10","id":"0_0_10_1","text":"长沙市","value":"长沙市","open":true},{"pId":"0_0_10","id":"0_0_10_2","text":"邵阳市","value":"邵阳市","open":true},{"pId":"0_0","id":"0_0_11","text":"吉林省( 共4个 )","value":"吉林省","open":true},{"pId":"0_0_11","id":"0_0_11_0","text":"白山市","value":"白山市","open":true},{"pId":"0_0_11","id":"0_0_11_1","text":"长春市","value":"长春市","open":true},{"pId":"0_0_11","id":"0_0_11_2","text":"松原市","value":"松原市","open":true},{"pId":"0_0_11","id":"0_0_11_3","text":"通化市","value":"通化市","open":true},{"pId":"0_0","id":"0_0_12","text":"江苏省( 共8个 )","value":"江苏省","open":true},{"pId":"0_0_12","id":"0_0_12_0","text":"常州市","value":"常州市","open":true},{"pId":"0_0_12","id":"0_0_12_1","text":"南京市","value":"南京市","open":true},{"pId":"0_0_12","id":"0_0_12_2","text":"南通市","value":"南通市","open":true},{"pId":"0_0_12","id":"0_0_12_3","text":"苏州市","value":"苏州市","open":true},{"pId":"0_0_12","id":"0_0_12_4","text":"宿迁市","value":"宿迁市","open":true},{"pId":"0_0_12","id":"0_0_12_5","text":"泰州市","value":"泰州市","open":true},{"pId":"0_0_12","id":"0_0_12_6","text":"无锡市","value":"无锡市","open":true},{"pId":"0_0_12","id":"0_0_12_7","text":"盐城市","value":"盐城市","open":true},{"pId":"0_0","id":"0_0_13","text":"辽宁省( 共11个 )","value":"辽宁省","open":true},{"pId":"0_0_13","id":"0_0_13_0","text":"鞍山市","value":"鞍山市","open":true},{"pId":"0_0_13","id":"0_0_13_1","text":"本溪市","value":"本溪市","open":true},{"pId":"0_0_13","id":"0_0_13_2","text":"朝阳市","value":"朝阳市","open":true},{"pId":"0_0_13","id":"0_0_13_3","text":"大连市","value":"大连市","open":true},{"pId":"0_0_13","id":"0_0_13_4","text":"抚顺市","value":"抚顺市","open":true},{"pId":"0_0_13","id":"0_0_13_5","text":"葫芦岛市","value":"葫芦岛市","open":true},{"pId":"0_0_13","id":"0_0_13_6","text":"锦州市","value":"锦州市","open":true},{"pId":"0_0_13","id":"0_0_13_7","text":"辽阳市","value":"辽阳市","open":true},{"pId":"0_0_13","id":"0_0_13_8","text":"盘锦市","value":"盘锦市","open":true},{"pId":"0_0_13","id":"0_0_13_9","text":"沈阳市","value":"沈阳市","open":true},{"pId":"0_0_13","id":"0_0_13_10","text":"营口市","value":"营口市","open":true},{"pId":"0_0","id":"0_0_14","text":"内蒙古( 共1个 )","value":"内蒙古","open":true},{"pId":"0_0_14","id":"0_0_14_0","text":"鄂尔多斯市","value":"鄂尔多斯市","open":true},{"pId":"0_0","id":"0_0_15","text":"宁夏回族自治区( 共1个 )","value":"宁夏回族自治区","open":true},{"pId":"0_0_15","id":"0_0_15_0","text":"银川市","value":"银川市","open":true},{"pId":"0_0","id":"0_0_16","text":"山东省( 共7个 )","value":"山东省","open":true},{"pId":"0_0_16","id":"0_0_16_0","text":"济南市","value":"济南市","open":true},{"pId":"0_0_16","id":"0_0_16_1","text":"济宁市","value":"济宁市","open":true},{"pId":"0_0_16","id":"0_0_16_2","text":"聊城市","value":"聊城市","open":true},{"pId":"0_0_16","id":"0_0_16_3","text":"临沂市","value":"临沂市","open":true},{"pId":"0_0_16","id":"0_0_16_4","text":"青岛市","value":"青岛市","open":true},{"pId":"0_0_16","id":"0_0_16_5","text":"烟台市","value":"烟台市","open":true},{"pId":"0_0_16","id":"0_0_16_6","text":"枣庄市","value":"枣庄市","open":true},{"pId":"0_0","id":"0_0_17","text":"山西省( 共1个 )","value":"山西省","open":true},{"pId":"0_0_17","id":"0_0_17_0","text":"太原市","value":"太原市","open":true},{"pId":"0_0","id":"0_0_18","text":"陕西省( 共1个 )","value":"陕西省","open":true},{"pId":"0_0_18","id":"0_0_18_0","text":"西安市","value":"西安市","open":true},{"pId":"0_0","id":"0_0_19","text":"上海市( 共1个 )","value":"上海市","open":true},{"pId":"0_0_19","id":"0_0_19_0","text":"上海市区","value":"上海市区","open":true},{"pId":"0_0","id":"0_0_20","text":"四川省( 共1个 )","value":"四川省","open":true},{"pId":"0_0_20","id":"0_0_20_0","text":"成都市","value":"成都市","open":true},{"pId":"0_0","id":"0_0_21","text":"新疆维吾尔族自治区( 共2个 )","value":"新疆维吾尔族自治区","open":true},{"pId":"0_0_21","id":"0_0_21_0","text":"吐鲁番地区","value":"吐鲁番地区","open":true},{"pId":"0_0_21","id":"0_0_21_1","text":"乌鲁木齐","value":"乌鲁木齐","open":true},{"pId":"0_0","id":"0_0_22","text":"云南省( 共1个 )","value":"云南省","open":true},{"pId":"0_0_22","id":"0_0_22_0","text":"昆明市","value":"昆明市","open":true},{"pId":"0_0","id":"0_0_23","text":"浙江省( 共5个 )","value":"浙江省","open":true},{"pId":"0_0_23","id":"0_0_23_0","text":"杭州市","value":"杭州市","open":true},{"pId":"0_0_23","id":"0_0_23_1","text":"湖州市","value":"湖州市","open":true},{"pId":"0_0_23","id":"0_0_23_2","text":"嘉兴市","value":"嘉兴市","open":true},{"pId":"0_0_23","id":"0_0_23_3","text":"宁波市","value":"宁波市","open":true},{"pId":"0_0_23","id":"0_0_23_4","text":"绍兴市","value":"绍兴市","open":true},{"pId":"0_0","id":"0_0_24","text":"重庆市( 共1个 )","value":"重庆市","open":true},{"pId":"0_0_24","id":"0_0_24_0","text":"重庆市区","value":"重庆市区","open":true},{"pId":"0","id":"0_1","text":"中国( 共34个 )","value":"中国","open":true},{"pId":"0_1","id":"0_1_0","text":"安徽省( 共19个 )","value":"安徽省","open":true},{"pId":"0_1_0","id":"0_1_0_0","text":"安庆市","value":"安庆市","open":true},{"pId":"0_1_0","id":"0_1_0_1","text":"蚌埠市","value":"蚌埠市","open":true},{"pId":"0_1_0","id":"0_1_0_2","text":"亳州市","value":"亳州市","open":true},{"pId":"0_1_0","id":"0_1_0_3","text":"巢湖市","value":"巢湖市","open":true},{"pId":"0_1_0","id":"0_1_0_4","text":"池州市","value":"池州市","open":true},{"pId":"0_1_0","id":"0_1_0_5","text":"滁州市","value":"滁州市","open":true},{"pId":"0_1_0","id":"0_1_0_6","text":"阜阳市","value":"阜阳市","open":true},{"pId":"0_1_0","id":"0_1_0_7","text":"毫州市","value":"毫州市","open":true},{"pId":"0_1_0","id":"0_1_0_8","text":"合肥市","value":"合肥市","open":true},{"pId":"0_1_0","id":"0_1_0_9","text":"淮北市","value":"淮北市","open":true},{"pId":"0_1_0","id":"0_1_0_10","text":"淮南市","value":"淮南市","open":true},{"pId":"0_1_0","id":"0_1_0_11","text":"黄山市","value":"黄山市","open":true},{"pId":"0_1_0","id":"0_1_0_12","text":"六安市","value":"六安市","open":true},{"pId":"0_1_0","id":"0_1_0_13","text":"马鞍山市","value":"马鞍山市","open":true},{"pId":"0_1_0","id":"0_1_0_14","text":"濮阳市","value":"濮阳市","open":true},{"pId":"0_1_0","id":"0_1_0_15","text":"宿州市","value":"宿州市","open":true},{"pId":"0_1_0","id":"0_1_0_16","text":"铜陵市","value":"铜陵市","open":true},{"pId":"0_1_0","id":"0_1_0_17","text":"芜湖市","value":"芜湖市","open":true},{"pId":"0_1_0","id":"0_1_0_18","text":"宣城市","value":"宣城市","open":true},{"pId":"0_1","id":"0_1_1","text":"澳门特别行政区( 共1个 )","value":"澳门特别行政区","open":true},{"pId":"0_1_1","id":"0_1_1_0","text":"澳门","value":"澳门","open":true},{"pId":"0_1","id":"0_1_2","text":"北京市( 共17个 )","value":"北京市","open":true},{"pId":"0_1_2","id":"0_1_2_0","text":"北京市区","value":"北京市区","open":true},{"pId":"0_1_2","id":"0_1_2_1","text":"昌平区","value":"昌平区","open":true},{"pId":"0_1_2","id":"0_1_2_2","text":"朝阳区","value":"朝阳区","open":true},{"pId":"0_1_2","id":"0_1_2_3","text":"大兴区","value":"大兴区","open":true},{"pId":"0_1_2","id":"0_1_2_4","text":"东城区","value":"东城区","open":true},{"pId":"0_1_2","id":"0_1_2_5","text":"房山区","value":"房山区","open":true},{"pId":"0_1_2","id":"0_1_2_6","text":"丰台区","value":"丰台区","open":true},{"pId":"0_1_2","id":"0_1_2_7","text":"海淀区","value":"海淀区","open":true},{"pId":"0_1_2","id":"0_1_2_8","text":"海淀区4内","value":"海淀区4内","open":true},{"pId":"0_1_2","id":"0_1_2_9","text":"海淀区4外","value":"海淀区4外","open":true},{"pId":"0_1_2","id":"0_1_2_10","text":"门头沟区","value":"门头沟区","open":true},{"pId":"0_1_2","id":"0_1_2_11","text":"平谷区","value":"平谷区","open":true},{"pId":"0_1_2","id":"0_1_2_12","text":"石景山区","value":"石景山区","open":true},{"pId":"0_1_2","id":"0_1_2_13","text":"顺义区","value":"顺义区","open":true},{"pId":"0_1_2","id":"0_1_2_14","text":"通州区","value":"通州区","open":true},{"pId":"0_1_2","id":"0_1_2_15","text":"西城区","value":"西城区","open":true},{"pId":"0_1_2","id":"0_1_2_16","text":"西城区 ","value":"西城区 ","open":true},{"pId":"0_1","id":"0_1_3","text":"福建省( 共9个 )","value":"福建省","open":true},{"pId":"0_1_3","id":"0_1_3_0","text":"福州市","value":"福州市","open":true},{"pId":"0_1_3","id":"0_1_3_1","text":"龙岩市","value":"龙岩市","open":true},{"pId":"0_1_3","id":"0_1_3_2","text":"南平市","value":"南平市","open":true},{"pId":"0_1_3","id":"0_1_3_3","text":"宁德市","value":"宁德市","open":true},{"pId":"0_1_3","id":"0_1_3_4","text":"莆田市","value":"莆田市","open":true},{"pId":"0_1_3","id":"0_1_3_5","text":"泉州市","value":"泉州市","open":true},{"pId":"0_1_3","id":"0_1_3_6","text":"三明市","value":"三明市","open":true},{"pId":"0_1_3","id":"0_1_3_7","text":"厦门市","value":"厦门市","open":true},{"pId":"0_1_3","id":"0_1_3_8","text":"漳州市","value":"漳州市","open":true},{"pId":"0_1","id":"0_1_4","text":"甘肃省( 共12个 )","value":"甘肃省","open":true},{"pId":"0_1_4","id":"0_1_4_0","text":"白银市","value":"白银市","open":true},{"pId":"0_1_4","id":"0_1_4_1","text":"嘉峪关市","value":"嘉峪关市","open":true},{"pId":"0_1_4","id":"0_1_4_2","text":"金昌市","value":"金昌市","open":true},{"pId":"0_1_4","id":"0_1_4_3","text":"酒泉市","value":"酒泉市","open":true},{"pId":"0_1_4","id":"0_1_4_4","text":"兰州市","value":"兰州市","open":true},{"pId":"0_1_4","id":"0_1_4_5","text":"陇南市","value":"陇南市","open":true},{"pId":"0_1_4","id":"0_1_4_6","text":"平凉市","value":"平凉市","open":true},{"pId":"0_1_4","id":"0_1_4_7","text":"庆阳市","value":"庆阳市","open":true},{"pId":"0_1_4","id":"0_1_4_8","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1_4","id":"0_1_4_9","text":"天水市","value":"天水市","open":true},{"pId":"0_1_4","id":"0_1_4_10","text":"武威市","value":"武威市","open":true},{"pId":"0_1_4","id":"0_1_4_11","text":"张掖市","value":"张掖市","open":true},{"pId":"0_1","id":"0_1_5","text":"广东省( 共21个 )","value":"广东省","open":true},{"pId":"0_1_5","id":"0_1_5_0","text":"潮州市","value":"潮州市","open":true},{"pId":"0_1_5","id":"0_1_5_1","text":"东莞市","value":"东莞市","open":true},{"pId":"0_1_5","id":"0_1_5_2","text":"佛山市","value":"佛山市","open":true},{"pId":"0_1_5","id":"0_1_5_3","text":"广州市","value":"广州市","open":true},{"pId":"0_1_5","id":"0_1_5_4","text":"河源市","value":"河源市","open":true},{"pId":"0_1_5","id":"0_1_5_5","text":"惠州市","value":"惠州市","open":true},{"pId":"0_1_5","id":"0_1_5_6","text":"江门市","value":"江门市","open":true},{"pId":"0_1_5","id":"0_1_5_7","text":"揭阳市","value":"揭阳市","open":true},{"pId":"0_1_5","id":"0_1_5_8","text":"茂名市","value":"茂名市","open":true},{"pId":"0_1_5","id":"0_1_5_9","text":"梅州市","value":"梅州市","open":true},{"pId":"0_1_5","id":"0_1_5_10","text":"清远市","value":"清远市","open":true},{"pId":"0_1_5","id":"0_1_5_11","text":"汕头市","value":"汕头市","open":true},{"pId":"0_1_5","id":"0_1_5_12","text":"汕尾市","value":"汕尾市","open":true},{"pId":"0_1_5","id":"0_1_5_13","text":"韶关市","value":"韶关市","open":true},{"pId":"0_1_5","id":"0_1_5_14","text":"深圳市","value":"深圳市","open":true},{"pId":"0_1_5","id":"0_1_5_15","text":"阳江市","value":"阳江市","open":true},{"pId":"0_1_5","id":"0_1_5_16","text":"云浮市","value":"云浮市","open":true},{"pId":"0_1_5","id":"0_1_5_17","text":"湛江市","value":"湛江市","open":true},{"pId":"0_1_5","id":"0_1_5_18","text":"肇庆市","value":"肇庆市","open":true},{"pId":"0_1_5","id":"0_1_5_19","text":"中山市","value":"中山市","open":true},{"pId":"0_1_5","id":"0_1_5_20","text":"珠海市","value":"珠海市","open":true},{"pId":"0_1","id":"0_1_6","text":"广西壮族自治区( 共14个 )","value":"广西壮族自治区","open":true},{"pId":"0_1_6","id":"0_1_6_0","text":"百色市","value":"百色市","open":true},{"pId":"0_1_6","id":"0_1_6_1","text":"北海市","value":"北海市","open":true},{"pId":"0_1_6","id":"0_1_6_2","text":"崇左市","value":"崇左市","open":true},{"pId":"0_1_6","id":"0_1_6_3","text":"防城港市","value":"防城港市","open":true},{"pId":"0_1_6","id":"0_1_6_4","text":"桂林市","value":"桂林市","open":true},{"pId":"0_1_6","id":"0_1_6_5","text":"贵港市","value":"贵港市","open":true},{"pId":"0_1_6","id":"0_1_6_6","text":"河池市","value":"河池市","open":true},{"pId":"0_1_6","id":"0_1_6_7","text":"贺州市","value":"贺州市","open":true},{"pId":"0_1_6","id":"0_1_6_8","text":"来宾市","value":"来宾市","open":true},{"pId":"0_1_6","id":"0_1_6_9","text":"柳州市","value":"柳州市","open":true},{"pId":"0_1_6","id":"0_1_6_10","text":"南宁市","value":"南宁市","open":true},{"pId":"0_1_6","id":"0_1_6_11","text":"钦州市","value":"钦州市","open":true},{"pId":"0_1_6","id":"0_1_6_12","text":"梧州市","value":"梧州市","open":true},{"pId":"0_1_6","id":"0_1_6_13","text":"玉林市","value":"玉林市","open":true},{"pId":"0_1","id":"0_1_7","text":"贵州省( 共9个 )","value":"贵州省","open":true},{"pId":"0_1_7","id":"0_1_7_0","text":"安顺市","value":"安顺市","open":true},{"pId":"0_1_7","id":"0_1_7_1","text":"毕节地区","value":"毕节地区","open":true},{"pId":"0_1_7","id":"0_1_7_2","text":"贵阳市","value":"贵阳市","open":true},{"pId":"0_1_7","id":"0_1_7_3","text":"六盘水市","value":"六盘水市","open":true},{"pId":"0_1_7","id":"0_1_7_4","text":"黔东南州","value":"黔东南州","open":true},{"pId":"0_1_7","id":"0_1_7_5","text":"黔南州","value":"黔南州","open":true},{"pId":"0_1_7","id":"0_1_7_6","text":"黔西南市","value":"黔西南市","open":true},{"pId":"0_1_7","id":"0_1_7_7","text":"铜仁地区","value":"铜仁地区","open":true},{"pId":"0_1_7","id":"0_1_7_8","text":"遵义市","value":"遵义市","open":true},{"pId":"0_1","id":"0_1_8","text":"海南省( 共2个 )","value":"海南省","open":true},{"pId":"0_1_8","id":"0_1_8_0","text":"海口市","value":"海口市","open":true},{"pId":"0_1_8","id":"0_1_8_1","text":"三亚市","value":"三亚市","open":true},{"pId":"0_1","id":"0_1_9","text":"河北省( 共12个 )","value":"河北省","open":true},{"pId":"0_1_9","id":"0_1_9_0","text":"保定市","value":"保定市","open":true},{"pId":"0_1_9","id":"0_1_9_1","text":"沧州市","value":"沧州市","open":true},{"pId":"0_1_9","id":"0_1_9_2","text":"承德市","value":"承德市","open":true},{"pId":"0_1_9","id":"0_1_9_3","text":"邯郸市","value":"邯郸市","open":true},{"pId":"0_1_9","id":"0_1_9_4","text":"衡水市","value":"衡水市","open":true},{"pId":"0_1_9","id":"0_1_9_5","text":"廊坊市","value":"廊坊市","open":true},{"pId":"0_1_9","id":"0_1_9_6","text":"秦皇岛市","value":"秦皇岛市","open":true},{"pId":"0_1_9","id":"0_1_9_7","text":"石家庄市","value":"石家庄市","open":true},{"pId":"0_1_9","id":"0_1_9_8","text":"唐山市","value":"唐山市","open":true},{"pId":"0_1_9","id":"0_1_9_9","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1_9","id":"0_1_9_10","text":"邢台市","value":"邢台市","open":true},{"pId":"0_1_9","id":"0_1_9_11","text":"张家口市","value":"张家口市","open":true},{"pId":"0_1","id":"0_1_10","text":"河南省( 共19个 )","value":"河南省","open":true},{"pId":"0_1_10","id":"0_1_10_0","text":"安阳市","value":"安阳市","open":true},{"pId":"0_1_10","id":"0_1_10_1","text":"鹤壁市","value":"鹤壁市","open":true},{"pId":"0_1_10","id":"0_1_10_2","text":"济源市","value":"济源市","open":true},{"pId":"0_1_10","id":"0_1_10_3","text":"焦作市","value":"焦作市","open":true},{"pId":"0_1_10","id":"0_1_10_4","text":"开封市","value":"开封市","open":true},{"pId":"0_1_10","id":"0_1_10_5","text":"廊坊市","value":"廊坊市","open":true},{"pId":"0_1_10","id":"0_1_10_6","text":"洛阳市","value":"洛阳市","open":true},{"pId":"0_1_10","id":"0_1_10_7","text":"漯河市","value":"漯河市","open":true},{"pId":"0_1_10","id":"0_1_10_8","text":"南阳市","value":"南阳市","open":true},{"pId":"0_1_10","id":"0_1_10_9","text":"平顶山市","value":"平顶山市","open":true},{"pId":"0_1_10","id":"0_1_10_10","text":"濮阳市","value":"濮阳市","open":true},{"pId":"0_1_10","id":"0_1_10_11","text":"三门峡市","value":"三门峡市","open":true},{"pId":"0_1_10","id":"0_1_10_12","text":"商丘市","value":"商丘市","open":true},{"pId":"0_1_10","id":"0_1_10_13","text":"新乡市","value":"新乡市","open":true},{"pId":"0_1_10","id":"0_1_10_14","text":"信阳市","value":"信阳市","open":true},{"pId":"0_1_10","id":"0_1_10_15","text":"许昌市","value":"许昌市","open":true},{"pId":"0_1_10","id":"0_1_10_16","text":"郑州市","value":"郑州市","open":true},{"pId":"0_1_10","id":"0_1_10_17","text":"周口市","value":"周口市","open":true},{"pId":"0_1_10","id":"0_1_10_18","text":"驻马店市","value":"驻马店市","open":true},{"pId":"0_1","id":"0_1_11","text":"黑龙江省( 共13个 )","value":"黑龙江省","open":true},{"pId":"0_1_11","id":"0_1_11_0","text":"大庆市","value":"大庆市","open":true},{"pId":"0_1_11","id":"0_1_11_1","text":"大兴安岭地区","value":"大兴安岭地区","open":true},{"pId":"0_1_11","id":"0_1_11_2","text":"大兴安岭市","value":"大兴安岭市","open":true},{"pId":"0_1_11","id":"0_1_11_3","text":"哈尔滨市","value":"哈尔滨市","open":true},{"pId":"0_1_11","id":"0_1_11_4","text":"鹤港市","value":"鹤港市","open":true},{"pId":"0_1_11","id":"0_1_11_5","text":"黑河市","value":"黑河市","open":true},{"pId":"0_1_11","id":"0_1_11_6","text":"佳木斯市","value":"佳木斯市","open":true},{"pId":"0_1_11","id":"0_1_11_7","text":"牡丹江市","value":"牡丹江市","open":true},{"pId":"0_1_11","id":"0_1_11_8","text":"七台河市","value":"七台河市","open":true},{"pId":"0_1_11","id":"0_1_11_9","text":"齐齐哈尔市","value":"齐齐哈尔市","open":true},{"pId":"0_1_11","id":"0_1_11_10","text":"双鸭山市","value":"双鸭山市","open":true},{"pId":"0_1_11","id":"0_1_11_11","text":"绥化市","value":"绥化市","open":true},{"pId":"0_1_11","id":"0_1_11_12","text":"伊春市","value":"伊春市","open":true},{"pId":"0_1","id":"0_1_12","text":"湖北省( 共16个 )","value":"湖北省","open":true},{"pId":"0_1_12","id":"0_1_12_0","text":"鄂州市","value":"鄂州市","open":true},{"pId":"0_1_12","id":"0_1_12_1","text":"恩施土家族苗族自治州","value":"恩施土家族苗族自治州","open":true},{"pId":"0_1_12","id":"0_1_12_2","text":"黄冈市","value":"黄冈市","open":true},{"pId":"0_1_12","id":"0_1_12_3","text":"黄石市","value":"黄石市","open":true},{"pId":"0_1_12","id":"0_1_12_4","text":"荆门市","value":"荆门市","open":true},{"pId":"0_1_12","id":"0_1_12_5","text":"荆州市","value":"荆州市","open":true},{"pId":"0_1_12","id":"0_1_12_6","text":"神农架市","value":"神农架市","open":true},{"pId":"0_1_12","id":"0_1_12_7","text":"十堰市","value":"十堰市","open":true},{"pId":"0_1_12","id":"0_1_12_8","text":"随州市","value":"随州市","open":true},{"pId":"0_1_12","id":"0_1_12_9","text":"天门市","value":"天门市","open":true},{"pId":"0_1_12","id":"0_1_12_10","text":"武汉市","value":"武汉市","open":true},{"pId":"0_1_12","id":"0_1_12_11","text":"咸宁市","value":"咸宁市","open":true},{"pId":"0_1_12","id":"0_1_12_12","text":"襄樊市","value":"襄樊市","open":true},{"pId":"0_1_12","id":"0_1_12_13","text":"襄阳市","value":"襄阳市","open":true},{"pId":"0_1_12","id":"0_1_12_14","text":"孝感市","value":"孝感市","open":true},{"pId":"0_1_12","id":"0_1_12_15","text":"宜昌市","value":"宜昌市","open":true},{"pId":"0_1","id":"0_1_13","text":"湖南省( 共15个 )","value":"湖南省","open":true},{"pId":"0_1_13","id":"0_1_13_0","text":"常德市","value":"常德市","open":true},{"pId":"0_1_13","id":"0_1_13_1","text":"长沙市","value":"长沙市","open":true},{"pId":"0_1_13","id":"0_1_13_2","text":"郴州市","value":"郴州市","open":true},{"pId":"0_1_13","id":"0_1_13_3","text":"衡阳市","value":"衡阳市","open":true},{"pId":"0_1_13","id":"0_1_13_4","text":"怀化市","value":"怀化市","open":true},{"pId":"0_1_13","id":"0_1_13_5","text":"娄底市","value":"娄底市","open":true},{"pId":"0_1_13","id":"0_1_13_6","text":"邵阳市","value":"邵阳市","open":true},{"pId":"0_1_13","id":"0_1_13_7","text":"湘潭市","value":"湘潭市","open":true},{"pId":"0_1_13","id":"0_1_13_8","text":"湘西市","value":"湘西市","open":true},{"pId":"0_1_13","id":"0_1_13_9","text":"湘西土家族苗族自治州","value":"湘西土家族苗族自治州","open":true},{"pId":"0_1_13","id":"0_1_13_10","text":"益阳市","value":"益阳市","open":true},{"pId":"0_1_13","id":"0_1_13_11","text":"永州市","value":"永州市","open":true},{"pId":"0_1_13","id":"0_1_13_12","text":"岳阳市","value":"岳阳市","open":true},{"pId":"0_1_13","id":"0_1_13_13","text":"张家界市","value":"张家界市","open":true},{"pId":"0_1_13","id":"0_1_13_14","text":"株洲市","value":"株洲市","open":true},{"pId":"0_1","id":"0_1_14","text":"吉林省( 共10个 )","value":"吉林省","open":true},{"pId":"0_1_14","id":"0_1_14_0","text":"白城市","value":"白城市","open":true},{"pId":"0_1_14","id":"0_1_14_1","text":"白山市","value":"白山市","open":true},{"pId":"0_1_14","id":"0_1_14_2","text":"长春市","value":"长春市","open":true},{"pId":"0_1_14","id":"0_1_14_3","text":"大庆市","value":"大庆市","open":true},{"pId":"0_1_14","id":"0_1_14_4","text":"吉林市","value":"吉林市","open":true},{"pId":"0_1_14","id":"0_1_14_5","text":"辽源市","value":"辽源市","open":true},{"pId":"0_1_14","id":"0_1_14_6","text":"四平市","value":"四平市","open":true},{"pId":"0_1_14","id":"0_1_14_7","text":"松原市","value":"松原市","open":true},{"pId":"0_1_14","id":"0_1_14_8","text":"通化市","value":"通化市","open":true},{"pId":"0_1_14","id":"0_1_14_9","text":"延边朝鲜族自治州","value":"延边朝鲜族自治州","open":true},{"pId":"0_1","id":"0_1_15","text":"江苏省( 共13个 )","value":"江苏省","open":true},{"pId":"0_1_15","id":"0_1_15_0","text":"常州市","value":"常州市","open":true},{"pId":"0_1_15","id":"0_1_15_1","text":"淮安市","value":"淮安市","open":true},{"pId":"0_1_15","id":"0_1_15_2","text":"连云港市","value":"连云港市","open":true},{"pId":"0_1_15","id":"0_1_15_3","text":"南京市","value":"南京市","open":true},{"pId":"0_1_15","id":"0_1_15_4","text":"南通市","value":"南通市","open":true},{"pId":"0_1_15","id":"0_1_15_5","text":"苏州市","value":"苏州市","open":true},{"pId":"0_1_15","id":"0_1_15_6","text":"宿迁市","value":"宿迁市","open":true},{"pId":"0_1_15","id":"0_1_15_7","text":"泰州市","value":"泰州市","open":true},{"pId":"0_1_15","id":"0_1_15_8","text":"无锡市","value":"无锡市","open":true},{"pId":"0_1_15","id":"0_1_15_9","text":"徐州市","value":"徐州市","open":true},{"pId":"0_1_15","id":"0_1_15_10","text":"盐城市","value":"盐城市","open":true},{"pId":"0_1_15","id":"0_1_15_11","text":"扬州市","value":"扬州市","open":true},{"pId":"0_1_15","id":"0_1_15_12","text":"镇江市","value":"镇江市","open":true},{"pId":"0_1","id":"0_1_16","text":"江西省( 共10个 )","value":"江西省","open":true},{"pId":"0_1_16","id":"0_1_16_0","text":"抚州市","value":"抚州市","open":true},{"pId":"0_1_16","id":"0_1_16_1","text":"赣州市","value":"赣州市","open":true},{"pId":"0_1_16","id":"0_1_16_2","text":"景德镇市","value":"景德镇市","open":true},{"pId":"0_1_16","id":"0_1_16_3","text":"九江市","value":"九江市","open":true},{"pId":"0_1_16","id":"0_1_16_4","text":"南昌市","value":"南昌市","open":true},{"pId":"0_1_16","id":"0_1_16_5","text":"萍乡市","value":"萍乡市","open":true},{"pId":"0_1_16","id":"0_1_16_6","text":"上饶市","value":"上饶市","open":true},{"pId":"0_1_16","id":"0_1_16_7","text":"新余市","value":"新余市","open":true},{"pId":"0_1_16","id":"0_1_16_8","text":"宜春市","value":"宜春市","open":true},{"pId":"0_1_16","id":"0_1_16_9","text":"鹰潭市","value":"鹰潭市","open":true},{"pId":"0_1","id":"0_1_17","text":"辽宁省( 共14个 )","value":"辽宁省","open":true},{"pId":"0_1_17","id":"0_1_17_0","text":"鞍山市","value":"鞍山市","open":true},{"pId":"0_1_17","id":"0_1_17_1","text":"本溪市","value":"本溪市","open":true},{"pId":"0_1_17","id":"0_1_17_2","text":"朝阳市","value":"朝阳市","open":true},{"pId":"0_1_17","id":"0_1_17_3","text":"大连市","value":"大连市","open":true},{"pId":"0_1_17","id":"0_1_17_4","text":"丹东市","value":"丹东市","open":true},{"pId":"0_1_17","id":"0_1_17_5","text":"抚顺市","value":"抚顺市","open":true},{"pId":"0_1_17","id":"0_1_17_6","text":"阜新市","value":"阜新市","open":true},{"pId":"0_1_17","id":"0_1_17_7","text":"葫芦岛市","value":"葫芦岛市","open":true},{"pId":"0_1_17","id":"0_1_17_8","text":"锦州市","value":"锦州市","open":true},{"pId":"0_1_17","id":"0_1_17_9","text":"辽阳市","value":"辽阳市","open":true},{"pId":"0_1_17","id":"0_1_17_10","text":"盘锦市","value":"盘锦市","open":true},{"pId":"0_1_17","id":"0_1_17_11","text":"沈阳市","value":"沈阳市","open":true},{"pId":"0_1_17","id":"0_1_17_12","text":"铁岭市","value":"铁岭市","open":true},{"pId":"0_1_17","id":"0_1_17_13","text":"营口市","value":"营口市","open":true},{"pId":"0_1","id":"0_1_18","text":"内蒙古( 共10个 )","value":"内蒙古","open":true},{"pId":"0_1_18","id":"0_1_18_0","text":"包头市","value":"包头市","open":true},{"pId":"0_1_18","id":"0_1_18_1","text":"赤峰市","value":"赤峰市","open":true},{"pId":"0_1_18","id":"0_1_18_2","text":"鄂尔多斯市","value":"鄂尔多斯市","open":true},{"pId":"0_1_18","id":"0_1_18_3","text":"呼和浩特市","value":"呼和浩特市","open":true},{"pId":"0_1_18","id":"0_1_18_4","text":"呼伦贝尔市","value":"呼伦贝尔市","open":true},{"pId":"0_1_18","id":"0_1_18_5","text":"通辽市","value":"通辽市","open":true},{"pId":"0_1_18","id":"0_1_18_6","text":"乌海市","value":"乌海市","open":true},{"pId":"0_1_18","id":"0_1_18_7","text":"锡林郭勒市","value":"锡林郭勒市","open":true},{"pId":"0_1_18","id":"0_1_18_8","text":"兴安市","value":"兴安市","open":true},{"pId":"0_1_18","id":"0_1_18_9","text":"运城市","value":"运城市","open":true},{"pId":"0_1","id":"0_1_19","text":"宁夏回族自治区( 共5个 )","value":"宁夏回族自治区","open":true},{"pId":"0_1_19","id":"0_1_19_0","text":"固原市","value":"固原市","open":true},{"pId":"0_1_19","id":"0_1_19_1","text":"石嘴山市","value":"石嘴山市","open":true},{"pId":"0_1_19","id":"0_1_19_2","text":"吴忠市","value":"吴忠市","open":true},{"pId":"0_1_19","id":"0_1_19_3","text":"银川市","value":"银川市","open":true},{"pId":"0_1_19","id":"0_1_19_4","text":"中卫市","value":"中卫市","open":true},{"pId":"0_1","id":"0_1_20","text":"青海省( 共4个 )","value":"青海省","open":true},{"pId":"0_1_20","id":"0_1_20_0","text":"海东地区","value":"海东地区","open":true},{"pId":"0_1_20","id":"0_1_20_1","text":"海南藏族自治州","value":"海南藏族自治州","open":true},{"pId":"0_1_20","id":"0_1_20_2","text":"海西蒙古族藏族自治州","value":"海西蒙古族藏族自治州","open":true},{"pId":"0_1_20","id":"0_1_20_3","text":"西宁市","value":"西宁市","open":true},{"pId":"0_1","id":"0_1_21","text":"山东省( 共17个 )","value":"山东省","open":true},{"pId":"0_1_21","id":"0_1_21_0","text":"滨州市","value":"滨州市","open":true},{"pId":"0_1_21","id":"0_1_21_1","text":"德州市","value":"德州市","open":true},{"pId":"0_1_21","id":"0_1_21_2","text":"东营市","value":"东营市","open":true},{"pId":"0_1_21","id":"0_1_21_3","text":"菏泽市","value":"菏泽市","open":true},{"pId":"0_1_21","id":"0_1_21_4","text":"济南市","value":"济南市","open":true},{"pId":"0_1_21","id":"0_1_21_5","text":"济宁市","value":"济宁市","open":true},{"pId":"0_1_21","id":"0_1_21_6","text":"莱芜市","value":"莱芜市","open":true},{"pId":"0_1_21","id":"0_1_21_7","text":"聊城市","value":"聊城市","open":true},{"pId":"0_1_21","id":"0_1_21_8","text":"临沂市","value":"临沂市","open":true},{"pId":"0_1_21","id":"0_1_21_9","text":"青岛市","value":"青岛市","open":true},{"pId":"0_1_21","id":"0_1_21_10","text":"日照市","value":"日照市","open":true},{"pId":"0_1_21","id":"0_1_21_11","text":"泰安市","value":"泰安市","open":true},{"pId":"0_1_21","id":"0_1_21_12","text":"威海市","value":"威海市","open":true},{"pId":"0_1_21","id":"0_1_21_13","text":"潍坊市","value":"潍坊市","open":true},{"pId":"0_1_21","id":"0_1_21_14","text":"烟台市","value":"烟台市","open":true},{"pId":"0_1_21","id":"0_1_21_15","text":"枣庄市","value":"枣庄市","open":true},{"pId":"0_1_21","id":"0_1_21_16","text":"淄博市","value":"淄博市","open":true},{"pId":"0_1","id":"0_1_22","text":"山西省( 共12个 )","value":"山西省","open":true},{"pId":"0_1_22","id":"0_1_22_0","text":"长治市","value":"长治市","open":true},{"pId":"0_1_22","id":"0_1_22_1","text":"大同市","value":"大同市","open":true},{"pId":"0_1_22","id":"0_1_22_2","text":"晋城市","value":"晋城市","open":true},{"pId":"0_1_22","id":"0_1_22_3","text":"晋中市","value":"晋中市","open":true},{"pId":"0_1_22","id":"0_1_22_4","text":"临汾市","value":"临汾市","open":true},{"pId":"0_1_22","id":"0_1_22_5","text":"吕梁市","value":"吕梁市","open":true},{"pId":"0_1_22","id":"0_1_22_6","text":"青岛市","value":"青岛市","open":true},{"pId":"0_1_22","id":"0_1_22_7","text":"朔州市","value":"朔州市","open":true},{"pId":"0_1_22","id":"0_1_22_8","text":"太原市","value":"太原市","open":true},{"pId":"0_1_22","id":"0_1_22_9","text":"忻州市","value":"忻州市","open":true},{"pId":"0_1_22","id":"0_1_22_10","text":"阳泉市","value":"阳泉市","open":true},{"pId":"0_1_22","id":"0_1_22_11","text":"运城市","value":"运城市","open":true},{"pId":"0_1","id":"0_1_23","text":"陕西省( 共9个 )","value":"陕西省","open":true},{"pId":"0_1_23","id":"0_1_23_0","text":"安康市","value":"安康市","open":true},{"pId":"0_1_23","id":"0_1_23_1","text":"宝鸡市","value":"宝鸡市","open":true},{"pId":"0_1_23","id":"0_1_23_2","text":"汉中市","value":"汉中市","open":true},{"pId":"0_1_23","id":"0_1_23_3","text":"商洛市","value":"商洛市","open":true},{"pId":"0_1_23","id":"0_1_23_4","text":"渭南市","value":"渭南市","open":true},{"pId":"0_1_23","id":"0_1_23_5","text":"西安市","value":"西安市","open":true},{"pId":"0_1_23","id":"0_1_23_6","text":"咸阳市","value":"咸阳市","open":true},{"pId":"0_1_23","id":"0_1_23_7","text":"延安市","value":"延安市","open":true},{"pId":"0_1_23","id":"0_1_23_8","text":"榆林市","value":"榆林市","open":true},{"pId":"0_1","id":"0_1_24","text":"上海市( 共19个 )","value":"上海市","open":true},{"pId":"0_1_24","id":"0_1_24_0","text":"宝山区","value":"宝山区","open":true},{"pId":"0_1_24","id":"0_1_24_1","text":"长宁区","value":"长宁区","open":true},{"pId":"0_1_24","id":"0_1_24_2","text":"崇明县","value":"崇明县","open":true},{"pId":"0_1_24","id":"0_1_24_3","text":"奉贤区","value":"奉贤区","open":true},{"pId":"0_1_24","id":"0_1_24_4","text":"虹口区","value":"虹口区","open":true},{"pId":"0_1_24","id":"0_1_24_5","text":"黄浦区","value":"黄浦区","open":true},{"pId":"0_1_24","id":"0_1_24_6","text":"嘉定区","value":"嘉定区","open":true},{"pId":"0_1_24","id":"0_1_24_7","text":"金山区","value":"金山区","open":true},{"pId":"0_1_24","id":"0_1_24_8","text":"静安区","value":"静安区","open":true},{"pId":"0_1_24","id":"0_1_24_9","text":"昆明市","value":"昆明市","open":true},{"pId":"0_1_24","id":"0_1_24_10","text":"闵行区","value":"闵行区","open":true},{"pId":"0_1_24","id":"0_1_24_11","text":"普陀区","value":"普陀区","open":true},{"pId":"0_1_24","id":"0_1_24_12","text":"浦东新区","value":"浦东新区","open":true},{"pId":"0_1_24","id":"0_1_24_13","text":"青浦区","value":"青浦区","open":true},{"pId":"0_1_24","id":"0_1_24_14","text":"上海市区","value":"上海市区","open":true},{"pId":"0_1_24","id":"0_1_24_15","text":"松江区","value":"松江区","open":true},{"pId":"0_1_24","id":"0_1_24_16","text":"徐汇区","value":"徐汇区","open":true},{"pId":"0_1_24","id":"0_1_24_17","text":"杨浦区","value":"杨浦区","open":true},{"pId":"0_1_24","id":"0_1_24_18","text":"闸北区","value":"闸北区","open":true},{"pId":"0_1","id":"0_1_25","text":"四川省( 共21个 )","value":"四川省","open":true},{"pId":"0_1_25","id":"0_1_25_0","text":"阿坝藏族羌族自治州","value":"阿坝藏族羌族自治州","open":true},{"pId":"0_1_25","id":"0_1_25_1","text":"巴中市","value":"巴中市","open":true},{"pId":"0_1_25","id":"0_1_25_2","text":"成都市","value":"成都市","open":true},{"pId":"0_1_25","id":"0_1_25_3","text":"达州市","value":"达州市","open":true},{"pId":"0_1_25","id":"0_1_25_4","text":"德阳市","value":"德阳市","open":true},{"pId":"0_1_25","id":"0_1_25_5","text":"甘孜市","value":"甘孜市","open":true},{"pId":"0_1_25","id":"0_1_25_6","text":"广安市","value":"广安市","open":true},{"pId":"0_1_25","id":"0_1_25_7","text":"广元市","value":"广元市","open":true},{"pId":"0_1_25","id":"0_1_25_8","text":"乐山市","value":"乐山市","open":true},{"pId":"0_1_25","id":"0_1_25_9","text":"凉山市","value":"凉山市","open":true},{"pId":"0_1_25","id":"0_1_25_10","text":"泸州市","value":"泸州市","open":true},{"pId":"0_1_25","id":"0_1_25_11","text":"眉山市","value":"眉山市","open":true},{"pId":"0_1_25","id":"0_1_25_12","text":"绵阳市","value":"绵阳市","open":true},{"pId":"0_1_25","id":"0_1_25_13","text":"南充市","value":"南充市","open":true},{"pId":"0_1_25","id":"0_1_25_14","text":"内江市","value":"内江市","open":true},{"pId":"0_1_25","id":"0_1_25_15","text":"攀枝花市","value":"攀枝花市","open":true},{"pId":"0_1_25","id":"0_1_25_16","text":"遂宁市","value":"遂宁市","open":true},{"pId":"0_1_25","id":"0_1_25_17","text":"雅安市","value":"雅安市","open":true},{"pId":"0_1_25","id":"0_1_25_18","text":"宜宾市","value":"宜宾市","open":true},{"pId":"0_1_25","id":"0_1_25_19","text":"资阳市","value":"资阳市","open":true},{"pId":"0_1_25","id":"0_1_25_20","text":"自贡市","value":"自贡市","open":true},{"pId":"0_1","id":"0_1_26","text":"台湾( 共1个 )","value":"台湾","open":true},{"pId":"0_1_26","id":"0_1_26_0","text":"台北市","value":"台北市","open":true},{"pId":"0_1","id":"0_1_27","text":"天津市( 共1个 )","value":"天津市","open":true},{"pId":"0_1_27","id":"0_1_27_0","text":"天津市区","value":"天津市区","open":true},{"pId":"0_1","id":"0_1_28","text":"西藏自治区( 共2个 )","value":"西藏自治区","open":true},{"pId":"0_1_28","id":"0_1_28_0","text":"阿里市","value":"阿里市","open":true},{"pId":"0_1_28","id":"0_1_28_1","text":"日喀则市","value":"日喀则市","open":true},{"pId":"0_1","id":"0_1_29","text":"香港特别行政区( 共1个 )","value":"香港特别行政区","open":true},{"pId":"0_1_29","id":"0_1_29_0","text":"香港","value":"香港","open":true},{"pId":"0_1","id":"0_1_30","text":"新疆维吾尔族自治区( 共11个 )","value":"新疆维吾尔族自治区","open":true},{"pId":"0_1_30","id":"0_1_30_0","text":"巴音郭楞市","value":"巴音郭楞市","open":true},{"pId":"0_1_30","id":"0_1_30_1","text":"哈密市","value":"哈密市","open":true},{"pId":"0_1_30","id":"0_1_30_2","text":"和田市","value":"和田市","open":true},{"pId":"0_1_30","id":"0_1_30_3","text":"喀什地区","value":"喀什地区","open":true},{"pId":"0_1_30","id":"0_1_30_4","text":"克拉玛依市","value":"克拉玛依市","open":true},{"pId":"0_1_30","id":"0_1_30_5","text":"克孜勒苏柯州","value":"克孜勒苏柯州","open":true},{"pId":"0_1_30","id":"0_1_30_6","text":"石河子市","value":"石河子市","open":true},{"pId":"0_1_30","id":"0_1_30_7","text":"塔城市","value":"塔城市","open":true},{"pId":"0_1_30","id":"0_1_30_8","text":"吐鲁番地区","value":"吐鲁番地区","open":true},{"pId":"0_1_30","id":"0_1_30_9","text":"乌鲁木齐","value":"乌鲁木齐","open":true},{"pId":"0_1_30","id":"0_1_30_10","text":"伊犁市","value":"伊犁市","open":true},{"pId":"0_1","id":"0_1_31","text":"云南省( 共12个 )","value":"云南省","open":true},{"pId":"0_1_31","id":"0_1_31_0","text":"保山市","value":"保山市","open":true},{"pId":"0_1_31","id":"0_1_31_1","text":"楚雄彝族自治州","value":"楚雄彝族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_2","text":"大理白族自治州","value":"大理白族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_3","text":"红河哈尼族彝族自治州","value":"红河哈尼族彝族自治州","open":true},{"pId":"0_1_31","id":"0_1_31_4","text":"昆明市","value":"昆明市","open":true},{"pId":"0_1_31","id":"0_1_31_5","text":"丽江市","value":"丽江市","open":true},{"pId":"0_1_31","id":"0_1_31_6","text":"临沧市","value":"临沧市","open":true},{"pId":"0_1_31","id":"0_1_31_7","text":"曲靖市","value":"曲靖市","open":true},{"pId":"0_1_31","id":"0_1_31_8","text":"思茅市","value":"思茅市","open":true},{"pId":"0_1_31","id":"0_1_31_9","text":"文山市","value":"文山市","open":true},{"pId":"0_1_31","id":"0_1_31_10","text":"玉溪市","value":"玉溪市","open":true},{"pId":"0_1_31","id":"0_1_31_11","text":"昭通市","value":"昭通市","open":true},{"pId":"0_1","id":"0_1_32","text":"浙江省( 共12个 )","value":"浙江省","open":true},{"pId":"0_1_32","id":"0_1_32_0","text":"杭州市","value":"杭州市","open":true},{"pId":"0_1_32","id":"0_1_32_1","text":"湖州市","value":"湖州市","open":true},{"pId":"0_1_32","id":"0_1_32_2","text":"嘉兴市","value":"嘉兴市","open":true},{"pId":"0_1_32","id":"0_1_32_3","text":"金华市","value":"金华市","open":true},{"pId":"0_1_32","id":"0_1_32_4","text":"丽水市","value":"丽水市","open":true},{"pId":"0_1_32","id":"0_1_32_5","text":"宁波市","value":"宁波市","open":true},{"pId":"0_1_32","id":"0_1_32_6","text":"衢州市","value":"衢州市","open":true},{"pId":"0_1_32","id":"0_1_32_7","text":"绍兴市","value":"绍兴市","open":true},{"pId":"0_1_32","id":"0_1_32_8","text":"台州市","value":"台州市","open":true},{"pId":"0_1_32","id":"0_1_32_9","text":"温州市","value":"温州市","open":true},{"pId":"0_1_32","id":"0_1_32_10","text":"浙江省","value":"浙江省","open":true},{"pId":"0_1_32","id":"0_1_32_11","text":"舟山市","value":"舟山市","open":true},{"pId":"0_1","id":"0_1_33","text":"重庆市( 共1个 )","value":"重庆市","open":true},{"pId":"0_1_33","id":"0_1_33_0","text":"重庆市区","value":"重庆市区","open":true}] }; + diff --git a/docs/widget.js b/docs/widget.js index 7e9bde29b8..a90a7500f1 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -17173,20 +17173,12 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree _initData: function (items) { this.items = items; - var nodes = BI.Tree.transformToTreeFormat(items); + var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initMap(); this._initFloors(); }, - _initMap: function () { - var map = this.map = {}; - BI.each(this.items, function (i, item) { - map[item.value] = item; - }); - }, - _initFloors: function () { this.floors = -1; var root = this.tree.getRoot(); @@ -17258,7 +17250,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return; } BI.each(selected, function (k) { - var node = self._getNode(k); + var node = self._getNode(parentValues, k); var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); @@ -17517,7 +17509,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree } function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { - var node = self.map[value]; + var node = self._getNode(parentValues, value) result.push({ id: node.id, pId: node.pId, @@ -17695,14 +17687,34 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return finded.finded.length > 0 || finded.matched.length > 0; }, - _getNode: function (v) { - return this.tree.search(v, "value"); + _getNode: function (parentValues, v) { + var self = this; + var findedParentNode; + 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) { + findedParentNode = node; + return false; + } + if (node.value === parentValues[index]) { + index++; + return; + } + return true; + }); + return findedParentNode; }, _getChildren: function (parentValues) { if (parentValues.length > 0) { var value = BI.last(parentValues); - var parent = this.tree.search(value, "value"); + var parent = this._getNode(parentValues.slice(0, parentValues.length - 1), value); } else { var parent = this.tree.getRoot(); } @@ -17970,8 +17982,6 @@ BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { _defaultConfig: function () { return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-pane", - width: 200, - height: 30, items: null, itemsCreator: BI.emptyFn, cache: true diff --git a/src/base/tree/asynctree.js b/src/base/tree/asynctree.js index 96f9c900df..301b599636 100644 --- a/src/base/tree/asynctree.js +++ b/src/base/tree/asynctree.js @@ -187,7 +187,7 @@ BI.AsyncTree = BI.inherit(BI.TreeView, { } var checkedValues = this._getSelectedValues(); if (BI.isEmpty(checkedValues)) { - return this.selectedValues; + return BI.deepClone(this.selectedValues); } if (BI.isEmpty(this.selectedValues)) { return checkedValues; diff --git a/src/base/tree/parttree.js b/src/base/tree/parttree.js index e75cce7a05..d628cd72c1 100644 --- a/src/base/tree/parttree.js +++ b/src/base/tree/parttree.js @@ -46,7 +46,7 @@ BI.PartTree = BI.inherit(BI.AsyncTree, { BI.AsyncTree.superclass._selectTreeNode.apply(self, arguments); } else { o.itemsCreator(BI.extend({}, o.paras, { - type: BI.TreeView.REQ_TYPE_CALCULATE_SELECT_DATA, + type: BI.TreeView.REQ_TYPE_SELECT_DATA, selectedValues: this.selectedValues, notSelectedValue: name, parentValues: parentValues diff --git a/src/base/tree/treeview.js b/src/base/tree/treeview.js index 204d5936a2..37c66d55a0 100644 --- a/src/base/tree/treeview.js +++ b/src/base/tree/treeview.js @@ -216,7 +216,7 @@ BI.TreeView = BI.inherit(BI.Pane, { _getNodeValue: function (node) { //去除标红 - return node.value || node.text.replace(/<[^>]+>/g, ""); + return node.value == null ? node.text.replace(/<[^>]+>/g, "") : node.value; }, //获取半选框值 @@ -308,6 +308,7 @@ BI.TreeView = BI.inherit(BI.Pane, { var self = this, o = this.options; var ns = BI.Tree.arrayFormat(nodes); BI.each(ns, function (i, n) { + n.title = n.title || n.text || n.value; //处理标红 if (BI.isKey(o.paras.keyword)) { n.text = $("
").__textKeywordMarked__(n.text, o.paras.keyword, n.py).html(); @@ -450,7 +451,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }, setSelectedValue: function (value) { - this.options.paras.selectedValues = value || {}; + this.options.paras.selectedValues = BI.deepClone(value) || {}; this.selectedValues = BI.deepClone(value) || {}; }, @@ -469,7 +470,7 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function(){ + getExpandedValue: function () { if (!this.nodes) { return null; } @@ -486,14 +487,9 @@ BI.TreeView = BI.inherit(BI.Pane, { return this._getSelectedValues(); }, - empty: function () { - BI.isNotNull(this.nodes) && this.nodes.destroy(); - }, - - destroy: function () { + destroyed: function () { this.stop(); this.nodes && this.nodes.destroy(); - BI.TreeView.superclass.destroy.apply(this, arguments); } }); BI.extend(BI.TreeView, { diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.js b/src/component/treevaluechooser/abstract.treevaluechooser.js index ea539c1508..1fe0033c29 100644 --- a/src/component/treevaluechooser/abstract.treevaluechooser.js +++ b/src/component/treevaluechooser/abstract.treevaluechooser.js @@ -13,20 +13,12 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { _initData: function (items) { this.items = items; - var nodes = BI.Tree.transformToTreeFormat(items); + var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initMap(); this._initFloors(); }, - _initMap: function () { - var map = this.map = {}; - BI.each(this.items, function (i, item) { - map[item.value] = item; - }); - }, - _initFloors: function () { this.floors = -1; var root = this.tree.getRoot(); @@ -98,7 +90,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return; } BI.each(selected, function (k) { - var node = self._getNode(k); + var node = self._getNode(parentValues, k); var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); @@ -357,7 +349,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { } function createOneJson(parentValues, value, isOpen, checked, half, flag, result) { - var node = self.map[value]; + var node = self._getNode(parentValues, value) result.push({ id: node.id, pId: node.pId, @@ -535,14 +527,34 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return finded.finded.length > 0 || finded.matched.length > 0; }, - _getNode: function (v) { - return this.tree.search(v, "value"); + _getNode: function (parentValues, v) { + var self = this; + var findedParentNode; + 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) { + findedParentNode = node; + return false; + } + if (node.value === parentValues[index]) { + index++; + return; + } + return true; + }); + return findedParentNode; }, _getChildren: function (parentValues) { if (parentValues.length > 0) { var value = BI.last(parentValues); - var parent = this.tree.search(value, "value"); + var parent = this._getNode(parentValues.slice(0, parentValues.length - 1), value); } else { var parent = this.tree.getRoot(); } diff --git a/src/component/valuechooser/pane.valuechooser.js b/src/component/valuechooser/pane.valuechooser.js index 67ef9cab98..49c4aaf188 100644 --- a/src/component/valuechooser/pane.valuechooser.js +++ b/src/component/valuechooser/pane.valuechooser.js @@ -11,8 +11,6 @@ BI.ValueChooserPane = BI.inherit(BI.AbstractValueChooser, { _defaultConfig: function () { return BI.extend(BI.ValueChooserPane.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-value-chooser-pane", - width: 200, - height: 30, items: null, itemsCreator: BI.emptyFn, cache: true diff --git a/src/core/base.js b/src/core/base.js index 96438a27e9..35ddfdead3 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -457,15 +457,15 @@ if (!window.BI) { }, has: function (obj, keys) { - if (BI.isKey(keys)) { - return _.has.apply(_, arguments); - } - if (!keys || BI.isEmpty(keys)) { - return false; + if (BI.isArray(keys)) { + if (keys.length === 0) { + return false; + } + return BI.every(keys, function (i, key) { + return _.has(obj, key); + }); } - return BI.every(keys, function (i, key) { - return _.has(obj, key); - }); + return _.has.apply(_, arguments); }, //数字和字符串可以作为key diff --git a/src/core/utils/tree.js b/src/core/utils/tree.js index 139dedce12..c5632f0a7a 100644 --- a/src/core/utils/tree.js +++ b/src/core/utils/tree.js @@ -17,7 +17,7 @@ }, isRoot: function (node) { - return node === this.root || node.id === this.root.id; + return node === this.root; }, getRoot: function () { @@ -394,7 +394,7 @@ if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = BI.clone(nodes[i]); - node.pId = pId; + node.pId = node.pId == null ? pId : node.pId; delete node.children; r.push(node); if (nodes[i]["children"]) { @@ -403,7 +403,7 @@ } } else { var newNodes = BI.clone(nodes); - newNodes.pId = pId; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; delete newNodes.children; r.push(newNodes); if (nodes["children"]) { @@ -414,21 +414,25 @@ }, arrayFormat: function (nodes, pId) { - if (!nodes) return []; + if (!nodes) { + return []; + } var r = []; if (BI.isArray(nodes)) { for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; + node.pId = node.pId == null ? pId : node.pId; r.push(node); if (nodes[i]["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes[i]["children"], node.id)); + r = r.concat(BI.Tree.arrayFormat(nodes[i]["children"], node.id)); } } } else { var newNodes = nodes; + newNodes.pId = newNodes.pId == null ? pId : newNodes.pId; r.push(newNodes); if (nodes["children"]) { - r = r.concat(BI.Tree.transformToArrayFormat(nodes["children"], newNodes.id)); + r = r.concat(BI.Tree.arrayFormat(nodes["children"], newNodes.id)); } } return r; @@ -444,13 +448,13 @@ var r = []; var tmpMap = []; for (i = 0, l = sNodes.length; i < l; i++) { - if(BI.isNull(sNodes[i].id)) { + if (BI.isNull(sNodes[i].id)) { return sNodes; } tmpMap[sNodes[i].id] = BI.clone(sNodes[i]); } for (i = 0, l = sNodes.length; i < l; i++) { - if (tmpMap[sNodes[i].pId] && sNodes[i].id != sNodes[i].pId) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { if (!tmpMap[sNodes[i].pId].children) { tmpMap[sNodes[i].pId].children = []; } @@ -466,6 +470,37 @@ } }, + treeFormat: function (sNodes) { + var i, l; + if (!sNodes) { + return []; + } + + if (BI.isArray(sNodes)) { + var r = []; + var tmpMap = []; + for (i = 0, l = sNodes.length; i < l; i++) { + if (BI.isNull(sNodes[i].id)) { + return sNodes; + } + tmpMap[sNodes[i].id] = sNodes[i]; + } + for (i = 0, l = sNodes.length; i < l; i++) { + if (tmpMap[sNodes[i].pId] && sNodes[i].id !== sNodes[i].pId) { + if (!tmpMap[sNodes[i].pId].children) { + tmpMap[sNodes[i].pId].children = []; + } + tmpMap[sNodes[i].pId].children.push(tmpMap[sNodes[i].id]); + } else { + r.push(tmpMap[sNodes[i].id]); + } + } + return r; + } else { + return [sNodes]; + } + }, + traversal: function (array, callback) { if (BI.isNull(array)) { return; From a79c8a8ff7b071ac538195b76665d1d5ec66ff6b Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 21:31:40 +0800 Subject: [PATCH 05/27] add --- bi/widget.js | 13 +++++++++++++ docs/widget.js | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/bi/widget.js b/bi/widget.js index a90a7500f1..54d8412158 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -11433,6 +11433,14 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }); }, + stopSearch: function () { + this.trigger.stopSearch(); + }, + + updateValue: function (v) { + this.adapter.updateValue(v); + }, + getValue: function () { return this.storeValue.value; }, @@ -11482,6 +11490,11 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { this.popup.setValue(v.value); }, + updateValue: function (v) { + this.popup.updateValue(v); + this.popup.refresh(); + }, + populate: function (config) { this.popup.stroke(config); } diff --git a/docs/widget.js b/docs/widget.js index a90a7500f1..54d8412158 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -11433,6 +11433,14 @@ BI.MultiSelectTree = BI.inherit(BI.Widget, { }); }, + stopSearch: function () { + this.trigger.stopSearch(); + }, + + updateValue: function (v) { + this.adapter.updateValue(v); + }, + getValue: function () { return this.storeValue.value; }, @@ -11482,6 +11490,11 @@ BI.MultiSelectTreePopup = BI.inherit(BI.Widget, { this.popup.setValue(v.value); }, + updateValue: function (v) { + this.popup.updateValue(v); + this.popup.refresh(); + }, + populate: function (config) { this.popup.stroke(config); } From 44a279d9c23df07082616106d1f00b4aecc28bd6 Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 22:00:17 +0800 Subject: [PATCH 06/27] add --- bi/case.js | 18 ------------------ docs/case.js | 18 ------------------ src/case/toolbar/toolbar.multiselect.js | 18 ------------------ 3 files changed, 54 deletions(-) diff --git a/bi/case.js b/bi/case.js index 2a7f667cdb..00223d3cbc 100644 --- a/bi/case.js +++ b/bi/case.js @@ -10269,7 +10269,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, - onCheck: BI.emptyFn, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -10283,7 +10282,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(self.isSelected()); - o.onCheck.call(self, self.isSelected()); } }); this.half = BI.createWidget({ @@ -10291,7 +10289,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(true); - o.onCheck.call(self, self.isSelected()); } }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function () { @@ -10334,21 +10331,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, - doClick: function () { - var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); - if (isHalf === true) { - this.setSelected(true); - } else { - this.setSelected(!isSelected); - } - - if (this.isValid()) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, this.getValue(), this); - this.options.onCheck.call(this, this.isSelected()); - this.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); - } - }, - setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); diff --git a/docs/case.js b/docs/case.js index 2a7f667cdb..00223d3cbc 100644 --- a/docs/case.js +++ b/docs/case.js @@ -10269,7 +10269,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, - onCheck: BI.emptyFn, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -10283,7 +10282,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(self.isSelected()); - o.onCheck.call(self, self.isSelected()); } }); this.half = BI.createWidget({ @@ -10291,7 +10289,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(true); - o.onCheck.call(self, self.isSelected()); } }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function () { @@ -10334,21 +10331,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, - doClick: function () { - var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); - if (isHalf === true) { - this.setSelected(true); - } else { - this.setSelected(!isSelected); - } - - if (this.isValid()) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, this.getValue(), this); - this.options.onCheck.call(this, this.isSelected()); - this.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); - } - }, - setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); diff --git a/src/case/toolbar/toolbar.multiselect.js b/src/case/toolbar/toolbar.multiselect.js index 78c4b049b3..7a1497d8d9 100644 --- a/src/case/toolbar/toolbar.multiselect.js +++ b/src/case/toolbar/toolbar.multiselect.js @@ -12,7 +12,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, - onCheck: BI.emptyFn, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -26,7 +25,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(self.isSelected()); - o.onCheck.call(self, self.isSelected()); } }); this.half = BI.createWidget({ @@ -34,7 +32,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { stopPropagation: true, handler: function () { self.setSelected(true); - o.onCheck.call(self, self.isSelected()); } }); this.checkbox.on(BI.Controller.EVENT_CHANGE, function () { @@ -77,21 +74,6 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, - doClick: function () { - var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); - if (isHalf === true) { - this.setSelected(true); - } else { - this.setSelected(!isSelected); - } - - if (this.isValid()) { - this.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.CLICK, this.getValue(), this); - this.options.onCheck.call(this, this.isSelected()); - this.fireEvent(BI.MultiSelectBar.EVENT_CHANGE, this.isSelected(), this); - } - }, - setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); From 659d675e3f10e72ae526e61f5e060cd9315a175a Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 22:24:34 +0800 Subject: [PATCH 07/27] add --- bi/widget.js | 35 +++++-------------- docs/widget.js | 35 +++++-------------- .../abstract.treevaluechooser.js | 35 +++++-------------- 3 files changed, 24 insertions(+), 81 deletions(-) diff --git a/bi/widget.js b/bi/widget.js index 54d8412158..d13df3eee8 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -17189,16 +17189,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initFloors(); - }, - - _initFloors: function () { - this.floors = -1; - var root = this.tree.getRoot(); - while (root) { - this.floors++; - root = root.getChildren()[0]; - } }, _itemsCreator: function (options, callback) { @@ -17242,23 +17232,20 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return; } - doCheck(0, [], this.tree.getRoot(), selectedValues); + doCheck([], this.tree.getRoot(), selectedValues); callback({ items: result }); - function doCheck(floor, parentValues, node, selected) { - if (floor >= self.floors) { - return; - } + function doCheck(parentValues, node, selected) { if (selected == null || BI.isEmpty(selected)) { BI.each(node.getChildren(), function (i, child) { var newParents = BI.clone(parentValues); newParents.push(child.value); var llen = self._getChildCount(newParents); createOneJson(child, node.id, llen); - doCheck(floor + 1, newParents, child, {}); + doCheck(newParents, child, {}); }); return; } @@ -17267,7 +17254,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); - doCheck(floor + 1, newParents, node, selected[k]); + doCheck(newParents, node, selected[k]); }) } @@ -17357,9 +17344,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree if (self._isMatch(current, keyword)) { return true; } - if (deep >= self.floors) { - return false; - } var children = self._getChildren(newParents); @@ -17495,9 +17479,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); return [true, checked]; } - if (deep >= self.floors) { - return [false, false]; - } var newParents = BI.clone(parentValues); newParents.push(current); var children = self._getChildren(newParents); @@ -17529,7 +17510,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree text: node.text, value: node.value, title: node.title, - isParent: parentValues.length + 1 < self.floors, + isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, halfCheck: half, @@ -17613,7 +17594,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree value: nodes[i].value, text: nodes[i].text, times: 1, - isParent: parentValues.length + 1 < this.floors, + isParent: nodes[i].getChildrenLength() > 0, checked: state[0], halfCheck: state[1] }) @@ -17660,14 +17641,14 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree function getCheckState(current, parentValues, valueMap, checkState) { var checked = checkState.checked, half = checkState.half; - var hasChild = parentValues.length + 1 < self.floors; var tempCheck = false, halfCheck = false; if (BI.has(valueMap, current)) { //可能是半选 if (valueMap[current][0] === 1) { var values = BI.clone(parentValues); values.push(current); - if (hasChild && self._getChildCount(values) !== valueMap[current][1]) { + var childCount = self._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { halfCheck = true; } } else if (valueMap[current][0] === 2) { diff --git a/docs/widget.js b/docs/widget.js index 54d8412158..d13df3eee8 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -17189,16 +17189,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initFloors(); - }, - - _initFloors: function () { - this.floors = -1; - var root = this.tree.getRoot(); - while (root) { - this.floors++; - root = root.getChildren()[0]; - } }, _itemsCreator: function (options, callback) { @@ -17242,23 +17232,20 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree return; } - doCheck(0, [], this.tree.getRoot(), selectedValues); + doCheck([], this.tree.getRoot(), selectedValues); callback({ items: result }); - function doCheck(floor, parentValues, node, selected) { - if (floor >= self.floors) { - return; - } + function doCheck(parentValues, node, selected) { if (selected == null || BI.isEmpty(selected)) { BI.each(node.getChildren(), function (i, child) { var newParents = BI.clone(parentValues); newParents.push(child.value); var llen = self._getChildCount(newParents); createOneJson(child, node.id, llen); - doCheck(floor + 1, newParents, child, {}); + doCheck(newParents, child, {}); }); return; } @@ -17267,7 +17254,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); - doCheck(floor + 1, newParents, node, selected[k]); + doCheck(newParents, node, selected[k]); }) } @@ -17357,9 +17344,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree if (self._isMatch(current, keyword)) { return true; } - if (deep >= self.floors) { - return false; - } var children = self._getChildren(newParents); @@ -17495,9 +17479,6 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); return [true, checked]; } - if (deep >= self.floors) { - return [false, false]; - } var newParents = BI.clone(parentValues); newParents.push(current); var children = self._getChildren(newParents); @@ -17529,7 +17510,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree text: node.text, value: node.value, title: node.title, - isParent: parentValues.length + 1 < self.floors, + isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, halfCheck: half, @@ -17613,7 +17594,7 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree value: nodes[i].value, text: nodes[i].text, times: 1, - isParent: parentValues.length + 1 < this.floors, + isParent: nodes[i].getChildrenLength() > 0, checked: state[0], halfCheck: state[1] }) @@ -17660,14 +17641,14 @@ BI.shortcut('bi.all_value_chooser_pane', BI.AllValueChooserPane);BI.AbstractTree function getCheckState(current, parentValues, valueMap, checkState) { var checked = checkState.checked, half = checkState.half; - var hasChild = parentValues.length + 1 < self.floors; var tempCheck = false, halfCheck = false; if (BI.has(valueMap, current)) { //可能是半选 if (valueMap[current][0] === 1) { var values = BI.clone(parentValues); values.push(current); - if (hasChild && self._getChildCount(values) !== valueMap[current][1]) { + var childCount = self._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { halfCheck = true; } } else if (valueMap[current][0] === 2) { diff --git a/src/component/treevaluechooser/abstract.treevaluechooser.js b/src/component/treevaluechooser/abstract.treevaluechooser.js index 1fe0033c29..41699b41eb 100644 --- a/src/component/treevaluechooser/abstract.treevaluechooser.js +++ b/src/component/treevaluechooser/abstract.treevaluechooser.js @@ -16,16 +16,6 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var nodes = BI.Tree.treeFormat(items); this.tree = new BI.Tree(); this.tree.initTree(nodes); - this._initFloors(); - }, - - _initFloors: function () { - this.floors = -1; - var root = this.tree.getRoot(); - while (root) { - this.floors++; - root = root.getChildren()[0]; - } }, _itemsCreator: function (options, callback) { @@ -69,23 +59,20 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { return; } - doCheck(0, [], this.tree.getRoot(), selectedValues); + doCheck([], this.tree.getRoot(), selectedValues); callback({ items: result }); - function doCheck(floor, parentValues, node, selected) { - if (floor >= self.floors) { - return; - } + function doCheck(parentValues, node, selected) { if (selected == null || BI.isEmpty(selected)) { BI.each(node.getChildren(), function (i, child) { var newParents = BI.clone(parentValues); newParents.push(child.value); var llen = self._getChildCount(newParents); createOneJson(child, node.id, llen); - doCheck(floor + 1, newParents, child, {}); + doCheck(newParents, child, {}); }); return; } @@ -94,7 +81,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { var newParents = BI.clone(parentValues); newParents.push(node.value); createOneJson(node, BI.last(parentValues), getCount(selected[k], newParents)); - doCheck(floor + 1, newParents, node, selected[k]); + doCheck(newParents, node, selected[k]); }) } @@ -184,9 +171,6 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { if (self._isMatch(current, keyword)) { return true; } - if (deep >= self.floors) { - return false; - } var children = self._getChildren(newParents); @@ -322,9 +306,6 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { createOneJson(parentValues, current, false, checked, !isAllSelect && isHalf(parentValues, current), true, result); return [true, checked]; } - if (deep >= self.floors) { - return [false, false]; - } var newParents = BI.clone(parentValues); newParents.push(current); var children = self._getChildren(newParents); @@ -356,7 +337,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { text: node.text, value: node.value, title: node.title, - isParent: parentValues.length + 1 < self.floors, + isParent: node.getChildrenLength() > 0, open: isOpen, checked: checked, halfCheck: half, @@ -440,7 +421,7 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { value: nodes[i].value, text: nodes[i].text, times: 1, - isParent: parentValues.length + 1 < this.floors, + isParent: nodes[i].getChildrenLength() > 0, checked: state[0], halfCheck: state[1] }) @@ -487,14 +468,14 @@ BI.AbstractTreeValueChooser = BI.inherit(BI.Widget, { function getCheckState(current, parentValues, valueMap, checkState) { var checked = checkState.checked, half = checkState.half; - var hasChild = parentValues.length + 1 < self.floors; var tempCheck = false, halfCheck = false; if (BI.has(valueMap, current)) { //可能是半选 if (valueMap[current][0] === 1) { var values = BI.clone(parentValues); values.push(current); - if (hasChild && self._getChildCount(values) !== valueMap[current][1]) { + var childCount = self._getChildCount(values); + if (childCount > 0 && childCount !== valueMap[current][1]) { halfCheck = true; } } else if (valueMap[current][0] === 2) { From 1007647d229d8efea7d05159576a73de246c6c7e Mon Sep 17 00:00:00 2001 From: guy Date: Sat, 20 May 2017 22:37:47 +0800 Subject: [PATCH 08/27] update --- bi/widget.js | 6 +++--- docs/widget.js | 6 +++--- src/widget/multiselectlist/multiselectlist.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bi/widget.js b/bi/widget.js index d13df3eee8..5ff973be8f 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -10973,6 +10973,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); + self.trigger.setValue(self.storeValue); }; this.adapter = BI.createWidget({ @@ -11032,6 +11033,8 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { self._showAdapter(); self._setStartValue(""); self.adapter.setValue(self.storeValue); + //需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); } }, { eventName: BI.Searcher.EVENT_PAUSE, @@ -11043,7 +11046,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { value: [keyword] }, function () { self._showAdapter(); - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); @@ -11063,13 +11065,11 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); self.adapter.populate(); self._setStartValue(""); } else { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); } diff --git a/docs/widget.js b/docs/widget.js index d13df3eee8..5ff973be8f 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -10973,6 +10973,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); + self.trigger.setValue(self.storeValue); }; this.adapter = BI.createWidget({ @@ -11032,6 +11033,8 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { self._showAdapter(); self._setStartValue(""); self.adapter.setValue(self.storeValue); + //需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); } }, { eventName: BI.Searcher.EVENT_PAUSE, @@ -11043,7 +11046,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { value: [keyword] }, function () { self._showAdapter(); - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); @@ -11063,13 +11065,11 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); self.adapter.populate(); self._setStartValue(""); } else { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); } diff --git a/src/widget/multiselectlist/multiselectlist.js b/src/widget/multiselectlist/multiselectlist.js index aaf5239436..72e80b5503 100644 --- a/src/widget/multiselectlist/multiselectlist.js +++ b/src/widget/multiselectlist/multiselectlist.js @@ -17,6 +17,7 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { var assertShowValue = function () { BI.isKey(self._startValue) && self.storeValue.value[self.storeValue.type === BI.Selection.All ? "remove" : "pushDistinct"](self._startValue); + self.trigger.setValue(self.storeValue); }; this.adapter = BI.createWidget({ @@ -76,6 +77,8 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { self._showAdapter(); self._setStartValue(""); self.adapter.setValue(self.storeValue); + //需要刷新回到初始界面,否则搜索的结果不能放在最前面 + self.adapter.populate(); } }, { eventName: BI.Searcher.EVENT_PAUSE, @@ -87,7 +90,6 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { value: [keyword] }, function () { self._showAdapter(); - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); self._setStartValue(keyword); assertShowValue(); @@ -107,13 +109,11 @@ BI.MultiSelectList = BI.inherit(BI.Widget, { if (keywords.length > 0) { self._joinKeywords(keywords, function () { if (BI.isEndWithBlank(last)) { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); self.adapter.populate(); self._setStartValue(""); } else { - self.trigger.setValue(self.storeValue); self.adapter.setValue(self.storeValue); assertShowValue(); } From 49ea48a0419b35997070f5408f82580c9715b53b Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 21 May 2017 21:10:58 +0800 Subject: [PATCH 09/27] add --- bi/base.css | 32 ++ bi/base.js | 379 ++++++++++++++++++++- demo/js/config/core.js | 4 + demo/js/core/abstract/demo.virtual_list.js | 11 + docs/base.css | 32 ++ docs/base.js | 379 ++++++++++++++++++++- docs/demo.js | 14 + src/base/list/clusterize.js | 329 ++++++++++++++++++ src/base/list/virtuallist.js | 43 +++ src/base/tree/treeview.js | 7 +- src/less/base/list/clusterize.less | 36 ++ 11 files changed, 1246 insertions(+), 20 deletions(-) create mode 100644 demo/js/core/abstract/demo.virtual_list.js create mode 100644 src/base/list/clusterize.js create mode 100644 src/base/list/virtuallist.js create mode 100644 src/less/base/list/clusterize.less diff --git a/bi/base.css b/bi/base.css index 9a756c5503..a470b9f270 100644 --- a/bi/base.css +++ b/bi/base.css @@ -633,6 +633,38 @@ li.CodeMirror-hint-active { cursor: text; font-size: 14px; } +/* max-height - the only parameter in this file that needs to be edited. + * Change it to suit your needs. The rest is recommended to leave as is. + */ +.clusterize-scroll { + overflow: auto; +} +/** + * Avoid vertical margins for extra tags + * Necessary for correct calculations when rows have nonzero vertical margins + */ +.clusterize-extra-row { + margin-top: 0 !important; + margin-bottom: 0 !important; +} +/* By default extra tag .clusterize-keep-parity added to keep parity of rows. + * Useful when used :nth-child(even/odd) + */ +.clusterize-extra-row.clusterize-keep-parity { + display: none; +} +/* During initialization clusterize adds tabindex to force the browser to keep focus + * on the scrolling list, see issue #11 + * Outline removes default browser's borders for focused elements. + */ +.clusterize-content { + outline: 0; +} +/* Centering message that appears when no data provided + */ +.clusterize-no-data td { + text-align: center; +} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ diff --git a/bi/base.js b/bi/base.js index 47d72dbfbe..b17b359288 100644 --- a/bi/base.js +++ b/bi/base.js @@ -1937,6 +1937,7 @@ BI.TreeView = BI.inherit(BI.Pane, { this.nodes && this.nodes.expandAll(flag); }, + //设置树节点的状态 setValue: function (value, param) { this.setSelectedValue(value); this.checkAll(false); @@ -1964,12 +1965,6 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function () { - if (!this.nodes) { - return null; - } - }, - refresh: function () { this.nodes && this.nodes.refresh(); }, @@ -15453,7 +15448,377 @@ BI.SearcherView = BI.inherit(BI.Pane, { }); BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.searcher_view", BI.SearcherView);/** +BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2017-03-05 + * http://NeXTs.github.com/Clusterize.js/ + * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ + +;(function(name, definition) { + if (typeof module != 'undefined') module.exports = definition(); + else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); + else this[name] = definition(); +}('Clusterize', function() { + "use strict" + + // detect ie9 and lower + // https://gist.github.com/padolsey/527683#comment-786682 + var ie = (function(){ + for( var v = 3, + el = document.createElement('b'), + all = el.all || []; + el.innerHTML = '', + all[0]; + ){} + return v > 4 ? v : document.documentMode; + }()), + is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; + var Clusterize = function(data) { + if( ! (this instanceof Clusterize)) + return new Clusterize(data); + var self = this; + + var defaults = { + rows_in_block: 50, + blocks_in_cluster: 4, + tag: null, + show_no_data_row: true, + no_data_class: 'clusterize-no-data', + no_data_text: 'No data', + keep_parity: true, + callbacks: {} + } + + // public parameters + self.options = {}; + var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; + for(var i = 0, option; option = options[i]; i++) { + self.options[option] = typeof data[option] != 'undefined' && data[option] != null + ? data[option] + : defaults[option]; + } + + var elems = ['scroll', 'content']; + for(var i = 0, elem; elem = elems[i]; i++) { + self[elem + '_elem'] = data[elem + 'Id'] + ? document.getElementById(data[elem + 'Id']) + : data[elem + 'Elem']; + if( ! self[elem + '_elem']) + throw new Error("Error! Could not find " + elem + " element"); + } + + // tabindex forces the browser to keep focus on the scrolling list, fixes #11 + if( ! self.content_elem.hasAttribute('tabindex')) + self.content_elem.setAttribute('tabindex', 0); + + // private parameters + var rows = isArray(data.rows) + ? data.rows + : self.fetchMarkup(), + cache = {}, + scroll_top = self.scroll_elem.scrollTop; + + // append initial data + self.insertToDOM(rows, cache); + + // restore the scroll position + self.scroll_elem.scrollTop = scroll_top; + + // adding scroll handler + var last_cluster = false, + scroll_debounce = 0, + pointer_events_set = false, + scrollEv = function() { + // fixes scrolling issue on Mac #3 + if (is_mac) { + if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; + pointer_events_set = true; + clearTimeout(scroll_debounce); + scroll_debounce = setTimeout(function () { + self.content_elem.style.pointerEvents = 'auto'; + pointer_events_set = false; + }, 50); + } + if (last_cluster != (last_cluster = self.getClusterNum())) + self.insertToDOM(rows, cache); + if (self.options.callbacks.scrollingProgress) + self.options.callbacks.scrollingProgress(self.getScrollProgress()); + }, + resize_debounce = 0, + resizeEv = function() { + clearTimeout(resize_debounce); + resize_debounce = setTimeout(self.refresh, 100); + } + on('scroll', self.scroll_elem, scrollEv); + on('resize', window, resizeEv); + + // public methods + self.destroy = function(clean) { + off('scroll', self.scroll_elem, scrollEv); + off('resize', window, resizeEv); + self.html((clean ? self.generateEmptyRow() : rows).join('')); + } + self.refresh = function(force) { + if(self.getRowsHeight(rows) || force) self.update(rows); + } + self.update = function(new_rows) { + rows = isArray(new_rows) + ? new_rows + : []; + var scroll_top = self.scroll_elem.scrollTop; + // fixes #39 + if(rows.length * self.options.item_height < scroll_top) { + self.scroll_elem.scrollTop = 0; + last_cluster = 0; + } + self.insertToDOM(rows, cache); + self.scroll_elem.scrollTop = scroll_top; + } + self.clear = function() { + self.update([]); + } + self.getRowsAmount = function() { + return rows.length; + } + self.getScrollProgress = function() { + return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; + } + + var add = function(where, _new_rows) { + var new_rows = isArray(_new_rows) + ? _new_rows + : []; + if( ! new_rows.length) return; + rows = where == 'append' + ? rows.concat(new_rows) + : new_rows.concat(rows); + self.insertToDOM(rows, cache); + } + self.append = function(rows) { + add('append', rows); + } + self.prepend = function(rows) { + add('prepend', rows); + } + } + + Clusterize.prototype = { + constructor: Clusterize, + // fetch existing markup + fetchMarkup: function() { + var rows = [], rows_nodes = this.getChildNodes(this.content_elem); + while (rows_nodes.length) { + rows.push(rows_nodes.shift().outerHTML); + } + return rows; + }, + // get tag name, content tag name, tag height, calc cluster height + exploreEnvironment: function(rows, cache) { + var opts = this.options; + opts.content_tag = this.content_elem.tagName.toLowerCase(); + if( ! rows.length) return; + if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); + if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); + if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); + this.getRowsHeight(rows); + }, + getRowsHeight: function(rows) { + var opts = this.options, + prev_item_height = opts.item_height; + opts.cluster_height = 0; + if( ! rows.length) return; + var nodes = this.content_elem.children; + var node = nodes[Math.floor(nodes.length / 2)]; + opts.item_height = node.offsetHeight; + // consider table's border-spacing + if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') + opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; + // consider margins (and margins collapsing) + if(opts.tag != 'tr') { + var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; + var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; + opts.item_height += Math.max(marginTop, marginBottom); + } + opts.block_height = opts.item_height * opts.rows_in_block; + opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; + opts.cluster_height = opts.blocks_in_cluster * opts.block_height; + return prev_item_height != opts.item_height; + }, + // get current cluster number + getClusterNum: function () { + this.options.scroll_top = this.scroll_elem.scrollTop; + return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; + }, + // generate empty row if no data provided + generateEmptyRow: function() { + var opts = this.options; + if( ! opts.tag || ! opts.show_no_data_row) return []; + var empty_row = document.createElement(opts.tag), + no_data_content = document.createTextNode(opts.no_data_text), td; + empty_row.className = opts.no_data_class; + if(opts.tag == 'tr') { + td = document.createElement('td'); + // fixes #53 + td.colSpan = 100; + td.appendChild(no_data_content); + } + empty_row.appendChild(td || no_data_content); + return [empty_row.outerHTML]; + }, + // generate cluster for current scroll position + generate: function (rows, cluster_num) { + var opts = this.options, + rows_len = rows.length; + if (rows_len < opts.rows_in_block) { + return { + top_offset: 0, + bottom_offset: 0, + rows_above: 0, + rows: rows_len ? rows : this.generateEmptyRow() + } + } + var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), + items_end = items_start + opts.rows_in_cluster, + top_offset = Math.max(items_start * opts.item_height, 0), + bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), + this_cluster_rows = [], + rows_above = items_start; + if(top_offset < 1) { + rows_above++; + } + for (var i = items_start; i < items_end; i++) { + rows[i] && this_cluster_rows.push(rows[i]); + } + return { + top_offset: top_offset, + bottom_offset: bottom_offset, + rows_above: rows_above, + rows: this_cluster_rows + } + }, + renderExtraTag: function(class_name, height) { + var tag = document.createElement(this.options.tag), + clusterize_prefix = 'clusterize-'; + tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); + height && (tag.style.height = height + 'px'); + return tag.outerHTML; + }, + // if necessary verify data changed and insert to DOM + insertToDOM: function(rows, cache) { + // explore row's height + if( ! this.options.cluster_height) { + this.exploreEnvironment(rows, cache); + } + var data = this.generate(rows, this.getClusterNum()), + this_cluster_rows = data.rows.join(''), + this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), + top_offset_changed = this.checkChanges('top', data.top_offset, cache), + only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), + callbacks = this.options.callbacks, + layout = []; + + if(this_cluster_content_changed || top_offset_changed) { + if(data.top_offset) { + this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); + layout.push(this.renderExtraTag('top-space', data.top_offset)); + } + layout.push(this_cluster_rows); + data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); + callbacks.clusterWillChange && callbacks.clusterWillChange(); + this.html(layout.join('')); + this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); + callbacks.clusterChanged && callbacks.clusterChanged(); + } else if(only_bottom_offset_changed) { + this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; + } + }, + // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround + html: function(data) { + var content_elem = this.content_elem; + if(ie && ie <= 9 && this.options.tag == 'tr') { + var div = document.createElement('div'), last; + div.innerHTML = '' + data + '
'; + while((last = content_elem.lastChild)) { + content_elem.removeChild(last); + } + var rows_nodes = this.getChildNodes(div.firstChild.firstChild); + while (rows_nodes.length) { + content_elem.appendChild(rows_nodes.shift()); + } + } else { + content_elem.innerHTML = data; + } + }, + getChildNodes: function(tag) { + var child_nodes = tag.children, nodes = []; + for (var i = 0, ii = child_nodes.length; i < ii; i++) { + nodes.push(child_nodes[i]); + } + return nodes; + }, + checkChanges: function(type, value, cache) { + var changed = value != cache[type]; + cache[type] = value; + return changed; + } + } + + // support functions + function on(evt, element, fnc) { + return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); + } + function off(evt, element, fnc) { + return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); + } + function isArray(arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + } + function getStyle(prop, elem) { + return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; + } + + return Clusterize; +}));/** + * 表示当前对象 + * + * Created by GUY on 2015/9/7. + * @class BI.VirtualList + * @extends BI.Widget + */ +BI.VirtualList = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-virtual-list clusterize-scroll", + }; + }, + render: function () { + var self = this, o = this.options; + return { + type: "bi.default", + items: [{ + type: "bi.layout", + ref: function () { + self.contentEl = this; + }, + cls: "clusterize-content" + }] + } + }, + + mounted: function () { + var data = []; + for (var i = 0; i < 10000; i++) { + data.push("
" + i + "
"); + } + new Clusterize({ + rows: data, + scrollElem: this.element[0], + contentElem: this.contentEl.element[0] + }) + }, + + populate: function () { + } +}); +BI.shortcut('bi.virtual_list', BI.VirtualList);/** * 分页控件 * * Created by GUY on 2015/8/31. diff --git a/demo/js/config/core.js b/demo/js/config/core.js index 05f334a539..02af07dee0 100644 --- a/demo/js/config/core.js +++ b/demo/js/config/core.js @@ -105,6 +105,10 @@ Demo.CORE_CONFIG = [{ pId: 102, text: "bi.collection_view", value: "demo.collection_view" +},{ + pId: 102, + text: "bi.virtual_list", + value: "demo.virtual_list" }, { pId: 102, id: 10201, diff --git a/demo/js/core/abstract/demo.virtual_list.js b/demo/js/core/abstract/demo.virtual_list.js new file mode 100644 index 0000000000..792a5d8288 --- /dev/null +++ b/demo/js/core/abstract/demo.virtual_list.js @@ -0,0 +1,11 @@ +Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, + render: function () { + return { + type: "bi.virtual_list" + } + } +}); +BI.shortcut("demo.virtual_list", Demo.Func); \ No newline at end of file diff --git a/docs/base.css b/docs/base.css index 9a756c5503..a470b9f270 100644 --- a/docs/base.css +++ b/docs/base.css @@ -633,6 +633,38 @@ li.CodeMirror-hint-active { cursor: text; font-size: 14px; } +/* max-height - the only parameter in this file that needs to be edited. + * Change it to suit your needs. The rest is recommended to leave as is. + */ +.clusterize-scroll { + overflow: auto; +} +/** + * Avoid vertical margins for extra tags + * Necessary for correct calculations when rows have nonzero vertical margins + */ +.clusterize-extra-row { + margin-top: 0 !important; + margin-bottom: 0 !important; +} +/* By default extra tag .clusterize-keep-parity added to keep parity of rows. + * Useful when used :nth-child(even/odd) + */ +.clusterize-extra-row.clusterize-keep-parity { + display: none; +} +/* During initialization clusterize adds tabindex to force the browser to keep focus + * on the scrolling list, see issue #11 + * Outline removes default browser's borders for focused elements. + */ +.clusterize-content { + outline: 0; +} +/* Centering message that appears when no data provided + */ +.clusterize-no-data td { + text-align: center; +} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ diff --git a/docs/base.js b/docs/base.js index 47d72dbfbe..b17b359288 100644 --- a/docs/base.js +++ b/docs/base.js @@ -1937,6 +1937,7 @@ BI.TreeView = BI.inherit(BI.Pane, { this.nodes && this.nodes.expandAll(flag); }, + //设置树节点的状态 setValue: function (value, param) { this.setSelectedValue(value); this.checkAll(false); @@ -1964,12 +1965,6 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function () { - if (!this.nodes) { - return null; - } - }, - refresh: function () { this.nodes && this.nodes.refresh(); }, @@ -15453,7 +15448,377 @@ BI.SearcherView = BI.inherit(BI.Pane, { }); BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.searcher_view", BI.SearcherView);/** +BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2017-03-05 + * http://NeXTs.github.com/Clusterize.js/ + * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ + +;(function(name, definition) { + if (typeof module != 'undefined') module.exports = definition(); + else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); + else this[name] = definition(); +}('Clusterize', function() { + "use strict" + + // detect ie9 and lower + // https://gist.github.com/padolsey/527683#comment-786682 + var ie = (function(){ + for( var v = 3, + el = document.createElement('b'), + all = el.all || []; + el.innerHTML = '', + all[0]; + ){} + return v > 4 ? v : document.documentMode; + }()), + is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; + var Clusterize = function(data) { + if( ! (this instanceof Clusterize)) + return new Clusterize(data); + var self = this; + + var defaults = { + rows_in_block: 50, + blocks_in_cluster: 4, + tag: null, + show_no_data_row: true, + no_data_class: 'clusterize-no-data', + no_data_text: 'No data', + keep_parity: true, + callbacks: {} + } + + // public parameters + self.options = {}; + var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; + for(var i = 0, option; option = options[i]; i++) { + self.options[option] = typeof data[option] != 'undefined' && data[option] != null + ? data[option] + : defaults[option]; + } + + var elems = ['scroll', 'content']; + for(var i = 0, elem; elem = elems[i]; i++) { + self[elem + '_elem'] = data[elem + 'Id'] + ? document.getElementById(data[elem + 'Id']) + : data[elem + 'Elem']; + if( ! self[elem + '_elem']) + throw new Error("Error! Could not find " + elem + " element"); + } + + // tabindex forces the browser to keep focus on the scrolling list, fixes #11 + if( ! self.content_elem.hasAttribute('tabindex')) + self.content_elem.setAttribute('tabindex', 0); + + // private parameters + var rows = isArray(data.rows) + ? data.rows + : self.fetchMarkup(), + cache = {}, + scroll_top = self.scroll_elem.scrollTop; + + // append initial data + self.insertToDOM(rows, cache); + + // restore the scroll position + self.scroll_elem.scrollTop = scroll_top; + + // adding scroll handler + var last_cluster = false, + scroll_debounce = 0, + pointer_events_set = false, + scrollEv = function() { + // fixes scrolling issue on Mac #3 + if (is_mac) { + if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; + pointer_events_set = true; + clearTimeout(scroll_debounce); + scroll_debounce = setTimeout(function () { + self.content_elem.style.pointerEvents = 'auto'; + pointer_events_set = false; + }, 50); + } + if (last_cluster != (last_cluster = self.getClusterNum())) + self.insertToDOM(rows, cache); + if (self.options.callbacks.scrollingProgress) + self.options.callbacks.scrollingProgress(self.getScrollProgress()); + }, + resize_debounce = 0, + resizeEv = function() { + clearTimeout(resize_debounce); + resize_debounce = setTimeout(self.refresh, 100); + } + on('scroll', self.scroll_elem, scrollEv); + on('resize', window, resizeEv); + + // public methods + self.destroy = function(clean) { + off('scroll', self.scroll_elem, scrollEv); + off('resize', window, resizeEv); + self.html((clean ? self.generateEmptyRow() : rows).join('')); + } + self.refresh = function(force) { + if(self.getRowsHeight(rows) || force) self.update(rows); + } + self.update = function(new_rows) { + rows = isArray(new_rows) + ? new_rows + : []; + var scroll_top = self.scroll_elem.scrollTop; + // fixes #39 + if(rows.length * self.options.item_height < scroll_top) { + self.scroll_elem.scrollTop = 0; + last_cluster = 0; + } + self.insertToDOM(rows, cache); + self.scroll_elem.scrollTop = scroll_top; + } + self.clear = function() { + self.update([]); + } + self.getRowsAmount = function() { + return rows.length; + } + self.getScrollProgress = function() { + return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; + } + + var add = function(where, _new_rows) { + var new_rows = isArray(_new_rows) + ? _new_rows + : []; + if( ! new_rows.length) return; + rows = where == 'append' + ? rows.concat(new_rows) + : new_rows.concat(rows); + self.insertToDOM(rows, cache); + } + self.append = function(rows) { + add('append', rows); + } + self.prepend = function(rows) { + add('prepend', rows); + } + } + + Clusterize.prototype = { + constructor: Clusterize, + // fetch existing markup + fetchMarkup: function() { + var rows = [], rows_nodes = this.getChildNodes(this.content_elem); + while (rows_nodes.length) { + rows.push(rows_nodes.shift().outerHTML); + } + return rows; + }, + // get tag name, content tag name, tag height, calc cluster height + exploreEnvironment: function(rows, cache) { + var opts = this.options; + opts.content_tag = this.content_elem.tagName.toLowerCase(); + if( ! rows.length) return; + if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); + if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); + if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); + this.getRowsHeight(rows); + }, + getRowsHeight: function(rows) { + var opts = this.options, + prev_item_height = opts.item_height; + opts.cluster_height = 0; + if( ! rows.length) return; + var nodes = this.content_elem.children; + var node = nodes[Math.floor(nodes.length / 2)]; + opts.item_height = node.offsetHeight; + // consider table's border-spacing + if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') + opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; + // consider margins (and margins collapsing) + if(opts.tag != 'tr') { + var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; + var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; + opts.item_height += Math.max(marginTop, marginBottom); + } + opts.block_height = opts.item_height * opts.rows_in_block; + opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; + opts.cluster_height = opts.blocks_in_cluster * opts.block_height; + return prev_item_height != opts.item_height; + }, + // get current cluster number + getClusterNum: function () { + this.options.scroll_top = this.scroll_elem.scrollTop; + return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; + }, + // generate empty row if no data provided + generateEmptyRow: function() { + var opts = this.options; + if( ! opts.tag || ! opts.show_no_data_row) return []; + var empty_row = document.createElement(opts.tag), + no_data_content = document.createTextNode(opts.no_data_text), td; + empty_row.className = opts.no_data_class; + if(opts.tag == 'tr') { + td = document.createElement('td'); + // fixes #53 + td.colSpan = 100; + td.appendChild(no_data_content); + } + empty_row.appendChild(td || no_data_content); + return [empty_row.outerHTML]; + }, + // generate cluster for current scroll position + generate: function (rows, cluster_num) { + var opts = this.options, + rows_len = rows.length; + if (rows_len < opts.rows_in_block) { + return { + top_offset: 0, + bottom_offset: 0, + rows_above: 0, + rows: rows_len ? rows : this.generateEmptyRow() + } + } + var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), + items_end = items_start + opts.rows_in_cluster, + top_offset = Math.max(items_start * opts.item_height, 0), + bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), + this_cluster_rows = [], + rows_above = items_start; + if(top_offset < 1) { + rows_above++; + } + for (var i = items_start; i < items_end; i++) { + rows[i] && this_cluster_rows.push(rows[i]); + } + return { + top_offset: top_offset, + bottom_offset: bottom_offset, + rows_above: rows_above, + rows: this_cluster_rows + } + }, + renderExtraTag: function(class_name, height) { + var tag = document.createElement(this.options.tag), + clusterize_prefix = 'clusterize-'; + tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); + height && (tag.style.height = height + 'px'); + return tag.outerHTML; + }, + // if necessary verify data changed and insert to DOM + insertToDOM: function(rows, cache) { + // explore row's height + if( ! this.options.cluster_height) { + this.exploreEnvironment(rows, cache); + } + var data = this.generate(rows, this.getClusterNum()), + this_cluster_rows = data.rows.join(''), + this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), + top_offset_changed = this.checkChanges('top', data.top_offset, cache), + only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), + callbacks = this.options.callbacks, + layout = []; + + if(this_cluster_content_changed || top_offset_changed) { + if(data.top_offset) { + this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); + layout.push(this.renderExtraTag('top-space', data.top_offset)); + } + layout.push(this_cluster_rows); + data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); + callbacks.clusterWillChange && callbacks.clusterWillChange(); + this.html(layout.join('')); + this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); + callbacks.clusterChanged && callbacks.clusterChanged(); + } else if(only_bottom_offset_changed) { + this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; + } + }, + // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround + html: function(data) { + var content_elem = this.content_elem; + if(ie && ie <= 9 && this.options.tag == 'tr') { + var div = document.createElement('div'), last; + div.innerHTML = '' + data + '
'; + while((last = content_elem.lastChild)) { + content_elem.removeChild(last); + } + var rows_nodes = this.getChildNodes(div.firstChild.firstChild); + while (rows_nodes.length) { + content_elem.appendChild(rows_nodes.shift()); + } + } else { + content_elem.innerHTML = data; + } + }, + getChildNodes: function(tag) { + var child_nodes = tag.children, nodes = []; + for (var i = 0, ii = child_nodes.length; i < ii; i++) { + nodes.push(child_nodes[i]); + } + return nodes; + }, + checkChanges: function(type, value, cache) { + var changed = value != cache[type]; + cache[type] = value; + return changed; + } + } + + // support functions + function on(evt, element, fnc) { + return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); + } + function off(evt, element, fnc) { + return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); + } + function isArray(arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + } + function getStyle(prop, elem) { + return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; + } + + return Clusterize; +}));/** + * 表示当前对象 + * + * Created by GUY on 2015/9/7. + * @class BI.VirtualList + * @extends BI.Widget + */ +BI.VirtualList = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-virtual-list clusterize-scroll", + }; + }, + render: function () { + var self = this, o = this.options; + return { + type: "bi.default", + items: [{ + type: "bi.layout", + ref: function () { + self.contentEl = this; + }, + cls: "clusterize-content" + }] + } + }, + + mounted: function () { + var data = []; + for (var i = 0; i < 10000; i++) { + data.push("
" + i + "
"); + } + new Clusterize({ + rows: data, + scrollElem: this.element[0], + contentElem: this.contentEl.element[0] + }) + }, + + populate: function () { + } +}); +BI.shortcut('bi.virtual_list', BI.VirtualList);/** * 分页控件 * * Created by GUY on 2015/8/31. diff --git a/docs/demo.js b/docs/demo.js index e7fa71450f..7542faa5b0 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -3038,6 +3038,10 @@ Demo.COMPONENT_CONFIG = [{ pId: 102, text: "bi.collection_view", value: "demo.collection_view" +},{ + pId: 102, + text: "bi.virtual_list", + value: "demo.virtual_list" }, { pId: 102, id: 10201, @@ -3476,6 +3480,16 @@ BI.shortcut("demo.virtual_group_item", Demo.Item);Demo.Func = BI.inherit(BI.Widg props: { baseCls: "demo-func" }, + render: function () { + return { + type: "bi.virtual_list" + } + } +}); +BI.shortcut("demo.virtual_list", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, _createDefaultTree: function () { var TREEITEMS = [{id: -1, pId: -2, value: "根目录", open: true, type: "bi.plus_group_node", height: 25}, diff --git a/src/base/list/clusterize.js b/src/base/list/clusterize.js new file mode 100644 index 0000000000..63c59e2baf --- /dev/null +++ b/src/base/list/clusterize.js @@ -0,0 +1,329 @@ +/*! Clusterize.js - v0.17.6 - 2017-03-05 + * http://NeXTs.github.com/Clusterize.js/ + * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ + +;(function(name, definition) { + if (typeof module != 'undefined') module.exports = definition(); + else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); + else this[name] = definition(); +}('Clusterize', function() { + "use strict" + + // detect ie9 and lower + // https://gist.github.com/padolsey/527683#comment-786682 + var ie = (function(){ + for( var v = 3, + el = document.createElement('b'), + all = el.all || []; + el.innerHTML = '', + all[0]; + ){} + return v > 4 ? v : document.documentMode; + }()), + is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; + var Clusterize = function(data) { + if( ! (this instanceof Clusterize)) + return new Clusterize(data); + var self = this; + + var defaults = { + rows_in_block: 50, + blocks_in_cluster: 4, + tag: null, + show_no_data_row: true, + no_data_class: 'clusterize-no-data', + no_data_text: 'No data', + keep_parity: true, + callbacks: {} + } + + // public parameters + self.options = {}; + var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; + for(var i = 0, option; option = options[i]; i++) { + self.options[option] = typeof data[option] != 'undefined' && data[option] != null + ? data[option] + : defaults[option]; + } + + var elems = ['scroll', 'content']; + for(var i = 0, elem; elem = elems[i]; i++) { + self[elem + '_elem'] = data[elem + 'Id'] + ? document.getElementById(data[elem + 'Id']) + : data[elem + 'Elem']; + if( ! self[elem + '_elem']) + throw new Error("Error! Could not find " + elem + " element"); + } + + // tabindex forces the browser to keep focus on the scrolling list, fixes #11 + if( ! self.content_elem.hasAttribute('tabindex')) + self.content_elem.setAttribute('tabindex', 0); + + // private parameters + var rows = isArray(data.rows) + ? data.rows + : self.fetchMarkup(), + cache = {}, + scroll_top = self.scroll_elem.scrollTop; + + // append initial data + self.insertToDOM(rows, cache); + + // restore the scroll position + self.scroll_elem.scrollTop = scroll_top; + + // adding scroll handler + var last_cluster = false, + scroll_debounce = 0, + pointer_events_set = false, + scrollEv = function() { + // fixes scrolling issue on Mac #3 + if (is_mac) { + if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; + pointer_events_set = true; + clearTimeout(scroll_debounce); + scroll_debounce = setTimeout(function () { + self.content_elem.style.pointerEvents = 'auto'; + pointer_events_set = false; + }, 50); + } + if (last_cluster != (last_cluster = self.getClusterNum())) + self.insertToDOM(rows, cache); + if (self.options.callbacks.scrollingProgress) + self.options.callbacks.scrollingProgress(self.getScrollProgress()); + }, + resize_debounce = 0, + resizeEv = function() { + clearTimeout(resize_debounce); + resize_debounce = setTimeout(self.refresh, 100); + } + on('scroll', self.scroll_elem, scrollEv); + on('resize', window, resizeEv); + + // public methods + self.destroy = function(clean) { + off('scroll', self.scroll_elem, scrollEv); + off('resize', window, resizeEv); + self.html((clean ? self.generateEmptyRow() : rows).join('')); + } + self.refresh = function(force) { + if(self.getRowsHeight(rows) || force) self.update(rows); + } + self.update = function(new_rows) { + rows = isArray(new_rows) + ? new_rows + : []; + var scroll_top = self.scroll_elem.scrollTop; + // fixes #39 + if(rows.length * self.options.item_height < scroll_top) { + self.scroll_elem.scrollTop = 0; + last_cluster = 0; + } + self.insertToDOM(rows, cache); + self.scroll_elem.scrollTop = scroll_top; + } + self.clear = function() { + self.update([]); + } + self.getRowsAmount = function() { + return rows.length; + } + self.getScrollProgress = function() { + return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; + } + + var add = function(where, _new_rows) { + var new_rows = isArray(_new_rows) + ? _new_rows + : []; + if( ! new_rows.length) return; + rows = where == 'append' + ? rows.concat(new_rows) + : new_rows.concat(rows); + self.insertToDOM(rows, cache); + } + self.append = function(rows) { + add('append', rows); + } + self.prepend = function(rows) { + add('prepend', rows); + } + } + + Clusterize.prototype = { + constructor: Clusterize, + // fetch existing markup + fetchMarkup: function() { + var rows = [], rows_nodes = this.getChildNodes(this.content_elem); + while (rows_nodes.length) { + rows.push(rows_nodes.shift().outerHTML); + } + return rows; + }, + // get tag name, content tag name, tag height, calc cluster height + exploreEnvironment: function(rows, cache) { + var opts = this.options; + opts.content_tag = this.content_elem.tagName.toLowerCase(); + if( ! rows.length) return; + if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); + if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); + if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); + this.getRowsHeight(rows); + }, + getRowsHeight: function(rows) { + var opts = this.options, + prev_item_height = opts.item_height; + opts.cluster_height = 0; + if( ! rows.length) return; + var nodes = this.content_elem.children; + var node = nodes[Math.floor(nodes.length / 2)]; + opts.item_height = node.offsetHeight; + // consider table's border-spacing + if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') + opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; + // consider margins (and margins collapsing) + if(opts.tag != 'tr') { + var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; + var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; + opts.item_height += Math.max(marginTop, marginBottom); + } + opts.block_height = opts.item_height * opts.rows_in_block; + opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; + opts.cluster_height = opts.blocks_in_cluster * opts.block_height; + return prev_item_height != opts.item_height; + }, + // get current cluster number + getClusterNum: function () { + this.options.scroll_top = this.scroll_elem.scrollTop; + return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; + }, + // generate empty row if no data provided + generateEmptyRow: function() { + var opts = this.options; + if( ! opts.tag || ! opts.show_no_data_row) return []; + var empty_row = document.createElement(opts.tag), + no_data_content = document.createTextNode(opts.no_data_text), td; + empty_row.className = opts.no_data_class; + if(opts.tag == 'tr') { + td = document.createElement('td'); + // fixes #53 + td.colSpan = 100; + td.appendChild(no_data_content); + } + empty_row.appendChild(td || no_data_content); + return [empty_row.outerHTML]; + }, + // generate cluster for current scroll position + generate: function (rows, cluster_num) { + var opts = this.options, + rows_len = rows.length; + if (rows_len < opts.rows_in_block) { + return { + top_offset: 0, + bottom_offset: 0, + rows_above: 0, + rows: rows_len ? rows : this.generateEmptyRow() + } + } + var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), + items_end = items_start + opts.rows_in_cluster, + top_offset = Math.max(items_start * opts.item_height, 0), + bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), + this_cluster_rows = [], + rows_above = items_start; + if(top_offset < 1) { + rows_above++; + } + for (var i = items_start; i < items_end; i++) { + rows[i] && this_cluster_rows.push(rows[i]); + } + return { + top_offset: top_offset, + bottom_offset: bottom_offset, + rows_above: rows_above, + rows: this_cluster_rows + } + }, + renderExtraTag: function(class_name, height) { + var tag = document.createElement(this.options.tag), + clusterize_prefix = 'clusterize-'; + tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); + height && (tag.style.height = height + 'px'); + return tag.outerHTML; + }, + // if necessary verify data changed and insert to DOM + insertToDOM: function(rows, cache) { + // explore row's height + if( ! this.options.cluster_height) { + this.exploreEnvironment(rows, cache); + } + var data = this.generate(rows, this.getClusterNum()), + this_cluster_rows = data.rows.join(''), + this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), + top_offset_changed = this.checkChanges('top', data.top_offset, cache), + only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), + callbacks = this.options.callbacks, + layout = []; + + if(this_cluster_content_changed || top_offset_changed) { + if(data.top_offset) { + this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); + layout.push(this.renderExtraTag('top-space', data.top_offset)); + } + layout.push(this_cluster_rows); + data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); + callbacks.clusterWillChange && callbacks.clusterWillChange(); + this.html(layout.join('')); + this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); + callbacks.clusterChanged && callbacks.clusterChanged(); + } else if(only_bottom_offset_changed) { + this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; + } + }, + // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround + html: function(data) { + var content_elem = this.content_elem; + if(ie && ie <= 9 && this.options.tag == 'tr') { + var div = document.createElement('div'), last; + div.innerHTML = '' + data + '
'; + while((last = content_elem.lastChild)) { + content_elem.removeChild(last); + } + var rows_nodes = this.getChildNodes(div.firstChild.firstChild); + while (rows_nodes.length) { + content_elem.appendChild(rows_nodes.shift()); + } + } else { + content_elem.innerHTML = data; + } + }, + getChildNodes: function(tag) { + var child_nodes = tag.children, nodes = []; + for (var i = 0, ii = child_nodes.length; i < ii; i++) { + nodes.push(child_nodes[i]); + } + return nodes; + }, + checkChanges: function(type, value, cache) { + var changed = value != cache[type]; + cache[type] = value; + return changed; + } + } + + // support functions + function on(evt, element, fnc) { + return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); + } + function off(evt, element, fnc) { + return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); + } + function isArray(arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + } + function getStyle(prop, elem) { + return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; + } + + return Clusterize; +})); \ No newline at end of file diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js new file mode 100644 index 0000000000..aca28e1979 --- /dev/null +++ b/src/base/list/virtuallist.js @@ -0,0 +1,43 @@ +/** + * 表示当前对象 + * + * Created by GUY on 2015/9/7. + * @class BI.VirtualList + * @extends BI.Widget + */ +BI.VirtualList = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-virtual-list clusterize-scroll", + }; + }, + render: function () { + var self = this, o = this.options; + return { + type: "bi.default", + items: [{ + type: "bi.layout", + ref: function () { + self.contentEl = this; + }, + cls: "clusterize-content" + }] + } + }, + + mounted: function () { + var data = []; + for (var i = 0; i < 10000; i++) { + data.push("
" + i + "
"); + } + new Clusterize({ + rows: data, + scrollElem: this.element[0], + contentElem: this.contentEl.element[0] + }) + }, + + populate: function () { + } +}); +BI.shortcut('bi.virtual_list', BI.VirtualList); \ No newline at end of file diff --git a/src/base/tree/treeview.js b/src/base/tree/treeview.js index 37c66d55a0..0326b38ae7 100644 --- a/src/base/tree/treeview.js +++ b/src/base/tree/treeview.js @@ -443,6 +443,7 @@ BI.TreeView = BI.inherit(BI.Pane, { this.nodes && this.nodes.expandAll(flag); }, + //设置树节点的状态 setValue: function (value, param) { this.setSelectedValue(value); this.checkAll(false); @@ -470,12 +471,6 @@ BI.TreeView = BI.inherit(BI.Pane, { }); }, - getExpandedValue: function () { - if (!this.nodes) { - return null; - } - }, - refresh: function () { this.nodes && this.nodes.refresh(); }, diff --git a/src/less/base/list/clusterize.less b/src/less/base/list/clusterize.less new file mode 100644 index 0000000000..6aafca8652 --- /dev/null +++ b/src/less/base/list/clusterize.less @@ -0,0 +1,36 @@ +/* max-height - the only parameter in this file that needs to be edited. + * Change it to suit your needs. The rest is recommended to leave as is. + */ +.clusterize-scroll{ + overflow: auto; +} + +/** + * Avoid vertical margins for extra tags + * Necessary for correct calculations when rows have nonzero vertical margins + */ +.clusterize-extra-row{ + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +/* By default extra tag .clusterize-keep-parity added to keep parity of rows. + * Useful when used :nth-child(even/odd) + */ +.clusterize-extra-row.clusterize-keep-parity{ + display: none; +} + +/* During initialization clusterize adds tabindex to force the browser to keep focus + * on the scrolling list, see issue #11 + * Outline removes default browser's borders for focused elements. + */ +.clusterize-content{ + outline: 0; +} + +/* Centering message that appears when no data provided + */ +.clusterize-no-data td{ + text-align: center; +} \ No newline at end of file From e5fd174d7fb88e90f8d7a1164056ce580f4f590e Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 21 May 2017 21:11:13 +0800 Subject: [PATCH 10/27] add --- src/css/base/list/clusterize.css | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/css/base/list/clusterize.css diff --git a/src/css/base/list/clusterize.css b/src/css/base/list/clusterize.css new file mode 100644 index 0000000000..2b8d17ee55 --- /dev/null +++ b/src/css/base/list/clusterize.css @@ -0,0 +1,32 @@ +/* max-height - the only parameter in this file that needs to be edited. + * Change it to suit your needs. The rest is recommended to leave as is. + */ +.clusterize-scroll { + overflow: auto; +} +/** + * Avoid vertical margins for extra tags + * Necessary for correct calculations when rows have nonzero vertical margins + */ +.clusterize-extra-row { + margin-top: 0 !important; + margin-bottom: 0 !important; +} +/* By default extra tag .clusterize-keep-parity added to keep parity of rows. + * Useful when used :nth-child(even/odd) + */ +.clusterize-extra-row.clusterize-keep-parity { + display: none; +} +/* During initialization clusterize adds tabindex to force the browser to keep focus + * on the scrolling list, see issue #11 + * Outline removes default browser's borders for focused elements. + */ +.clusterize-content { + outline: 0; +} +/* Centering message that appears when no data provided + */ +.clusterize-no-data td { + text-align: center; +} From 9b09376aec21d96e58a8146f02f676e50803ac59 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 21 May 2017 22:59:19 +0800 Subject: [PATCH 11/27] add --- src/base/foundation/{bi.message.js => message.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/base/foundation/{bi.message.js => message.js} (100%) diff --git a/src/base/foundation/bi.message.js b/src/base/foundation/message.js similarity index 100% rename from src/base/foundation/bi.message.js rename to src/base/foundation/message.js From d391ed5550713ade658b3b96800d88cd9575cf9b Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 22 May 2017 09:30:41 +0800 Subject: [PATCH 12/27] add --- bi/base.js | 7 +++++++ bi/case.js | 12 ++++++++++++ bi/widget.js | 4 +++- docs/base.js | 7 +++++++ docs/case.js | 12 ++++++++++++ docs/widget.js | 4 +++- src/base/single/button/button.basic.js | 7 +++++++ src/case/toolbar/toolbar.multiselect.js | 12 ++++++++++++ src/widget/sequencetable/treenumber.sequencetable.js | 4 +++- 9 files changed, 66 insertions(+), 3 deletions(-) diff --git a/bi/base.js b/bi/base.js index b17b359288..cace48d533 100644 --- a/bi/base.js +++ b/bi/base.js @@ -817,12 +817,19 @@ BI.BasicButton = BI.inherit(BI.Single, { }, _doClick: function () { + if (this.isValid()) { + this.beforeClick(); + } this._trigger(); if (this.isValid()) { this.doClick(); } }, + beforeClick: function () { + + }, + doClick: function () { }, diff --git a/bi/case.js b/bi/case.js index 00223d3cbc..668dfc0646 100644 --- a/bi/case.js +++ b/bi/case.js @@ -10269,6 +10269,8 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, + //手动控制选中 + disableSelected: true, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -10331,6 +10333,16 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, + //自己手动控制选中 + beforeClick: function () { + var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); + if (isHalf === true) { + this.setSelected(true); + } else { + this.setSelected(!isSelected); + } + }, + setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); diff --git a/bi/widget.js b/bi/widget.js index 5ff973be8f..778e5221f4 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -79,7 +79,9 @@ BI.SequenceTableTreeNumber = BI.inherit(BI.Widget, { var cnt = this.start; function track(node) { - self.cache[node.text || node.value] = cnt++; + //如果已经有缓存了就不改计数了,复杂表会出现这种情况 + self.cache[node.text || node.value] || (self.cache[node.text || node.value] = cnt); + cnt++; } BI.each(nodes, function (i, node) { diff --git a/docs/base.js b/docs/base.js index b17b359288..cace48d533 100644 --- a/docs/base.js +++ b/docs/base.js @@ -817,12 +817,19 @@ BI.BasicButton = BI.inherit(BI.Single, { }, _doClick: function () { + if (this.isValid()) { + this.beforeClick(); + } this._trigger(); if (this.isValid()) { this.doClick(); } }, + beforeClick: function () { + + }, + doClick: function () { }, diff --git a/docs/case.js b/docs/case.js index 00223d3cbc..668dfc0646 100644 --- a/docs/case.js +++ b/docs/case.js @@ -10269,6 +10269,8 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, + //手动控制选中 + disableSelected: true, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -10331,6 +10333,16 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, + //自己手动控制选中 + beforeClick: function () { + var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); + if (isHalf === true) { + this.setSelected(true); + } else { + this.setSelected(!isSelected); + } + }, + setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); diff --git a/docs/widget.js b/docs/widget.js index 5ff973be8f..778e5221f4 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -79,7 +79,9 @@ BI.SequenceTableTreeNumber = BI.inherit(BI.Widget, { var cnt = this.start; function track(node) { - self.cache[node.text || node.value] = cnt++; + //如果已经有缓存了就不改计数了,复杂表会出现这种情况 + self.cache[node.text || node.value] || (self.cache[node.text || node.value] = cnt); + cnt++; } BI.each(nodes, function (i, node) { diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js index 8e1079af03..636fb51d4b 100644 --- a/src/base/single/button/button.basic.js +++ b/src/base/single/button/button.basic.js @@ -234,12 +234,19 @@ BI.BasicButton = BI.inherit(BI.Single, { }, _doClick: function () { + if (this.isValid()) { + this.beforeClick(); + } this._trigger(); if (this.isValid()) { this.doClick(); } }, + beforeClick: function () { + + }, + doClick: function () { }, diff --git a/src/case/toolbar/toolbar.multiselect.js b/src/case/toolbar/toolbar.multiselect.js index 7a1497d8d9..156398c47e 100644 --- a/src/case/toolbar/toolbar.multiselect.js +++ b/src/case/toolbar/toolbar.multiselect.js @@ -12,6 +12,8 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { height: 25, text: BI.i18nText('BI-Select_All'), isAllCheckedBySelectedValue: BI.emptyFn, + //手动控制选中 + disableSelected: true, isHalfCheckedBySelectedValue: function (selectedValues) { return selectedValues.length > 0; } @@ -74,6 +76,16 @@ BI.MultiSelectBar = BI.inherit(BI.BasicButton, { this.half.invisible(); }, + //自己手动控制选中 + beforeClick: function () { + var isHalf = this.isHalfSelected(), isSelected = this.isSelected(); + if (isHalf === true) { + this.setSelected(true); + } else { + this.setSelected(!isSelected); + } + }, + setSelected: function (v) { this.checkbox.setSelected(v); this.setHalfSelected(false); diff --git a/src/widget/sequencetable/treenumber.sequencetable.js b/src/widget/sequencetable/treenumber.sequencetable.js index d1ae137dc0..6a1fff133d 100644 --- a/src/widget/sequencetable/treenumber.sequencetable.js +++ b/src/widget/sequencetable/treenumber.sequencetable.js @@ -79,7 +79,9 @@ BI.SequenceTableTreeNumber = BI.inherit(BI.Widget, { var cnt = this.start; function track(node) { - self.cache[node.text || node.value] = cnt++; + //如果已经有缓存了就不改计数了,复杂表会出现这种情况 + self.cache[node.text || node.value] || (self.cache[node.text || node.value] = cnt); + cnt++; } BI.each(nodes, function (i, node) { From 9ebd618bf866ebc1994e2e7234010caef6940ac2 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Mon, 22 May 2017 10:23:54 +0800 Subject: [PATCH 13/27] _setValid --- bi/base.js | 8 ++++---- docs/base.js | 8 ++++---- src/base/single/editor/editor.textarea.js | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bi/base.js b/bi/base.js index cace48d533..a87574fc00 100644 --- a/bi/base.js +++ b/bi/base.js @@ -18487,10 +18487,10 @@ BI.TextAreaEditor = BI.inherit(BI.Single, { return this.style; }, - setValid: function (b) { - BI.TextAreaEditor.superclass.setValid.apply(this, arguments); - this.content.setValid(b); - this.watermark && this.watermark.setValid(b); + _setValid: function (b) { + BI.TextAreaEditor.superclass._setValid.apply(this, arguments); + // this.content.setValid(b); + // this.watermark && this.watermark.setValid(b); } }); BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/docs/base.js b/docs/base.js index cace48d533..a87574fc00 100644 --- a/docs/base.js +++ b/docs/base.js @@ -18487,10 +18487,10 @@ BI.TextAreaEditor = BI.inherit(BI.Single, { return this.style; }, - setValid: function (b) { - BI.TextAreaEditor.superclass.setValid.apply(this, arguments); - this.content.setValid(b); - this.watermark && this.watermark.setValid(b); + _setValid: function (b) { + BI.TextAreaEditor.superclass._setValid.apply(this, arguments); + // this.content.setValid(b); + // this.watermark && this.watermark.setValid(b); } }); BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; diff --git a/src/base/single/editor/editor.textarea.js b/src/base/single/editor/editor.textarea.js index 15c6bc7a15..97d94290c3 100644 --- a/src/base/single/editor/editor.textarea.js +++ b/src/base/single/editor/editor.textarea.js @@ -149,10 +149,10 @@ BI.TextAreaEditor = BI.inherit(BI.Single, { return this.style; }, - setValid: function (b) { - BI.TextAreaEditor.superclass.setValid.apply(this, arguments); - this.content.setValid(b); - this.watermark && this.watermark.setValid(b); + _setValid: function (b) { + BI.TextAreaEditor.superclass._setValid.apply(this, arguments); + // this.content.setValid(b); + // this.watermark && this.watermark.setValid(b); } }); BI.TextAreaEditor.EVENT_CHANGE = "EVENT_CHANGE"; From 15d00c210fb469938ff9268d5b86f7a46b973bbf Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Mon, 22 May 2017 10:40:18 +0800 Subject: [PATCH 14/27] update --- bi/base.js | 9 ++------- bi/case.js | 11 +---------- docs/base.js | 9 ++------- docs/case.js | 11 +---------- src/base/single/editor/editor.js | 5 ----- src/base/single/input/input.js | 4 ++-- src/case/editor/editor.search.js | 6 +----- src/case/editor/editor.sign.js | 5 ----- 8 files changed, 9 insertions(+), 51 deletions(-) diff --git a/bi/base.js b/bi/base.js index a87574fc00..37c398684d 100644 --- a/bi/base.js +++ b/bi/base.js @@ -18216,11 +18216,6 @@ BI.Editor = BI.inherit(BI.Single, { return BI.trim(this.editor.getValue()); }, - setValid: function (b) { - BI.Editor.superclass.setValid.apply(this, arguments); - this.editor.setValid(b); - }, - isEditing: function () { return this.editor.isEditing(); }, @@ -19483,8 +19478,8 @@ BI.Input = BI.inherit(BI.Single, { return this._lastValidValue; }, - setValid: function () { - BI.Input.superclass.setValid.apply(this, arguments); + _setValid: function () { + BI.Input.superclass._setValid.apply(this, arguments); if (this.isValid()) { this._lastValidValue = this.getValue(); this.element.removeClass("bi-input-error"); diff --git a/bi/case.js b/bi/case.js index 668dfc0646..240ab1d94f 100644 --- a/bi/case.js +++ b/bi/case.js @@ -5184,11 +5184,7 @@ BI.SearchEditor = BI.inherit(BI.Widget, { this.clear.visible(); } }, - - setValid: function (b) { - this.editor.setValid(b); - }, - + isEditing: function () { return this.editor.isEditing(); }, @@ -5867,11 +5863,6 @@ BI.SignEditor = BI.inherit(BI.Widget, { return this.editor.isValid(); }, - setValid: function (v) { - BI.SignEditor.superclass.setValid.apply(this, arguments); - this.editor.setValid(v); - }, - setErrorText: function (text) { this.editor.setErrorText(text); }, diff --git a/docs/base.js b/docs/base.js index a87574fc00..37c398684d 100644 --- a/docs/base.js +++ b/docs/base.js @@ -18216,11 +18216,6 @@ BI.Editor = BI.inherit(BI.Single, { return BI.trim(this.editor.getValue()); }, - setValid: function (b) { - BI.Editor.superclass.setValid.apply(this, arguments); - this.editor.setValid(b); - }, - isEditing: function () { return this.editor.isEditing(); }, @@ -19483,8 +19478,8 @@ BI.Input = BI.inherit(BI.Single, { return this._lastValidValue; }, - setValid: function () { - BI.Input.superclass.setValid.apply(this, arguments); + _setValid: function () { + BI.Input.superclass._setValid.apply(this, arguments); if (this.isValid()) { this._lastValidValue = this.getValue(); this.element.removeClass("bi-input-error"); diff --git a/docs/case.js b/docs/case.js index 668dfc0646..240ab1d94f 100644 --- a/docs/case.js +++ b/docs/case.js @@ -5184,11 +5184,7 @@ BI.SearchEditor = BI.inherit(BI.Widget, { this.clear.visible(); } }, - - setValid: function (b) { - this.editor.setValid(b); - }, - + isEditing: function () { return this.editor.isEditing(); }, @@ -5867,11 +5863,6 @@ BI.SignEditor = BI.inherit(BI.Widget, { return this.editor.isValid(); }, - setValid: function (v) { - BI.SignEditor.superclass.setValid.apply(this, arguments); - this.editor.setValid(v); - }, - setErrorText: function (text) { this.editor.setErrorText(text); }, diff --git a/src/base/single/editor/editor.js b/src/base/single/editor/editor.js index b352506e29..a0a684474a 100644 --- a/src/base/single/editor/editor.js +++ b/src/base/single/editor/editor.js @@ -292,11 +292,6 @@ BI.Editor = BI.inherit(BI.Single, { return BI.trim(this.editor.getValue()); }, - setValid: function (b) { - BI.Editor.superclass.setValid.apply(this, arguments); - this.editor.setValid(b); - }, - isEditing: function () { return this.editor.isEditing(); }, diff --git a/src/base/single/input/input.js b/src/base/single/input/input.js index 06d59168ec..48c17ebcbb 100644 --- a/src/base/single/input/input.js +++ b/src/base/single/input/input.js @@ -241,8 +241,8 @@ BI.Input = BI.inherit(BI.Single, { return this._lastValidValue; }, - setValid: function () { - BI.Input.superclass.setValid.apply(this, arguments); + _setValid: function () { + BI.Input.superclass._setValid.apply(this, arguments); if (this.isValid()) { this._lastValidValue = this.getValue(); this.element.removeClass("bi-input-error"); diff --git a/src/case/editor/editor.search.js b/src/case/editor/editor.search.js index 1cad5eb312..4658b9d9f4 100644 --- a/src/case/editor/editor.search.js +++ b/src/case/editor/editor.search.js @@ -157,11 +157,7 @@ BI.SearchEditor = BI.inherit(BI.Widget, { this.clear.visible(); } }, - - setValid: function (b) { - this.editor.setValid(b); - }, - + isEditing: function () { return this.editor.isEditing(); }, diff --git a/src/case/editor/editor.sign.js b/src/case/editor/editor.sign.js index 13e39bc73a..2c148209e9 100644 --- a/src/case/editor/editor.sign.js +++ b/src/case/editor/editor.sign.js @@ -206,11 +206,6 @@ BI.SignEditor = BI.inherit(BI.Widget, { return this.editor.isValid(); }, - setValid: function (v) { - BI.SignEditor.superclass.setValid.apply(this, arguments); - this.editor.setValid(v); - }, - setErrorText: function (text) { this.editor.setErrorText(text); }, From e1fcbf930f423388b80fb023184d314cf1db86a2 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Mon, 22 May 2017 15:38:10 +0800 Subject: [PATCH 15/27] =?UTF-8?q?=E7=B2=BE=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bi/core.js | 2 +- docs/core.js | 2 +- src/core/proto/number.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bi/core.js b/bi/core.js index de5f6d5d1f..2cd75c8d9d 100644 --- a/bi/core.js +++ b/bi/core.js @@ -6857,7 +6857,7 @@ function accDiv(arg1, arg2) { with (Math) { r1 = Number(arg1.toString().replace(".", "")); r2 = Number(arg2.toString().replace(".", "")); - return (r1 / r2) * pow(10, t2 - t1); + return (t2 > t1) ? (r1 / r2) * pow(10, t2 - t1) : (r1 / r2) / pow(10, t1 - t2); } } diff --git a/docs/core.js b/docs/core.js index 4b80066049..2111af08a7 100644 --- a/docs/core.js +++ b/docs/core.js @@ -24390,7 +24390,7 @@ function accDiv(arg1, arg2) { with (Math) { r1 = Number(arg1.toString().replace(".", "")); r2 = Number(arg2.toString().replace(".", "")); - return (r1 / r2) * pow(10, t2 - t1); + return (t2 > t1) ? (r1 / r2) * pow(10, t2 - t1) : (r1 / r2) / pow(10, t1 - t2); } } diff --git a/src/core/proto/number.js b/src/core/proto/number.js index 4a002b71b9..45f5656e64 100644 --- a/src/core/proto/number.js +++ b/src/core/proto/number.js @@ -259,7 +259,7 @@ function accDiv(arg1, arg2) { with (Math) { r1 = Number(arg1.toString().replace(".", "")); r2 = Number(arg2.toString().replace(".", "")); - return (r1 / r2) * pow(10, t2 - t1); + return (t2 > t1) ? (r1 / r2) * pow(10, t2 - t1) : (r1 / r2) / pow(10, t1 - t2); } } From afd1cdbbcb72616161b02a60450906b3cffeb230 Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 22 May 2017 16:26:44 +0800 Subject: [PATCH 16/27] add --- bi/base.css | 32 -- bi/base.js | 502 ++++++------------ bi/core.js | 2 +- demo/js/core/abstract/demo.collection_view.js | 2 + demo/js/core/abstract/demo.grid_view.js | 4 + demo/js/core/abstract/demo.virtual_list.js | 9 +- docs/base.css | 32 -- docs/base.js | 502 ++++++------------ docs/core.js | 2 +- docs/demo.js | 15 +- src/base/collection/collection.js | 4 +- src/base/grid/grid.js | 12 +- src/base/list/clusterize.js | 329 ------------ src/base/list/virtuallist.js | 153 +++++- src/core/utils/prefixIntervalTree.js | 2 +- src/css/base/list/clusterize.css | 32 -- src/less/base/list/clusterize.less | 36 -- 17 files changed, 472 insertions(+), 1198 deletions(-) delete mode 100644 src/base/list/clusterize.js delete mode 100644 src/css/base/list/clusterize.css delete mode 100644 src/less/base/list/clusterize.less diff --git a/bi/base.css b/bi/base.css index a470b9f270..9a756c5503 100644 --- a/bi/base.css +++ b/bi/base.css @@ -633,38 +633,6 @@ li.CodeMirror-hint-active { cursor: text; font-size: 14px; } -/* max-height - the only parameter in this file that needs to be edited. - * Change it to suit your needs. The rest is recommended to leave as is. - */ -.clusterize-scroll { - overflow: auto; -} -/** - * Avoid vertical margins for extra tags - * Necessary for correct calculations when rows have nonzero vertical margins - */ -.clusterize-extra-row { - margin-top: 0 !important; - margin-bottom: 0 !important; -} -/* By default extra tag .clusterize-keep-parity added to keep parity of rows. - * Useful when used :nth-child(even/odd) - */ -.clusterize-extra-row.clusterize-keep-parity { - display: none; -} -/* During initialization clusterize adds tabindex to force the browser to keep focus - * on the scrolling list, see issue #11 - * Outline removes default browser's borders for focused elements. - */ -.clusterize-content { - outline: 0; -} -/* Centering message that appears when no data provided - */ -.clusterize-no-data td { - text-align: center; -} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ diff --git a/bi/base.js b/bi/base.js index cace48d533..40ab66d6f0 100644 --- a/bi/base.js +++ b/bi/base.js @@ -2530,8 +2530,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, @@ -14671,16 +14671,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, - rowHeightGetter: BI.emptyFn, - columnWidthGetter: BI.emptyFn, - // estimatedColumnSize: 100, - // estimatedRowSize: 30, + rowHeightGetter: BI.emptyFn, //number类型或function类型 + columnWidthGetter: BI.emptyFn, //number类型或function类型 + // estimatedColumnSize: 100, //columnWidthGetter为function时必设 + // estimatedRowSize: 30, //rowHeightGetter为function时必设 scrollLeft: 0, scrollTop: 0, items: [] @@ -15455,335 +15455,7 @@ BI.SearcherView = BI.inherit(BI.Pane, { }); BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2017-03-05 - * http://NeXTs.github.com/Clusterize.js/ - * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ - -;(function(name, definition) { - if (typeof module != 'undefined') module.exports = definition(); - else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); - else this[name] = definition(); -}('Clusterize', function() { - "use strict" - - // detect ie9 and lower - // https://gist.github.com/padolsey/527683#comment-786682 - var ie = (function(){ - for( var v = 3, - el = document.createElement('b'), - all = el.all || []; - el.innerHTML = '', - all[0]; - ){} - return v > 4 ? v : document.documentMode; - }()), - is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; - var Clusterize = function(data) { - if( ! (this instanceof Clusterize)) - return new Clusterize(data); - var self = this; - - var defaults = { - rows_in_block: 50, - blocks_in_cluster: 4, - tag: null, - show_no_data_row: true, - no_data_class: 'clusterize-no-data', - no_data_text: 'No data', - keep_parity: true, - callbacks: {} - } - - // public parameters - self.options = {}; - var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; - for(var i = 0, option; option = options[i]; i++) { - self.options[option] = typeof data[option] != 'undefined' && data[option] != null - ? data[option] - : defaults[option]; - } - - var elems = ['scroll', 'content']; - for(var i = 0, elem; elem = elems[i]; i++) { - self[elem + '_elem'] = data[elem + 'Id'] - ? document.getElementById(data[elem + 'Id']) - : data[elem + 'Elem']; - if( ! self[elem + '_elem']) - throw new Error("Error! Could not find " + elem + " element"); - } - - // tabindex forces the browser to keep focus on the scrolling list, fixes #11 - if( ! self.content_elem.hasAttribute('tabindex')) - self.content_elem.setAttribute('tabindex', 0); - - // private parameters - var rows = isArray(data.rows) - ? data.rows - : self.fetchMarkup(), - cache = {}, - scroll_top = self.scroll_elem.scrollTop; - - // append initial data - self.insertToDOM(rows, cache); - - // restore the scroll position - self.scroll_elem.scrollTop = scroll_top; - - // adding scroll handler - var last_cluster = false, - scroll_debounce = 0, - pointer_events_set = false, - scrollEv = function() { - // fixes scrolling issue on Mac #3 - if (is_mac) { - if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; - pointer_events_set = true; - clearTimeout(scroll_debounce); - scroll_debounce = setTimeout(function () { - self.content_elem.style.pointerEvents = 'auto'; - pointer_events_set = false; - }, 50); - } - if (last_cluster != (last_cluster = self.getClusterNum())) - self.insertToDOM(rows, cache); - if (self.options.callbacks.scrollingProgress) - self.options.callbacks.scrollingProgress(self.getScrollProgress()); - }, - resize_debounce = 0, - resizeEv = function() { - clearTimeout(resize_debounce); - resize_debounce = setTimeout(self.refresh, 100); - } - on('scroll', self.scroll_elem, scrollEv); - on('resize', window, resizeEv); - - // public methods - self.destroy = function(clean) { - off('scroll', self.scroll_elem, scrollEv); - off('resize', window, resizeEv); - self.html((clean ? self.generateEmptyRow() : rows).join('')); - } - self.refresh = function(force) { - if(self.getRowsHeight(rows) || force) self.update(rows); - } - self.update = function(new_rows) { - rows = isArray(new_rows) - ? new_rows - : []; - var scroll_top = self.scroll_elem.scrollTop; - // fixes #39 - if(rows.length * self.options.item_height < scroll_top) { - self.scroll_elem.scrollTop = 0; - last_cluster = 0; - } - self.insertToDOM(rows, cache); - self.scroll_elem.scrollTop = scroll_top; - } - self.clear = function() { - self.update([]); - } - self.getRowsAmount = function() { - return rows.length; - } - self.getScrollProgress = function() { - return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; - } - - var add = function(where, _new_rows) { - var new_rows = isArray(_new_rows) - ? _new_rows - : []; - if( ! new_rows.length) return; - rows = where == 'append' - ? rows.concat(new_rows) - : new_rows.concat(rows); - self.insertToDOM(rows, cache); - } - self.append = function(rows) { - add('append', rows); - } - self.prepend = function(rows) { - add('prepend', rows); - } - } - - Clusterize.prototype = { - constructor: Clusterize, - // fetch existing markup - fetchMarkup: function() { - var rows = [], rows_nodes = this.getChildNodes(this.content_elem); - while (rows_nodes.length) { - rows.push(rows_nodes.shift().outerHTML); - } - return rows; - }, - // get tag name, content tag name, tag height, calc cluster height - exploreEnvironment: function(rows, cache) { - var opts = this.options; - opts.content_tag = this.content_elem.tagName.toLowerCase(); - if( ! rows.length) return; - if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); - if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); - if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); - this.getRowsHeight(rows); - }, - getRowsHeight: function(rows) { - var opts = this.options, - prev_item_height = opts.item_height; - opts.cluster_height = 0; - if( ! rows.length) return; - var nodes = this.content_elem.children; - var node = nodes[Math.floor(nodes.length / 2)]; - opts.item_height = node.offsetHeight; - // consider table's border-spacing - if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') - opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; - // consider margins (and margins collapsing) - if(opts.tag != 'tr') { - var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; - var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; - opts.item_height += Math.max(marginTop, marginBottom); - } - opts.block_height = opts.item_height * opts.rows_in_block; - opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; - opts.cluster_height = opts.blocks_in_cluster * opts.block_height; - return prev_item_height != opts.item_height; - }, - // get current cluster number - getClusterNum: function () { - this.options.scroll_top = this.scroll_elem.scrollTop; - return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; - }, - // generate empty row if no data provided - generateEmptyRow: function() { - var opts = this.options; - if( ! opts.tag || ! opts.show_no_data_row) return []; - var empty_row = document.createElement(opts.tag), - no_data_content = document.createTextNode(opts.no_data_text), td; - empty_row.className = opts.no_data_class; - if(opts.tag == 'tr') { - td = document.createElement('td'); - // fixes #53 - td.colSpan = 100; - td.appendChild(no_data_content); - } - empty_row.appendChild(td || no_data_content); - return [empty_row.outerHTML]; - }, - // generate cluster for current scroll position - generate: function (rows, cluster_num) { - var opts = this.options, - rows_len = rows.length; - if (rows_len < opts.rows_in_block) { - return { - top_offset: 0, - bottom_offset: 0, - rows_above: 0, - rows: rows_len ? rows : this.generateEmptyRow() - } - } - var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), - items_end = items_start + opts.rows_in_cluster, - top_offset = Math.max(items_start * opts.item_height, 0), - bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), - this_cluster_rows = [], - rows_above = items_start; - if(top_offset < 1) { - rows_above++; - } - for (var i = items_start; i < items_end; i++) { - rows[i] && this_cluster_rows.push(rows[i]); - } - return { - top_offset: top_offset, - bottom_offset: bottom_offset, - rows_above: rows_above, - rows: this_cluster_rows - } - }, - renderExtraTag: function(class_name, height) { - var tag = document.createElement(this.options.tag), - clusterize_prefix = 'clusterize-'; - tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); - height && (tag.style.height = height + 'px'); - return tag.outerHTML; - }, - // if necessary verify data changed and insert to DOM - insertToDOM: function(rows, cache) { - // explore row's height - if( ! this.options.cluster_height) { - this.exploreEnvironment(rows, cache); - } - var data = this.generate(rows, this.getClusterNum()), - this_cluster_rows = data.rows.join(''), - this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), - top_offset_changed = this.checkChanges('top', data.top_offset, cache), - only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), - callbacks = this.options.callbacks, - layout = []; - - if(this_cluster_content_changed || top_offset_changed) { - if(data.top_offset) { - this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); - layout.push(this.renderExtraTag('top-space', data.top_offset)); - } - layout.push(this_cluster_rows); - data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); - callbacks.clusterWillChange && callbacks.clusterWillChange(); - this.html(layout.join('')); - this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); - callbacks.clusterChanged && callbacks.clusterChanged(); - } else if(only_bottom_offset_changed) { - this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; - } - }, - // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround - html: function(data) { - var content_elem = this.content_elem; - if(ie && ie <= 9 && this.options.tag == 'tr') { - var div = document.createElement('div'), last; - div.innerHTML = '' + data + '
'; - while((last = content_elem.lastChild)) { - content_elem.removeChild(last); - } - var rows_nodes = this.getChildNodes(div.firstChild.firstChild); - while (rows_nodes.length) { - content_elem.appendChild(rows_nodes.shift()); - } - } else { - content_elem.innerHTML = data; - } - }, - getChildNodes: function(tag) { - var child_nodes = tag.children, nodes = []; - for (var i = 0, ii = child_nodes.length; i < ii; i++) { - nodes.push(child_nodes[i]); - } - return nodes; - }, - checkChanges: function(type, value, cache) { - var changed = value != cache[type]; - cache[type] = value; - return changed; - } - } - - // support functions - function on(evt, element, fnc) { - return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); - } - function off(evt, element, fnc) { - return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); - } - function isArray(arr) { - return Object.prototype.toString.call(arr) === '[object Array]'; - } - function getStyle(prop, elem) { - return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; - } - - return Clusterize; -}));/** +BI.shortcut("bi.searcher_view", BI.SearcherView);/** * 表示当前对象 * * Created by GUY on 2015/9/7. @@ -15793,39 +15465,161 @@ BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2 BI.VirtualList = BI.inherit(BI.Widget, { props: function () { return { - baseCls: "bi-virtual-list clusterize-scroll", + baseCls: "bi-virtual-list", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + items: [] }; }, + + init: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + render: function () { var self = this, o = this.options; return { - type: "bi.default", + type: "bi.vertical", items: [{ type: "bi.layout", ref: function () { - self.contentEl = this; - }, - cls: "clusterize-content" - }] + self.topBlank = this; + } + }, { + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, { + type: "bi.layout", + ref: function () { + self.bottomBlank = this; + } + }], + element: this } }, mounted: function () { - var data = []; - for (var i = 0; i < 10000; i++) { - data.push("
" + i + "
"); - } - new Clusterize({ - rows: data, - scrollElem: this.element[0], - contentElem: this.contentEl.element[0] - }) + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._renderMoreIf(); + }); }, - populate: function () { + _renderMoreIf: function () { + var o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = this.container.element.height() - lastHeight; + this.cache[cnt] = { + index: index, + height: addedHeight + }; + this.tree.set(cnt, addedHeight); + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; + } + }, + + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + // var height = this.element.height(); + // var minContentHeightFrom = o.scrollTop - o.overscanHeight; + // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + // var start = this.tree.greatestLowerBound(minContentHeightFrom); + // var end = this.tree.leastUpperBound(minContentHeightTo); + // var summaryTopHeight = 0; + // this.topBlank.setHeight(0); + // this.bottomBlank.setHeight(0); + // var needDestroyed = []; + // for (var i = 0; i < start; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.topBlank.setHeight(summaryTopHeight); + // } + // } + // summaryTopHeight = 0; + // for (var i = end + 1; i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.bottomBlank.setHeight(summaryTopHeight); + // } + // } + // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + // var currentFragment = firstFragment; + // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // if (!this.cache[i].destroyed) { + // currentFragment = lastFragment; + // } + // if (this.cache[i].destroyed === true) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // var w = this.container._children[j] = BI.createWidget(BI.extend({ + // root: true + // }, BI.stripEL(o.items[j]))); + // currentFragment.appendChild(w.element[0]); + // } + // this.cache[i].destroyed = false; + // } + // } + // this.container.element.prepend(firstFragment); + // this.container.element.append(lastFragment); + // BI.each(needDestroyed, function (i, child) { + // child && child._destroy(); + // }); + }, + + _populate: function () { + var o = this.options; + this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + + populate: function (items) { + + }, + + destroyed: function () { + this.restore(); } }); -BI.shortcut('bi.virtual_list', BI.VirtualList);/** +BI.shortcut('bi.virtual_list', BI.VirtualList); +/** * 分页控件 * * Created by GUY on 2015/8/31. diff --git a/bi/core.js b/bi/core.js index de5f6d5d1f..746f642b87 100644 --- a/bi/core.js +++ b/bi/core.js @@ -9657,7 +9657,7 @@ $.extend(BI, { return new BI.PrefixIntervalTree(xs); }; - BI.PrefixIntervalTree.empty = function () { + BI.PrefixIntervalTree.empty = function (size) { return BI.PrefixIntervalTree.uniform(size, 0); }; diff --git a/demo/js/core/abstract/demo.collection_view.js b/demo/js/core/abstract/demo.collection_view.js index 2867e1ed9a..ab175423ff 100644 --- a/demo/js/core/abstract/demo.collection_view.js +++ b/demo/js/core/abstract/demo.collection_view.js @@ -13,6 +13,8 @@ Demo.Func = BI.inherit(BI.Widget, { } var grid = BI.createWidget({ type: "bi.collection_view", + width: 400, + height: 300, items: items, cellSizeAndPositionGetter: function (index) { return { diff --git a/demo/js/core/abstract/demo.grid_view.js b/demo/js/core/abstract/demo.grid_view.js index 141b77bb59..bea89520b0 100644 --- a/demo/js/core/abstract/demo.grid_view.js +++ b/demo/js/core/abstract/demo.grid_view.js @@ -16,6 +16,10 @@ Demo.Func = BI.inherit(BI.Widget, { } var grid = BI.createWidget({ type: "bi.grid_view", + width: 400, + height: 300, + estimatedRowSize: 30, + estimatedColumnSize: 100, items: items, scrollTop: 100, rowHeightGetter: function () { diff --git a/demo/js/core/abstract/demo.virtual_list.js b/demo/js/core/abstract/demo.virtual_list.js index 792a5d8288..1a8a754d81 100644 --- a/demo/js/core/abstract/demo.virtual_list.js +++ b/demo/js/core/abstract/demo.virtual_list.js @@ -4,7 +4,14 @@ Demo.Func = BI.inherit(BI.Widget, { }, render: function () { return { - type: "bi.virtual_list" + type: "bi.virtual_list", + items: BI.map(BI.makeArray(200, 0), function (i, item) { + return { + type: "bi.label", + height: 30, + text: i + }; + }) } } }); diff --git a/docs/base.css b/docs/base.css index a470b9f270..9a756c5503 100644 --- a/docs/base.css +++ b/docs/base.css @@ -633,38 +633,6 @@ li.CodeMirror-hint-active { cursor: text; font-size: 14px; } -/* max-height - the only parameter in this file that needs to be edited. - * Change it to suit your needs. The rest is recommended to leave as is. - */ -.clusterize-scroll { - overflow: auto; -} -/** - * Avoid vertical margins for extra tags - * Necessary for correct calculations when rows have nonzero vertical margins - */ -.clusterize-extra-row { - margin-top: 0 !important; - margin-bottom: 0 !important; -} -/* By default extra tag .clusterize-keep-parity added to keep parity of rows. - * Useful when used :nth-child(even/odd) - */ -.clusterize-extra-row.clusterize-keep-parity { - display: none; -} -/* During initialization clusterize adds tabindex to force the browser to keep focus - * on the scrolling list, see issue #11 - * Outline removes default browser's borders for focused elements. - */ -.clusterize-content { - outline: 0; -} -/* Centering message that appears when no data provided - */ -.clusterize-no-data td { - text-align: center; -} /****添加计算宽度的--运算符直接需要space****/ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ diff --git a/docs/base.js b/docs/base.js index cace48d533..40ab66d6f0 100644 --- a/docs/base.js +++ b/docs/base.js @@ -2530,8 +2530,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, @@ -14671,16 +14671,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, - rowHeightGetter: BI.emptyFn, - columnWidthGetter: BI.emptyFn, - // estimatedColumnSize: 100, - // estimatedRowSize: 30, + rowHeightGetter: BI.emptyFn, //number类型或function类型 + columnWidthGetter: BI.emptyFn, //number类型或function类型 + // estimatedColumnSize: 100, //columnWidthGetter为function时必设 + // estimatedRowSize: 30, //rowHeightGetter为function时必设 scrollLeft: 0, scrollTop: 0, items: [] @@ -15455,335 +15455,7 @@ BI.SearcherView = BI.inherit(BI.Pane, { }); BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; -BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2017-03-05 - * http://NeXTs.github.com/Clusterize.js/ - * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ - -;(function(name, definition) { - if (typeof module != 'undefined') module.exports = definition(); - else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); - else this[name] = definition(); -}('Clusterize', function() { - "use strict" - - // detect ie9 and lower - // https://gist.github.com/padolsey/527683#comment-786682 - var ie = (function(){ - for( var v = 3, - el = document.createElement('b'), - all = el.all || []; - el.innerHTML = '', - all[0]; - ){} - return v > 4 ? v : document.documentMode; - }()), - is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; - var Clusterize = function(data) { - if( ! (this instanceof Clusterize)) - return new Clusterize(data); - var self = this; - - var defaults = { - rows_in_block: 50, - blocks_in_cluster: 4, - tag: null, - show_no_data_row: true, - no_data_class: 'clusterize-no-data', - no_data_text: 'No data', - keep_parity: true, - callbacks: {} - } - - // public parameters - self.options = {}; - var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; - for(var i = 0, option; option = options[i]; i++) { - self.options[option] = typeof data[option] != 'undefined' && data[option] != null - ? data[option] - : defaults[option]; - } - - var elems = ['scroll', 'content']; - for(var i = 0, elem; elem = elems[i]; i++) { - self[elem + '_elem'] = data[elem + 'Id'] - ? document.getElementById(data[elem + 'Id']) - : data[elem + 'Elem']; - if( ! self[elem + '_elem']) - throw new Error("Error! Could not find " + elem + " element"); - } - - // tabindex forces the browser to keep focus on the scrolling list, fixes #11 - if( ! self.content_elem.hasAttribute('tabindex')) - self.content_elem.setAttribute('tabindex', 0); - - // private parameters - var rows = isArray(data.rows) - ? data.rows - : self.fetchMarkup(), - cache = {}, - scroll_top = self.scroll_elem.scrollTop; - - // append initial data - self.insertToDOM(rows, cache); - - // restore the scroll position - self.scroll_elem.scrollTop = scroll_top; - - // adding scroll handler - var last_cluster = false, - scroll_debounce = 0, - pointer_events_set = false, - scrollEv = function() { - // fixes scrolling issue on Mac #3 - if (is_mac) { - if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; - pointer_events_set = true; - clearTimeout(scroll_debounce); - scroll_debounce = setTimeout(function () { - self.content_elem.style.pointerEvents = 'auto'; - pointer_events_set = false; - }, 50); - } - if (last_cluster != (last_cluster = self.getClusterNum())) - self.insertToDOM(rows, cache); - if (self.options.callbacks.scrollingProgress) - self.options.callbacks.scrollingProgress(self.getScrollProgress()); - }, - resize_debounce = 0, - resizeEv = function() { - clearTimeout(resize_debounce); - resize_debounce = setTimeout(self.refresh, 100); - } - on('scroll', self.scroll_elem, scrollEv); - on('resize', window, resizeEv); - - // public methods - self.destroy = function(clean) { - off('scroll', self.scroll_elem, scrollEv); - off('resize', window, resizeEv); - self.html((clean ? self.generateEmptyRow() : rows).join('')); - } - self.refresh = function(force) { - if(self.getRowsHeight(rows) || force) self.update(rows); - } - self.update = function(new_rows) { - rows = isArray(new_rows) - ? new_rows - : []; - var scroll_top = self.scroll_elem.scrollTop; - // fixes #39 - if(rows.length * self.options.item_height < scroll_top) { - self.scroll_elem.scrollTop = 0; - last_cluster = 0; - } - self.insertToDOM(rows, cache); - self.scroll_elem.scrollTop = scroll_top; - } - self.clear = function() { - self.update([]); - } - self.getRowsAmount = function() { - return rows.length; - } - self.getScrollProgress = function() { - return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; - } - - var add = function(where, _new_rows) { - var new_rows = isArray(_new_rows) - ? _new_rows - : []; - if( ! new_rows.length) return; - rows = where == 'append' - ? rows.concat(new_rows) - : new_rows.concat(rows); - self.insertToDOM(rows, cache); - } - self.append = function(rows) { - add('append', rows); - } - self.prepend = function(rows) { - add('prepend', rows); - } - } - - Clusterize.prototype = { - constructor: Clusterize, - // fetch existing markup - fetchMarkup: function() { - var rows = [], rows_nodes = this.getChildNodes(this.content_elem); - while (rows_nodes.length) { - rows.push(rows_nodes.shift().outerHTML); - } - return rows; - }, - // get tag name, content tag name, tag height, calc cluster height - exploreEnvironment: function(rows, cache) { - var opts = this.options; - opts.content_tag = this.content_elem.tagName.toLowerCase(); - if( ! rows.length) return; - if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); - if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); - if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); - this.getRowsHeight(rows); - }, - getRowsHeight: function(rows) { - var opts = this.options, - prev_item_height = opts.item_height; - opts.cluster_height = 0; - if( ! rows.length) return; - var nodes = this.content_elem.children; - var node = nodes[Math.floor(nodes.length / 2)]; - opts.item_height = node.offsetHeight; - // consider table's border-spacing - if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') - opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; - // consider margins (and margins collapsing) - if(opts.tag != 'tr') { - var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; - var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; - opts.item_height += Math.max(marginTop, marginBottom); - } - opts.block_height = opts.item_height * opts.rows_in_block; - opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; - opts.cluster_height = opts.blocks_in_cluster * opts.block_height; - return prev_item_height != opts.item_height; - }, - // get current cluster number - getClusterNum: function () { - this.options.scroll_top = this.scroll_elem.scrollTop; - return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; - }, - // generate empty row if no data provided - generateEmptyRow: function() { - var opts = this.options; - if( ! opts.tag || ! opts.show_no_data_row) return []; - var empty_row = document.createElement(opts.tag), - no_data_content = document.createTextNode(opts.no_data_text), td; - empty_row.className = opts.no_data_class; - if(opts.tag == 'tr') { - td = document.createElement('td'); - // fixes #53 - td.colSpan = 100; - td.appendChild(no_data_content); - } - empty_row.appendChild(td || no_data_content); - return [empty_row.outerHTML]; - }, - // generate cluster for current scroll position - generate: function (rows, cluster_num) { - var opts = this.options, - rows_len = rows.length; - if (rows_len < opts.rows_in_block) { - return { - top_offset: 0, - bottom_offset: 0, - rows_above: 0, - rows: rows_len ? rows : this.generateEmptyRow() - } - } - var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), - items_end = items_start + opts.rows_in_cluster, - top_offset = Math.max(items_start * opts.item_height, 0), - bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), - this_cluster_rows = [], - rows_above = items_start; - if(top_offset < 1) { - rows_above++; - } - for (var i = items_start; i < items_end; i++) { - rows[i] && this_cluster_rows.push(rows[i]); - } - return { - top_offset: top_offset, - bottom_offset: bottom_offset, - rows_above: rows_above, - rows: this_cluster_rows - } - }, - renderExtraTag: function(class_name, height) { - var tag = document.createElement(this.options.tag), - clusterize_prefix = 'clusterize-'; - tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); - height && (tag.style.height = height + 'px'); - return tag.outerHTML; - }, - // if necessary verify data changed and insert to DOM - insertToDOM: function(rows, cache) { - // explore row's height - if( ! this.options.cluster_height) { - this.exploreEnvironment(rows, cache); - } - var data = this.generate(rows, this.getClusterNum()), - this_cluster_rows = data.rows.join(''), - this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), - top_offset_changed = this.checkChanges('top', data.top_offset, cache), - only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), - callbacks = this.options.callbacks, - layout = []; - - if(this_cluster_content_changed || top_offset_changed) { - if(data.top_offset) { - this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); - layout.push(this.renderExtraTag('top-space', data.top_offset)); - } - layout.push(this_cluster_rows); - data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); - callbacks.clusterWillChange && callbacks.clusterWillChange(); - this.html(layout.join('')); - this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); - callbacks.clusterChanged && callbacks.clusterChanged(); - } else if(only_bottom_offset_changed) { - this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; - } - }, - // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround - html: function(data) { - var content_elem = this.content_elem; - if(ie && ie <= 9 && this.options.tag == 'tr') { - var div = document.createElement('div'), last; - div.innerHTML = '' + data + '
'; - while((last = content_elem.lastChild)) { - content_elem.removeChild(last); - } - var rows_nodes = this.getChildNodes(div.firstChild.firstChild); - while (rows_nodes.length) { - content_elem.appendChild(rows_nodes.shift()); - } - } else { - content_elem.innerHTML = data; - } - }, - getChildNodes: function(tag) { - var child_nodes = tag.children, nodes = []; - for (var i = 0, ii = child_nodes.length; i < ii; i++) { - nodes.push(child_nodes[i]); - } - return nodes; - }, - checkChanges: function(type, value, cache) { - var changed = value != cache[type]; - cache[type] = value; - return changed; - } - } - - // support functions - function on(evt, element, fnc) { - return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); - } - function off(evt, element, fnc) { - return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); - } - function isArray(arr) { - return Object.prototype.toString.call(arr) === '[object Array]'; - } - function getStyle(prop, elem) { - return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; - } - - return Clusterize; -}));/** +BI.shortcut("bi.searcher_view", BI.SearcherView);/** * 表示当前对象 * * Created by GUY on 2015/9/7. @@ -15793,39 +15465,161 @@ BI.shortcut("bi.searcher_view", BI.SearcherView);/*! Clusterize.js - v0.17.6 - 2 BI.VirtualList = BI.inherit(BI.Widget, { props: function () { return { - baseCls: "bi-virtual-list clusterize-scroll", + baseCls: "bi-virtual-list", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + items: [] }; }, + + init: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + render: function () { var self = this, o = this.options; return { - type: "bi.default", + type: "bi.vertical", items: [{ type: "bi.layout", ref: function () { - self.contentEl = this; - }, - cls: "clusterize-content" - }] + self.topBlank = this; + } + }, { + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, { + type: "bi.layout", + ref: function () { + self.bottomBlank = this; + } + }], + element: this } }, mounted: function () { - var data = []; - for (var i = 0; i < 10000; i++) { - data.push("
" + i + "
"); - } - new Clusterize({ - rows: data, - scrollElem: this.element[0], - contentElem: this.contentEl.element[0] - }) + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._renderMoreIf(); + }); }, - populate: function () { + _renderMoreIf: function () { + var o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = this.container.element.height() - lastHeight; + this.cache[cnt] = { + index: index, + height: addedHeight + }; + this.tree.set(cnt, addedHeight); + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; + } + }, + + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + // var height = this.element.height(); + // var minContentHeightFrom = o.scrollTop - o.overscanHeight; + // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + // var start = this.tree.greatestLowerBound(minContentHeightFrom); + // var end = this.tree.leastUpperBound(minContentHeightTo); + // var summaryTopHeight = 0; + // this.topBlank.setHeight(0); + // this.bottomBlank.setHeight(0); + // var needDestroyed = []; + // for (var i = 0; i < start; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.topBlank.setHeight(summaryTopHeight); + // } + // } + // summaryTopHeight = 0; + // for (var i = end + 1; i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.bottomBlank.setHeight(summaryTopHeight); + // } + // } + // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + // var currentFragment = firstFragment; + // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // if (!this.cache[i].destroyed) { + // currentFragment = lastFragment; + // } + // if (this.cache[i].destroyed === true) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // var w = this.container._children[j] = BI.createWidget(BI.extend({ + // root: true + // }, BI.stripEL(o.items[j]))); + // currentFragment.appendChild(w.element[0]); + // } + // this.cache[i].destroyed = false; + // } + // } + // this.container.element.prepend(firstFragment); + // this.container.element.append(lastFragment); + // BI.each(needDestroyed, function (i, child) { + // child && child._destroy(); + // }); + }, + + _populate: function () { + var o = this.options; + this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + + populate: function (items) { + + }, + + destroyed: function () { + this.restore(); } }); -BI.shortcut('bi.virtual_list', BI.VirtualList);/** +BI.shortcut('bi.virtual_list', BI.VirtualList); +/** * 分页控件 * * Created by GUY on 2015/8/31. diff --git a/docs/core.js b/docs/core.js index 4b80066049..8d2d7eb6c2 100644 --- a/docs/core.js +++ b/docs/core.js @@ -18115,7 +18115,7 @@ $.extend(BI, { return new BI.PrefixIntervalTree(xs); }; - BI.PrefixIntervalTree.empty = function () { + BI.PrefixIntervalTree.empty = function (size) { return BI.PrefixIntervalTree.uniform(size, 0); }; diff --git a/docs/demo.js b/docs/demo.js index 7542faa5b0..0c590a5639 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -3325,6 +3325,8 @@ BI.shortcut("demo.button_tree", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { } var grid = BI.createWidget({ type: "bi.collection_view", + width: 400, + height: 300, items: items, cellSizeAndPositionGetter: function (index) { return { @@ -3366,6 +3368,10 @@ BI.shortcut("demo.collection_view", Demo.Func);Demo.Func = BI.inherit(BI.Widget, } var grid = BI.createWidget({ type: "bi.grid_view", + width: 400, + height: 300, + estimatedRowSize: 30, + estimatedColumnSize: 100, items: items, scrollTop: 100, rowHeightGetter: function () { @@ -3482,7 +3488,14 @@ BI.shortcut("demo.virtual_group_item", Demo.Item);Demo.Func = BI.inherit(BI.Widg }, render: function () { return { - type: "bi.virtual_list" + type: "bi.virtual_list", + items: BI.map(BI.makeArray(200, 0), function (i, item) { + return { + type: "bi.label", + height: 30, + text: i + }; + }) } } }); diff --git a/src/base/collection/collection.js b/src/base/collection/collection.js index ab942f7bcf..039b02ca4a 100644 --- a/src/base/collection/collection.js +++ b/src/base/collection/collection.js @@ -9,8 +9,8 @@ BI.CollectionView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-collection", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, cellSizeAndPositionGetter: BI.emptyFn, diff --git a/src/base/grid/grid.js b/src/base/grid/grid.js index 3ff3ff30fd..556040c048 100644 --- a/src/base/grid/grid.js +++ b/src/base/grid/grid.js @@ -9,16 +9,16 @@ BI.GridView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.GridView.superclass._defaultConfig.apply(this, arguments), { baseCls: "bi-grid-view", - // width: 400, - // height: 300, + // width: 400, //必设 + // height: 300, //必设 overflowX: true, overflowY: true, overscanColumnCount: 0, overscanRowCount: 0, - rowHeightGetter: BI.emptyFn, - columnWidthGetter: BI.emptyFn, - // estimatedColumnSize: 100, - // estimatedRowSize: 30, + rowHeightGetter: BI.emptyFn, //number类型或function类型 + columnWidthGetter: BI.emptyFn, //number类型或function类型 + // estimatedColumnSize: 100, //columnWidthGetter为function时必设 + // estimatedRowSize: 30, //rowHeightGetter为function时必设 scrollLeft: 0, scrollTop: 0, items: [] diff --git a/src/base/list/clusterize.js b/src/base/list/clusterize.js deleted file mode 100644 index 63c59e2baf..0000000000 --- a/src/base/list/clusterize.js +++ /dev/null @@ -1,329 +0,0 @@ -/*! Clusterize.js - v0.17.6 - 2017-03-05 - * http://NeXTs.github.com/Clusterize.js/ - * Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */ - -;(function(name, definition) { - if (typeof module != 'undefined') module.exports = definition(); - else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); - else this[name] = definition(); -}('Clusterize', function() { - "use strict" - - // detect ie9 and lower - // https://gist.github.com/padolsey/527683#comment-786682 - var ie = (function(){ - for( var v = 3, - el = document.createElement('b'), - all = el.all || []; - el.innerHTML = '', - all[0]; - ){} - return v > 4 ? v : document.documentMode; - }()), - is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1; - var Clusterize = function(data) { - if( ! (this instanceof Clusterize)) - return new Clusterize(data); - var self = this; - - var defaults = { - rows_in_block: 50, - blocks_in_cluster: 4, - tag: null, - show_no_data_row: true, - no_data_class: 'clusterize-no-data', - no_data_text: 'No data', - keep_parity: true, - callbacks: {} - } - - // public parameters - self.options = {}; - var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks']; - for(var i = 0, option; option = options[i]; i++) { - self.options[option] = typeof data[option] != 'undefined' && data[option] != null - ? data[option] - : defaults[option]; - } - - var elems = ['scroll', 'content']; - for(var i = 0, elem; elem = elems[i]; i++) { - self[elem + '_elem'] = data[elem + 'Id'] - ? document.getElementById(data[elem + 'Id']) - : data[elem + 'Elem']; - if( ! self[elem + '_elem']) - throw new Error("Error! Could not find " + elem + " element"); - } - - // tabindex forces the browser to keep focus on the scrolling list, fixes #11 - if( ! self.content_elem.hasAttribute('tabindex')) - self.content_elem.setAttribute('tabindex', 0); - - // private parameters - var rows = isArray(data.rows) - ? data.rows - : self.fetchMarkup(), - cache = {}, - scroll_top = self.scroll_elem.scrollTop; - - // append initial data - self.insertToDOM(rows, cache); - - // restore the scroll position - self.scroll_elem.scrollTop = scroll_top; - - // adding scroll handler - var last_cluster = false, - scroll_debounce = 0, - pointer_events_set = false, - scrollEv = function() { - // fixes scrolling issue on Mac #3 - if (is_mac) { - if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none'; - pointer_events_set = true; - clearTimeout(scroll_debounce); - scroll_debounce = setTimeout(function () { - self.content_elem.style.pointerEvents = 'auto'; - pointer_events_set = false; - }, 50); - } - if (last_cluster != (last_cluster = self.getClusterNum())) - self.insertToDOM(rows, cache); - if (self.options.callbacks.scrollingProgress) - self.options.callbacks.scrollingProgress(self.getScrollProgress()); - }, - resize_debounce = 0, - resizeEv = function() { - clearTimeout(resize_debounce); - resize_debounce = setTimeout(self.refresh, 100); - } - on('scroll', self.scroll_elem, scrollEv); - on('resize', window, resizeEv); - - // public methods - self.destroy = function(clean) { - off('scroll', self.scroll_elem, scrollEv); - off('resize', window, resizeEv); - self.html((clean ? self.generateEmptyRow() : rows).join('')); - } - self.refresh = function(force) { - if(self.getRowsHeight(rows) || force) self.update(rows); - } - self.update = function(new_rows) { - rows = isArray(new_rows) - ? new_rows - : []; - var scroll_top = self.scroll_elem.scrollTop; - // fixes #39 - if(rows.length * self.options.item_height < scroll_top) { - self.scroll_elem.scrollTop = 0; - last_cluster = 0; - } - self.insertToDOM(rows, cache); - self.scroll_elem.scrollTop = scroll_top; - } - self.clear = function() { - self.update([]); - } - self.getRowsAmount = function() { - return rows.length; - } - self.getScrollProgress = function() { - return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0; - } - - var add = function(where, _new_rows) { - var new_rows = isArray(_new_rows) - ? _new_rows - : []; - if( ! new_rows.length) return; - rows = where == 'append' - ? rows.concat(new_rows) - : new_rows.concat(rows); - self.insertToDOM(rows, cache); - } - self.append = function(rows) { - add('append', rows); - } - self.prepend = function(rows) { - add('prepend', rows); - } - } - - Clusterize.prototype = { - constructor: Clusterize, - // fetch existing markup - fetchMarkup: function() { - var rows = [], rows_nodes = this.getChildNodes(this.content_elem); - while (rows_nodes.length) { - rows.push(rows_nodes.shift().outerHTML); - } - return rows; - }, - // get tag name, content tag name, tag height, calc cluster height - exploreEnvironment: function(rows, cache) { - var opts = this.options; - opts.content_tag = this.content_elem.tagName.toLowerCase(); - if( ! rows.length) return; - if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase(); - if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]); - if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase(); - this.getRowsHeight(rows); - }, - getRowsHeight: function(rows) { - var opts = this.options, - prev_item_height = opts.item_height; - opts.cluster_height = 0; - if( ! rows.length) return; - var nodes = this.content_elem.children; - var node = nodes[Math.floor(nodes.length / 2)]; - opts.item_height = node.offsetHeight; - // consider table's border-spacing - if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse') - opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0; - // consider margins (and margins collapsing) - if(opts.tag != 'tr') { - var marginTop = parseInt(getStyle('marginTop', node), 10) || 0; - var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0; - opts.item_height += Math.max(marginTop, marginBottom); - } - opts.block_height = opts.item_height * opts.rows_in_block; - opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block; - opts.cluster_height = opts.blocks_in_cluster * opts.block_height; - return prev_item_height != opts.item_height; - }, - // get current cluster number - getClusterNum: function () { - this.options.scroll_top = this.scroll_elem.scrollTop; - return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0; - }, - // generate empty row if no data provided - generateEmptyRow: function() { - var opts = this.options; - if( ! opts.tag || ! opts.show_no_data_row) return []; - var empty_row = document.createElement(opts.tag), - no_data_content = document.createTextNode(opts.no_data_text), td; - empty_row.className = opts.no_data_class; - if(opts.tag == 'tr') { - td = document.createElement('td'); - // fixes #53 - td.colSpan = 100; - td.appendChild(no_data_content); - } - empty_row.appendChild(td || no_data_content); - return [empty_row.outerHTML]; - }, - // generate cluster for current scroll position - generate: function (rows, cluster_num) { - var opts = this.options, - rows_len = rows.length; - if (rows_len < opts.rows_in_block) { - return { - top_offset: 0, - bottom_offset: 0, - rows_above: 0, - rows: rows_len ? rows : this.generateEmptyRow() - } - } - var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0), - items_end = items_start + opts.rows_in_cluster, - top_offset = Math.max(items_start * opts.item_height, 0), - bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0), - this_cluster_rows = [], - rows_above = items_start; - if(top_offset < 1) { - rows_above++; - } - for (var i = items_start; i < items_end; i++) { - rows[i] && this_cluster_rows.push(rows[i]); - } - return { - top_offset: top_offset, - bottom_offset: bottom_offset, - rows_above: rows_above, - rows: this_cluster_rows - } - }, - renderExtraTag: function(class_name, height) { - var tag = document.createElement(this.options.tag), - clusterize_prefix = 'clusterize-'; - tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' '); - height && (tag.style.height = height + 'px'); - return tag.outerHTML; - }, - // if necessary verify data changed and insert to DOM - insertToDOM: function(rows, cache) { - // explore row's height - if( ! this.options.cluster_height) { - this.exploreEnvironment(rows, cache); - } - var data = this.generate(rows, this.getClusterNum()), - this_cluster_rows = data.rows.join(''), - this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache), - top_offset_changed = this.checkChanges('top', data.top_offset, cache), - only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache), - callbacks = this.options.callbacks, - layout = []; - - if(this_cluster_content_changed || top_offset_changed) { - if(data.top_offset) { - this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity')); - layout.push(this.renderExtraTag('top-space', data.top_offset)); - } - layout.push(this_cluster_rows); - data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset)); - callbacks.clusterWillChange && callbacks.clusterWillChange(); - this.html(layout.join('')); - this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above); - callbacks.clusterChanged && callbacks.clusterChanged(); - } else if(only_bottom_offset_changed) { - this.content_elem.lastChild.style.height = data.bottom_offset + 'px'; - } - }, - // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround - html: function(data) { - var content_elem = this.content_elem; - if(ie && ie <= 9 && this.options.tag == 'tr') { - var div = document.createElement('div'), last; - div.innerHTML = '' + data + '
'; - while((last = content_elem.lastChild)) { - content_elem.removeChild(last); - } - var rows_nodes = this.getChildNodes(div.firstChild.firstChild); - while (rows_nodes.length) { - content_elem.appendChild(rows_nodes.shift()); - } - } else { - content_elem.innerHTML = data; - } - }, - getChildNodes: function(tag) { - var child_nodes = tag.children, nodes = []; - for (var i = 0, ii = child_nodes.length; i < ii; i++) { - nodes.push(child_nodes[i]); - } - return nodes; - }, - checkChanges: function(type, value, cache) { - var changed = value != cache[type]; - cache[type] = value; - return changed; - } - } - - // support functions - function on(evt, element, fnc) { - return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc); - } - function off(evt, element, fnc) { - return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc); - } - function isArray(arr) { - return Object.prototype.toString.call(arr) === '[object Array]'; - } - function getStyle(prop, elem) { - return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop]; - } - - return Clusterize; -})); \ No newline at end of file diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js index aca28e1979..2b164bd6bc 100644 --- a/src/base/list/virtuallist.js +++ b/src/base/list/virtuallist.js @@ -8,36 +8,157 @@ BI.VirtualList = BI.inherit(BI.Widget, { props: function () { return { - baseCls: "bi-virtual-list clusterize-scroll", + baseCls: "bi-virtual-list", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + items: [] }; }, + + init: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + render: function () { var self = this, o = this.options; return { - type: "bi.default", + type: "bi.vertical", items: [{ type: "bi.layout", ref: function () { - self.contentEl = this; - }, - cls: "clusterize-content" - }] + self.topBlank = this; + } + }, { + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, { + type: "bi.layout", + ref: function () { + self.bottomBlank = this; + } + }], + element: this } }, mounted: function () { - var data = []; - for (var i = 0; i < 10000; i++) { - data.push("
" + i + "
"); + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._renderMoreIf(); + }); + }, + + _renderMoreIf: function () { + var o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = this.container.element.height() - lastHeight; + this.cache[cnt] = { + index: index, + height: addedHeight + }; + this.tree.set(cnt, addedHeight); + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; } - new Clusterize({ - rows: data, - scrollElem: this.element[0], - contentElem: this.contentEl.element[0] - }) }, - populate: function () { + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + // var height = this.element.height(); + // var minContentHeightFrom = o.scrollTop - o.overscanHeight; + // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + // var start = this.tree.greatestLowerBound(minContentHeightFrom); + // var end = this.tree.leastUpperBound(minContentHeightTo); + // var summaryTopHeight = 0; + // this.topBlank.setHeight(0); + // this.bottomBlank.setHeight(0); + // var needDestroyed = []; + // for (var i = 0; i < start; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.topBlank.setHeight(summaryTopHeight); + // } + // } + // summaryTopHeight = 0; + // for (var i = end + 1; i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // summaryTopHeight += this.cache[i].height; + // if (!this.cache[i].destroyed) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // needDestroyed.push(this.container._children[j]); + // this.container._children[j] = null; + // } + // this.cache[i].destroyed = true; + // // this.bottomBlank.setHeight(summaryTopHeight); + // } + // } + // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + // var currentFragment = firstFragment; + // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + // var index = this.cache[i].index; + // if (!this.cache[i].destroyed) { + // currentFragment = lastFragment; + // } + // if (this.cache[i].destroyed === true) { + // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + // var w = this.container._children[j] = BI.createWidget(BI.extend({ + // root: true + // }, BI.stripEL(o.items[j]))); + // currentFragment.appendChild(w.element[0]); + // } + // this.cache[i].destroyed = false; + // } + // } + // this.container.element.prepend(firstFragment); + // this.container.element.append(lastFragment); + // BI.each(needDestroyed, function (i, child) { + // child && child._destroy(); + // }); + }, + + _populate: function () { + var o = this.options; + this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.cache = {}; + }, + + populate: function (items) { + + }, + + destroyed: function () { + this.restore(); } }); -BI.shortcut('bi.virtual_list', BI.VirtualList); \ No newline at end of file +BI.shortcut('bi.virtual_list', BI.VirtualList); diff --git a/src/core/utils/prefixIntervalTree.js b/src/core/utils/prefixIntervalTree.js index 82e1a50a78..043aa668b9 100644 --- a/src/core/utils/prefixIntervalTree.js +++ b/src/core/utils/prefixIntervalTree.js @@ -170,7 +170,7 @@ return new BI.PrefixIntervalTree(xs); }; - BI.PrefixIntervalTree.empty = function () { + BI.PrefixIntervalTree.empty = function (size) { return BI.PrefixIntervalTree.uniform(size, 0); }; diff --git a/src/css/base/list/clusterize.css b/src/css/base/list/clusterize.css deleted file mode 100644 index 2b8d17ee55..0000000000 --- a/src/css/base/list/clusterize.css +++ /dev/null @@ -1,32 +0,0 @@ -/* max-height - the only parameter in this file that needs to be edited. - * Change it to suit your needs. The rest is recommended to leave as is. - */ -.clusterize-scroll { - overflow: auto; -} -/** - * Avoid vertical margins for extra tags - * Necessary for correct calculations when rows have nonzero vertical margins - */ -.clusterize-extra-row { - margin-top: 0 !important; - margin-bottom: 0 !important; -} -/* By default extra tag .clusterize-keep-parity added to keep parity of rows. - * Useful when used :nth-child(even/odd) - */ -.clusterize-extra-row.clusterize-keep-parity { - display: none; -} -/* During initialization clusterize adds tabindex to force the browser to keep focus - * on the scrolling list, see issue #11 - * Outline removes default browser's borders for focused elements. - */ -.clusterize-content { - outline: 0; -} -/* Centering message that appears when no data provided - */ -.clusterize-no-data td { - text-align: center; -} diff --git a/src/less/base/list/clusterize.less b/src/less/base/list/clusterize.less deleted file mode 100644 index 6aafca8652..0000000000 --- a/src/less/base/list/clusterize.less +++ /dev/null @@ -1,36 +0,0 @@ -/* max-height - the only parameter in this file that needs to be edited. - * Change it to suit your needs. The rest is recommended to leave as is. - */ -.clusterize-scroll{ - overflow: auto; -} - -/** - * Avoid vertical margins for extra tags - * Necessary for correct calculations when rows have nonzero vertical margins - */ -.clusterize-extra-row{ - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -/* By default extra tag .clusterize-keep-parity added to keep parity of rows. - * Useful when used :nth-child(even/odd) - */ -.clusterize-extra-row.clusterize-keep-parity{ - display: none; -} - -/* During initialization clusterize adds tabindex to force the browser to keep focus - * on the scrolling list, see issue #11 - * Outline removes default browser's borders for focused elements. - */ -.clusterize-content{ - outline: 0; -} - -/* Centering message that appears when no data provided - */ -.clusterize-no-data td{ - text-align: center; -} \ No newline at end of file From 546087ba62d5f24dd326b3e6fe8f72819b4cb9c2 Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 22 May 2017 17:22:59 +0800 Subject: [PATCH 17/27] virtuallist --- bi/base.js | 135 ++++++++++++--------- demo/js/core/abstract/demo.virtual_list.js | 8 +- docs/base.js | 135 ++++++++++++--------- docs/demo.js | 8 +- src/base/list/virtuallist.js | 135 ++++++++++++--------- 5 files changed, 233 insertions(+), 188 deletions(-) diff --git a/bi/base.js b/bi/base.js index 5f1c88b26f..b14612763c 100644 --- a/bi/base.js +++ b/bi/base.js @@ -15476,6 +15476,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { init: function () { this.renderedIndex = -1; this.cache = {}; + this._scrollLock = false; + this._debounceRelease = BI.debounce(function () { + self._scrollLock = false; + }, 1000 / 60); }, render: function () { @@ -15511,23 +15515,27 @@ BI.VirtualList = BI.inherit(BI.Widget, { self._calculateBlocksToRender(); }); BI.ResizeDetector.addResizeListener(this, function () { - self._renderMoreIf(); + self._calculateBlocksToRender(); }); }, _renderMoreIf: function () { - var o = this.options; + var self = this, o = this.options; var height = this.element.height(); var minContentHeight = o.scrollTop + height + o.overscanHeight; var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, cnt = this.renderedIndex + 1; var lastHeight; - while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var getElementHeight = function () { + return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { var items = o.items.slice(index, index + o.blockSize); this.container.addItems(items); - var addedHeight = this.container.element.height() - lastHeight; + var addedHeight = getElementHeight() - lastHeight; this.cache[cnt] = { index: index, + scrollTop: lastHeight, height: addedHeight }; this.tree.set(cnt, addedHeight); @@ -15540,66 +15548,69 @@ BI.VirtualList = BI.inherit(BI.Widget, { _calculateBlocksToRender: function () { var o = this.options; this._renderMoreIf(); - // var height = this.element.height(); - // var minContentHeightFrom = o.scrollTop - o.overscanHeight; - // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; - // var start = this.tree.greatestLowerBound(minContentHeightFrom); - // var end = this.tree.leastUpperBound(minContentHeightTo); - // var summaryTopHeight = 0; + var height = this.element.height(); + var minContentHeightFrom = o.scrollTop - o.overscanHeight; + var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + var start = this.tree.greatestLowerBound(minContentHeightFrom); + var end = this.tree.leastUpperBound(minContentHeightTo); // this.topBlank.setHeight(0); // this.bottomBlank.setHeight(0); - // var needDestroyed = []; - // for (var i = 0; i < start; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.topBlank.setHeight(summaryTopHeight); - // } - // } - // summaryTopHeight = 0; - // for (var i = end + 1; i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.bottomBlank.setHeight(summaryTopHeight); - // } - // } - // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); - // var currentFragment = firstFragment; - // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // if (!this.cache[i].destroyed) { - // currentFragment = lastFragment; - // } - // if (this.cache[i].destroyed === true) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // var w = this.container._children[j] = BI.createWidget(BI.extend({ - // root: true - // }, BI.stripEL(o.items[j]))); - // currentFragment.appendChild(w.element[0]); - // } - // this.cache[i].destroyed = false; - // } - // } - // this.container.element.prepend(firstFragment); - // this.container.element.append(lastFragment); - // BI.each(needDestroyed, function (i, child) { - // child && child._destroy(); - // }); + var needDestroyed = []; + for (var i = 0; i < start; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + for (var i = end + 1; i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + var currentFragment = firstFragment; + for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + currentFragment = lastFragment; + } + if (this.cache[i].destroyed === true) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + var w = this.container._children[j] = BI.createWidget(BI.extend({ + root: true + }, BI.stripEL(o.items[j]))); + w.element.css("position", "relative");//vertical布局下position要改成relative + currentFragment.appendChild(w.element[0]); + } + this.cache[i].destroyed = false; + } + } + this._scrollLock = true; + this.container.element.prepend(firstFragment); + this.container.element.append(lastFragment); + this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); + var lastCache = this.cache[Math.min(end, this.renderedIndex)]; + this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - lastCache.scrollTop - lastCache.height); + BI.each(needDestroyed, function (i, child) { + child && child._destroy(); + }); + this._debounceRelease(); }, - _populate: function () { + _populate: function (items) { var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); this._calculateBlocksToRender(); this.element.scrollTop(o.scrollTop); @@ -15611,7 +15622,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, populate: function (items) { - + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); }, destroyed: function () { @@ -15619,6 +15633,7 @@ BI.VirtualList = BI.inherit(BI.Widget, { } }); BI.shortcut('bi.virtual_list', BI.VirtualList); + /** * 分页控件 * diff --git a/demo/js/core/abstract/demo.virtual_list.js b/demo/js/core/abstract/demo.virtual_list.js index 1a8a754d81..30b7c03587 100644 --- a/demo/js/core/abstract/demo.virtual_list.js +++ b/demo/js/core/abstract/demo.virtual_list.js @@ -5,12 +5,12 @@ Demo.Func = BI.inherit(BI.Widget, { render: function () { return { type: "bi.virtual_list", - items: BI.map(BI.makeArray(200, 0), function (i, item) { - return { + items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { + return BI.extend({}, item, { type: "bi.label", height: 30, - text: i - }; + text: (i + 1) + "." + item.text, + }); }) } } diff --git a/docs/base.js b/docs/base.js index 5f1c88b26f..b14612763c 100644 --- a/docs/base.js +++ b/docs/base.js @@ -15476,6 +15476,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { init: function () { this.renderedIndex = -1; this.cache = {}; + this._scrollLock = false; + this._debounceRelease = BI.debounce(function () { + self._scrollLock = false; + }, 1000 / 60); }, render: function () { @@ -15511,23 +15515,27 @@ BI.VirtualList = BI.inherit(BI.Widget, { self._calculateBlocksToRender(); }); BI.ResizeDetector.addResizeListener(this, function () { - self._renderMoreIf(); + self._calculateBlocksToRender(); }); }, _renderMoreIf: function () { - var o = this.options; + var self = this, o = this.options; var height = this.element.height(); var minContentHeight = o.scrollTop + height + o.overscanHeight; var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, cnt = this.renderedIndex + 1; var lastHeight; - while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var getElementHeight = function () { + return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { var items = o.items.slice(index, index + o.blockSize); this.container.addItems(items); - var addedHeight = this.container.element.height() - lastHeight; + var addedHeight = getElementHeight() - lastHeight; this.cache[cnt] = { index: index, + scrollTop: lastHeight, height: addedHeight }; this.tree.set(cnt, addedHeight); @@ -15540,66 +15548,69 @@ BI.VirtualList = BI.inherit(BI.Widget, { _calculateBlocksToRender: function () { var o = this.options; this._renderMoreIf(); - // var height = this.element.height(); - // var minContentHeightFrom = o.scrollTop - o.overscanHeight; - // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; - // var start = this.tree.greatestLowerBound(minContentHeightFrom); - // var end = this.tree.leastUpperBound(minContentHeightTo); - // var summaryTopHeight = 0; + var height = this.element.height(); + var minContentHeightFrom = o.scrollTop - o.overscanHeight; + var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + var start = this.tree.greatestLowerBound(minContentHeightFrom); + var end = this.tree.leastUpperBound(minContentHeightTo); // this.topBlank.setHeight(0); // this.bottomBlank.setHeight(0); - // var needDestroyed = []; - // for (var i = 0; i < start; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.topBlank.setHeight(summaryTopHeight); - // } - // } - // summaryTopHeight = 0; - // for (var i = end + 1; i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.bottomBlank.setHeight(summaryTopHeight); - // } - // } - // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); - // var currentFragment = firstFragment; - // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // if (!this.cache[i].destroyed) { - // currentFragment = lastFragment; - // } - // if (this.cache[i].destroyed === true) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // var w = this.container._children[j] = BI.createWidget(BI.extend({ - // root: true - // }, BI.stripEL(o.items[j]))); - // currentFragment.appendChild(w.element[0]); - // } - // this.cache[i].destroyed = false; - // } - // } - // this.container.element.prepend(firstFragment); - // this.container.element.append(lastFragment); - // BI.each(needDestroyed, function (i, child) { - // child && child._destroy(); - // }); + var needDestroyed = []; + for (var i = 0; i < start; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + for (var i = end + 1; i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + var currentFragment = firstFragment; + for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + currentFragment = lastFragment; + } + if (this.cache[i].destroyed === true) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + var w = this.container._children[j] = BI.createWidget(BI.extend({ + root: true + }, BI.stripEL(o.items[j]))); + w.element.css("position", "relative");//vertical布局下position要改成relative + currentFragment.appendChild(w.element[0]); + } + this.cache[i].destroyed = false; + } + } + this._scrollLock = true; + this.container.element.prepend(firstFragment); + this.container.element.append(lastFragment); + this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); + var lastCache = this.cache[Math.min(end, this.renderedIndex)]; + this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - lastCache.scrollTop - lastCache.height); + BI.each(needDestroyed, function (i, child) { + child && child._destroy(); + }); + this._debounceRelease(); }, - _populate: function () { + _populate: function (items) { var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); this._calculateBlocksToRender(); this.element.scrollTop(o.scrollTop); @@ -15611,7 +15622,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, populate: function (items) { - + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); }, destroyed: function () { @@ -15619,6 +15633,7 @@ BI.VirtualList = BI.inherit(BI.Widget, { } }); BI.shortcut('bi.virtual_list', BI.VirtualList); + /** * 分页控件 * diff --git a/docs/demo.js b/docs/demo.js index 0c590a5639..2f6f7af47d 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -3489,12 +3489,12 @@ BI.shortcut("demo.virtual_group_item", Demo.Item);Demo.Func = BI.inherit(BI.Widg render: function () { return { type: "bi.virtual_list", - items: BI.map(BI.makeArray(200, 0), function (i, item) { - return { + items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { + return BI.extend({}, item, { type: "bi.label", height: 30, - text: i - }; + text: (i + 1) + "." + item.text, + }); }) } } diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js index 2b164bd6bc..025921dedc 100644 --- a/src/base/list/virtuallist.js +++ b/src/base/list/virtuallist.js @@ -19,6 +19,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { init: function () { this.renderedIndex = -1; this.cache = {}; + this._scrollLock = false; + this._debounceRelease = BI.debounce(function () { + self._scrollLock = false; + }, 1000 / 60); }, render: function () { @@ -54,23 +58,27 @@ BI.VirtualList = BI.inherit(BI.Widget, { self._calculateBlocksToRender(); }); BI.ResizeDetector.addResizeListener(this, function () { - self._renderMoreIf(); + self._calculateBlocksToRender(); }); }, _renderMoreIf: function () { - var o = this.options; + var self = this, o = this.options; var height = this.element.height(); var minContentHeight = o.scrollTop + height + o.overscanHeight; var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, cnt = this.renderedIndex + 1; var lastHeight; - while ((lastHeight = this.container.element.height()) < minContentHeight && index < o.items.length) { + var getElementHeight = function () { + return self.container.element.height() + self.topBlank.element.height() + self.bottomBlank.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { var items = o.items.slice(index, index + o.blockSize); this.container.addItems(items); - var addedHeight = this.container.element.height() - lastHeight; + var addedHeight = getElementHeight() - lastHeight; this.cache[cnt] = { index: index, + scrollTop: lastHeight, height: addedHeight }; this.tree.set(cnt, addedHeight); @@ -83,66 +91,69 @@ BI.VirtualList = BI.inherit(BI.Widget, { _calculateBlocksToRender: function () { var o = this.options; this._renderMoreIf(); - // var height = this.element.height(); - // var minContentHeightFrom = o.scrollTop - o.overscanHeight; - // var minContentHeightTo = o.scrollTop + height + o.overscanHeight; - // var start = this.tree.greatestLowerBound(minContentHeightFrom); - // var end = this.tree.leastUpperBound(minContentHeightTo); - // var summaryTopHeight = 0; + var height = this.element.height(); + var minContentHeightFrom = o.scrollTop - o.overscanHeight; + var minContentHeightTo = o.scrollTop + height + o.overscanHeight; + var start = this.tree.greatestLowerBound(minContentHeightFrom); + var end = this.tree.leastUpperBound(minContentHeightTo); // this.topBlank.setHeight(0); // this.bottomBlank.setHeight(0); - // var needDestroyed = []; - // for (var i = 0; i < start; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.topBlank.setHeight(summaryTopHeight); - // } - // } - // summaryTopHeight = 0; - // for (var i = end + 1; i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // summaryTopHeight += this.cache[i].height; - // if (!this.cache[i].destroyed) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // needDestroyed.push(this.container._children[j]); - // this.container._children[j] = null; - // } - // this.cache[i].destroyed = true; - // // this.bottomBlank.setHeight(summaryTopHeight); - // } - // } - // var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); - // var currentFragment = firstFragment; - // for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { - // var index = this.cache[i].index; - // if (!this.cache[i].destroyed) { - // currentFragment = lastFragment; - // } - // if (this.cache[i].destroyed === true) { - // for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - // var w = this.container._children[j] = BI.createWidget(BI.extend({ - // root: true - // }, BI.stripEL(o.items[j]))); - // currentFragment.appendChild(w.element[0]); - // } - // this.cache[i].destroyed = false; - // } - // } - // this.container.element.prepend(firstFragment); - // this.container.element.append(lastFragment); - // BI.each(needDestroyed, function (i, child) { - // child && child._destroy(); - // }); + var needDestroyed = []; + for (var i = 0; i < start; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + for (var i = end + 1; i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + needDestroyed.push(this.container._children[j]); + this.container._children[j] = null; + } + this.cache[i].destroyed = true; + } + } + var firstFragment = document.createDocumentFragment(), lastFragment = document.createDocumentFragment(); + var currentFragment = firstFragment; + for (var i = (start < 0 ? 0 : start); i <= end && i <= this.renderedIndex; i++) { + var index = this.cache[i].index; + if (!this.cache[i].destroyed) { + currentFragment = lastFragment; + } + if (this.cache[i].destroyed === true) { + for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { + var w = this.container._children[j] = BI.createWidget(BI.extend({ + root: true + }, BI.stripEL(o.items[j]))); + w.element.css("position", "relative");//vertical布局下position要改成relative + currentFragment.appendChild(w.element[0]); + } + this.cache[i].destroyed = false; + } + } + this._scrollLock = true; + this.container.element.prepend(firstFragment); + this.container.element.append(lastFragment); + this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); + var lastCache = this.cache[Math.min(end, this.renderedIndex)]; + this.bottomBlank.setHeight(this.tree.sumTo(this.renderedIndex) - lastCache.scrollTop - lastCache.height); + BI.each(needDestroyed, function (i, child) { + child && child._destroy(); + }); + this._debounceRelease(); }, - _populate: function () { + _populate: function (items) { var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } this.tree = BI.PrefixIntervalTree.empty(Math.ceil(o.items.length / o.blockSize)); this._calculateBlocksToRender(); this.element.scrollTop(o.scrollTop); @@ -154,7 +165,10 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, populate: function (items) { - + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); }, destroyed: function () { @@ -162,3 +176,4 @@ BI.VirtualList = BI.inherit(BI.Widget, { } }); BI.shortcut('bi.virtual_list', BI.VirtualList); + From 32055d0bae6786628659b7a7ae62880df83fcf79 Mon Sep 17 00:00:00 2001 From: young Date: Mon, 22 May 2017 19:12:05 +0800 Subject: [PATCH 18/27] floatOpened --- bi/core.js | 1 + docs/core.js | 1 + src/core/controller/controller.floatbox.js | 1 + 3 files changed, 3 insertions(+) diff --git a/bi/core.js b/bi/core.js index de5f6d5d1f..6068f7c17a 100644 --- a/bi/core.js +++ b/bi/core.js @@ -15476,6 +15476,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { delete this.floatLayer[name]; delete this.zindexMap[name]; delete this.floatContainer[name]; + delete this.floatOpened[name]; return this; } });/** diff --git a/docs/core.js b/docs/core.js index 4b80066049..95c129a6f7 100644 --- a/docs/core.js +++ b/docs/core.js @@ -21074,6 +21074,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { delete this.floatLayer[name]; delete this.zindexMap[name]; delete this.floatContainer[name]; + delete this.floatOpened[name]; return this; } });/** diff --git a/src/core/controller/controller.floatbox.js b/src/core/controller/controller.floatbox.js index e700f34f36..f721a8fac1 100644 --- a/src/core/controller/controller.floatbox.js +++ b/src/core/controller/controller.floatbox.js @@ -137,6 +137,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { delete this.floatLayer[name]; delete this.zindexMap[name]; delete this.floatContainer[name]; + delete this.floatOpened[name]; return this; } }); \ No newline at end of file From 61129291f253d36e3efd31c7d1c836c600a47098 Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 22 May 2017 19:47:40 +0800 Subject: [PATCH 19/27] add --- bi/base.js | 9 +++++++++ docs/base.js | 9 +++++++++ src/base/list/virtuallist.js | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/bi/base.js b/bi/base.js index b14612763c..1e4d9ea34f 100644 --- a/bi/base.js +++ b/bi/base.js @@ -15616,8 +15616,17 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.element.scrollTop(o.scrollTop); }, + _clearChildren: function () { + BI.each(this.container._children, function (i, cell) { + cell && cell.el._destroy(); + }); + this.container._children = {}; + this.container.attr("items", []); + }, + restore: function () { this.renderedIndex = -1; + this._clearChildren(); this.cache = {}; }, diff --git a/docs/base.js b/docs/base.js index b14612763c..1e4d9ea34f 100644 --- a/docs/base.js +++ b/docs/base.js @@ -15616,8 +15616,17 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.element.scrollTop(o.scrollTop); }, + _clearChildren: function () { + BI.each(this.container._children, function (i, cell) { + cell && cell.el._destroy(); + }); + this.container._children = {}; + this.container.attr("items", []); + }, + restore: function () { this.renderedIndex = -1; + this._clearChildren(); this.cache = {}; }, diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js index 025921dedc..e4c7e76cdd 100644 --- a/src/base/list/virtuallist.js +++ b/src/base/list/virtuallist.js @@ -159,8 +159,17 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.element.scrollTop(o.scrollTop); }, + _clearChildren: function () { + BI.each(this.container._children, function (i, cell) { + cell && cell.el._destroy(); + }); + this.container._children = {}; + this.container.attr("items", []); + }, + restore: function () { this.renderedIndex = -1; + this._clearChildren(); this.cache = {}; }, From 603009a008d7be69f122783aa9516903fc8666f9 Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 23 May 2017 09:34:58 +0800 Subject: [PATCH 20/27] listview --- bi/base.css | 14 +-- bi/base.js | 129 ++++++++++++++++++--- bi/core.js | 4 +- demo/js/config/core.js | 6 +- demo/js/core/abstract/demo.list_view.js | 22 ++++ docs/base.css | 14 +-- docs/base.js | 129 ++++++++++++++++++--- docs/core.js | 4 +- docs/demo.js | 27 ++++- src/base/layer/layer.popup.js | 2 +- src/base/list/listview.js | 110 ++++++++++++++++++ src/base/list/virtuallist.js | 17 +-- src/core/controller/controller.floatbox.js | 2 +- src/core/controller/controller.layer.js | 2 +- src/css/base/view/popupview.css | 14 +-- src/less/base/view/popupview.less | 4 +- 16 files changed, 427 insertions(+), 73 deletions(-) create mode 100644 demo/js/core/abstract/demo.list_view.js create mode 100644 src/base/list/listview.js diff --git a/bi/base.css b/bi/base.css index 9a756c5503..1ced609f64 100644 --- a/bi/base.css +++ b/bi/base.css @@ -1342,30 +1342,30 @@ li.CodeMirror-hint-active { /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ /**********BI.BIListView*************/ -.bi-list-view { +.bi-popup-view { position: fixed !important; overflow-y: visible !important; overflow-x: visible !important; overflow: visible !important; cursor: default; } -.bi-list-view .list-view-outer { +.bi-popup-view .list-view-outer { -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; } -.bi-list-view .list-view-toolbar { +.bi-popup-view .list-view-toolbar { line-height: 30px; } -.bi-list-view .list-view-toolbar > .center-element { +.bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #d4dadd; } -.bi-list-view .list-view-toolbar > .first-element { +.bi-popup-view .list-view-toolbar > .first-element { border-left: none; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .center-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #525466; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .first-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .first-element { border-left: none; } diff --git a/bi/base.js b/bi/base.js index 1e4d9ea34f..4e6604dba2 100644 --- a/bi/base.js +++ b/bi/base.js @@ -15155,7 +15155,7 @@ BI.FloatBox.EVENT_FLOAT_BOX_OPEN = "EVENT_FLOAT_BOX_CLOSED"; BI.PopupView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-view", + baseCls: "bi-popup-view", maxWidth: 'auto', minWidth: 100, //maxHeight: 200, @@ -15458,7 +15458,117 @@ BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.searcher_view", BI.SearcherView);/** * 表示当前对象 * - * Created by GUY on 2015/9/7. + * Created by GUY on 2017/5/23. + * @class BI.ListView + * @extends BI.Widget + */ +BI.ListView = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-list-view", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + el: {}, + items: [] + }; + }, + + init: function () { + var self = this; + this.renderedIndex = -1; + this.cache = {}; + }, + + render: function () { + var self = this, o = this.options; + return { + type: "bi.vertical", + items: [BI.extend({ + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, o.el)], + element: this + } + }, + + mounted: function () { + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._calculateBlocksToRender(); + }); + }, + + _renderMoreIf: function () { + var self = this, o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + var getElementHeight = function () { + return self.container.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = getElementHeight() - lastHeight; + this.cache[cnt] = { + index: index, + scrollTop: lastHeight, + height: addedHeight + }; + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; + } + }, + + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + }, + + _populate: function (items) { + var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.container.empty(); + this.cache = {}; + }, + + populate: function (items) { + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); + }, + + destroyed: function () { + this.restore(); + } +}); +BI.shortcut('bi.list_view', BI.ListView); + +/** + * 表示当前对象 + * + * Created by GUY on 2017/5/22. * @class BI.VirtualList * @extends BI.Widget */ @@ -15474,12 +15584,9 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, init: function () { + var self = this; this.renderedIndex = -1; this.cache = {}; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 1000 / 60); }, render: function () { @@ -15553,8 +15660,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { var minContentHeightTo = o.scrollTop + height + o.overscanHeight; var start = this.tree.greatestLowerBound(minContentHeightFrom); var end = this.tree.leastUpperBound(minContentHeightTo); - // this.topBlank.setHeight(0); - // this.bottomBlank.setHeight(0); var needDestroyed = []; for (var i = 0; i < start; i++) { var index = this.cache[i].index; @@ -15585,16 +15690,12 @@ BI.VirtualList = BI.inherit(BI.Widget, { } if (this.cache[i].destroyed === true) { for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - var w = this.container._children[j] = BI.createWidget(BI.extend({ - root: true - }, BI.stripEL(o.items[j]))); - w.element.css("position", "relative");//vertical布局下position要改成relative + var w = this.container._addElement(j, BI.extend({root: true}, BI.stripEL(o.items[j]))); currentFragment.appendChild(w.element[0]); } this.cache[i].destroyed = false; } } - this._scrollLock = true; this.container.element.prepend(firstFragment); this.container.element.append(lastFragment); this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); @@ -15603,7 +15704,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { BI.each(needDestroyed, function (i, child) { child && child._destroy(); }); - this._debounceRelease(); }, _populate: function (items) { @@ -15628,6 +15728,7 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.renderedIndex = -1; this._clearChildren(); this.cache = {}; + this.options.scrollTop = 0; }, populate: function (items) { diff --git a/bi/core.js b/bi/core.js index f187fb80d8..b922588ac0 100644 --- a/bi/core.js +++ b/bi/core.js @@ -15386,7 +15386,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { } this.floatContainer[name] = BI.createWidget({ type: "bi.absolute", - cls: "bi-list-view", + cls: "bi-popup-view", items: [{ el: (this.floatLayer[name] = BI.createWidget({ type: 'bi.absolute', @@ -15574,7 +15574,7 @@ BI.LayerController = BI.inherit(BI.Controller, { }] }); if (w) { - layout.element.addClass("bi-list-view"); + layout.element.addClass("bi-popup-view"); layout.element.css({ left: w.offset().left + (offset.left || 0), top: w.offset().top + (offset.top || 0), diff --git a/demo/js/config/core.js b/demo/js/config/core.js index 02af07dee0..6163c3f40b 100644 --- a/demo/js/config/core.js +++ b/demo/js/config/core.js @@ -105,7 +105,11 @@ Demo.CORE_CONFIG = [{ pId: 102, text: "bi.collection_view", value: "demo.collection_view" -},{ +}, { + pId: 102, + text: "bi.list_view", + value: "demo.list_view" +}, { pId: 102, text: "bi.virtual_list", value: "demo.virtual_list" diff --git a/demo/js/core/abstract/demo.list_view.js b/demo/js/core/abstract/demo.list_view.js new file mode 100644 index 0000000000..5b1fa0d90c --- /dev/null +++ b/demo/js/core/abstract/demo.list_view.js @@ -0,0 +1,22 @@ +Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, + render: function () { + return { + type: "bi.list_view", + el: { + type: "bi.left" + }, + items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { + return BI.extend({}, item, { + type: "bi.label", + width: 200, + height: 200, + text: (i + 1) + "." + item.text, + }); + }) + } + } +}); +BI.shortcut("demo.list_view", Demo.Func); \ No newline at end of file diff --git a/docs/base.css b/docs/base.css index 9a756c5503..1ced609f64 100644 --- a/docs/base.css +++ b/docs/base.css @@ -1342,30 +1342,30 @@ li.CodeMirror-hint-active { /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ /**********BI.BIListView*************/ -.bi-list-view { +.bi-popup-view { position: fixed !important; overflow-y: visible !important; overflow-x: visible !important; overflow: visible !important; cursor: default; } -.bi-list-view .list-view-outer { +.bi-popup-view .list-view-outer { -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; } -.bi-list-view .list-view-toolbar { +.bi-popup-view .list-view-toolbar { line-height: 30px; } -.bi-list-view .list-view-toolbar > .center-element { +.bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #d4dadd; } -.bi-list-view .list-view-toolbar > .first-element { +.bi-popup-view .list-view-toolbar > .first-element { border-left: none; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .center-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #525466; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .first-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .first-element { border-left: none; } diff --git a/docs/base.js b/docs/base.js index 1e4d9ea34f..4e6604dba2 100644 --- a/docs/base.js +++ b/docs/base.js @@ -15155,7 +15155,7 @@ BI.FloatBox.EVENT_FLOAT_BOX_OPEN = "EVENT_FLOAT_BOX_CLOSED"; BI.PopupView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-view", + baseCls: "bi-popup-view", maxWidth: 'auto', minWidth: 100, //maxHeight: 200, @@ -15458,7 +15458,117 @@ BI.SearcherView.EVENT_CHANGE = "EVENT_CHANGE"; BI.shortcut("bi.searcher_view", BI.SearcherView);/** * 表示当前对象 * - * Created by GUY on 2015/9/7. + * Created by GUY on 2017/5/23. + * @class BI.ListView + * @extends BI.Widget + */ +BI.ListView = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-list-view", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + el: {}, + items: [] + }; + }, + + init: function () { + var self = this; + this.renderedIndex = -1; + this.cache = {}; + }, + + render: function () { + var self = this, o = this.options; + return { + type: "bi.vertical", + items: [BI.extend({ + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, o.el)], + element: this + } + }, + + mounted: function () { + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._calculateBlocksToRender(); + }); + }, + + _renderMoreIf: function () { + var self = this, o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + var getElementHeight = function () { + return self.container.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = getElementHeight() - lastHeight; + this.cache[cnt] = { + index: index, + scrollTop: lastHeight, + height: addedHeight + }; + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; + } + }, + + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + }, + + _populate: function (items) { + var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.container.empty(); + this.cache = {}; + }, + + populate: function (items) { + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); + }, + + destroyed: function () { + this.restore(); + } +}); +BI.shortcut('bi.list_view', BI.ListView); + +/** + * 表示当前对象 + * + * Created by GUY on 2017/5/22. * @class BI.VirtualList * @extends BI.Widget */ @@ -15474,12 +15584,9 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, init: function () { + var self = this; this.renderedIndex = -1; this.cache = {}; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 1000 / 60); }, render: function () { @@ -15553,8 +15660,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { var minContentHeightTo = o.scrollTop + height + o.overscanHeight; var start = this.tree.greatestLowerBound(minContentHeightFrom); var end = this.tree.leastUpperBound(minContentHeightTo); - // this.topBlank.setHeight(0); - // this.bottomBlank.setHeight(0); var needDestroyed = []; for (var i = 0; i < start; i++) { var index = this.cache[i].index; @@ -15585,16 +15690,12 @@ BI.VirtualList = BI.inherit(BI.Widget, { } if (this.cache[i].destroyed === true) { for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - var w = this.container._children[j] = BI.createWidget(BI.extend({ - root: true - }, BI.stripEL(o.items[j]))); - w.element.css("position", "relative");//vertical布局下position要改成relative + var w = this.container._addElement(j, BI.extend({root: true}, BI.stripEL(o.items[j]))); currentFragment.appendChild(w.element[0]); } this.cache[i].destroyed = false; } } - this._scrollLock = true; this.container.element.prepend(firstFragment); this.container.element.append(lastFragment); this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); @@ -15603,7 +15704,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { BI.each(needDestroyed, function (i, child) { child && child._destroy(); }); - this._debounceRelease(); }, _populate: function (items) { @@ -15628,6 +15728,7 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.renderedIndex = -1; this._clearChildren(); this.cache = {}; + this.options.scrollTop = 0; }, populate: function (items) { diff --git a/docs/core.js b/docs/core.js index 77fa17ae0f..ce382815e3 100644 --- a/docs/core.js +++ b/docs/core.js @@ -20984,7 +20984,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { } this.floatContainer[name] = BI.createWidget({ type: "bi.absolute", - cls: "bi-list-view", + cls: "bi-popup-view", items: [{ el: (this.floatLayer[name] = BI.createWidget({ type: 'bi.absolute', @@ -21172,7 +21172,7 @@ BI.LayerController = BI.inherit(BI.Controller, { }] }); if (w) { - layout.element.addClass("bi-list-view"); + layout.element.addClass("bi-popup-view"); layout.element.css({ left: w.offset().left + (offset.left || 0), top: w.offset().top + (offset.top || 0), diff --git a/docs/demo.js b/docs/demo.js index 2f6f7af47d..3db7d72868 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -3038,7 +3038,11 @@ Demo.COMPONENT_CONFIG = [{ pId: 102, text: "bi.collection_view", value: "demo.collection_view" -},{ +}, { + pId: 102, + text: "bi.list_view", + value: "demo.list_view" +}, { pId: 102, text: "bi.virtual_list", value: "demo.virtual_list" @@ -3407,6 +3411,27 @@ BI.shortcut("demo.grid_view", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { props: { baseCls: "demo-func" }, + render: function () { + return { + type: "bi.list_view", + el: { + type: "bi.left" + }, + items: BI.map(Demo.CONSTANTS.ITEMS, function (i, item) { + return BI.extend({}, item, { + type: "bi.label", + width: 200, + height: 200, + text: (i + 1) + "." + item.text, + }); + }) + } + } +}); +BI.shortcut("demo.list_view", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, _createItems: function () { var items = BI.makeArray(100, { diff --git a/src/base/layer/layer.popup.js b/src/base/layer/layer.popup.js index 1af2125776..2d683d3d94 100644 --- a/src/base/layer/layer.popup.js +++ b/src/base/layer/layer.popup.js @@ -6,7 +6,7 @@ BI.PopupView = BI.inherit(BI.Widget, { _defaultConfig: function () { return BI.extend(BI.PopupView.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-list-view", + baseCls: "bi-popup-view", maxWidth: 'auto', minWidth: 100, //maxHeight: 200, diff --git a/src/base/list/listview.js b/src/base/list/listview.js new file mode 100644 index 0000000000..4659e5d0d3 --- /dev/null +++ b/src/base/list/listview.js @@ -0,0 +1,110 @@ +/** + * 表示当前对象 + * + * Created by GUY on 2017/5/23. + * @class BI.ListView + * @extends BI.Widget + */ +BI.ListView = BI.inherit(BI.Widget, { + props: function () { + return { + baseCls: "bi-list-view", + overscanHeight: 100, + blockSize: 10, + scrollTop: 0, + el: {}, + items: [] + }; + }, + + init: function () { + var self = this; + this.renderedIndex = -1; + this.cache = {}; + }, + + render: function () { + var self = this, o = this.options; + return { + type: "bi.vertical", + items: [BI.extend({ + type: "bi.vertical", + scrolly: false, + ref: function () { + self.container = this; + } + }, o.el)], + element: this + } + }, + + mounted: function () { + var self = this, o = this.options; + this._populate(); + this.element.scroll(function (e) { + o.scrollTop = self.element.scrollTop(); + self._calculateBlocksToRender(); + }); + BI.ResizeDetector.addResizeListener(this, function () { + self._calculateBlocksToRender(); + }); + }, + + _renderMoreIf: function () { + var self = this, o = this.options; + var height = this.element.height(); + var minContentHeight = o.scrollTop + height + o.overscanHeight; + var index = (this.cache[this.renderedIndex] && (this.cache[this.renderedIndex].index + o.blockSize)) || 0, + cnt = this.renderedIndex + 1; + var lastHeight; + var getElementHeight = function () { + return self.container.element.height(); + }; + while ((lastHeight = getElementHeight()) < minContentHeight && index < o.items.length) { + var items = o.items.slice(index, index + o.blockSize); + this.container.addItems(items); + var addedHeight = getElementHeight() - lastHeight; + this.cache[cnt] = { + index: index, + scrollTop: lastHeight, + height: addedHeight + }; + this.renderedIndex = cnt; + cnt++; + index += o.blockSize; + } + }, + + _calculateBlocksToRender: function () { + var o = this.options; + this._renderMoreIf(); + }, + + _populate: function (items) { + var o = this.options; + if (items && this.options.items !== items) { + this.options.items = items; + } + this._calculateBlocksToRender(); + this.element.scrollTop(o.scrollTop); + }, + + restore: function () { + this.renderedIndex = -1; + this.container.empty(); + this.cache = {}; + }, + + populate: function (items) { + if (items && this.options.items !== items) { + this.restore(); + } + this._populate(); + }, + + destroyed: function () { + this.restore(); + } +}); +BI.shortcut('bi.list_view', BI.ListView); + diff --git a/src/base/list/virtuallist.js b/src/base/list/virtuallist.js index e4c7e76cdd..fce34dbb77 100644 --- a/src/base/list/virtuallist.js +++ b/src/base/list/virtuallist.js @@ -1,7 +1,7 @@ /** * 表示当前对象 * - * Created by GUY on 2015/9/7. + * Created by GUY on 2017/5/22. * @class BI.VirtualList * @extends BI.Widget */ @@ -17,12 +17,9 @@ BI.VirtualList = BI.inherit(BI.Widget, { }, init: function () { + var self = this; this.renderedIndex = -1; this.cache = {}; - this._scrollLock = false; - this._debounceRelease = BI.debounce(function () { - self._scrollLock = false; - }, 1000 / 60); }, render: function () { @@ -96,8 +93,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { var minContentHeightTo = o.scrollTop + height + o.overscanHeight; var start = this.tree.greatestLowerBound(minContentHeightFrom); var end = this.tree.leastUpperBound(minContentHeightTo); - // this.topBlank.setHeight(0); - // this.bottomBlank.setHeight(0); var needDestroyed = []; for (var i = 0; i < start; i++) { var index = this.cache[i].index; @@ -128,16 +123,12 @@ BI.VirtualList = BI.inherit(BI.Widget, { } if (this.cache[i].destroyed === true) { for (var j = index; j < index + o.blockSize && j < o.items.length; j++) { - var w = this.container._children[j] = BI.createWidget(BI.extend({ - root: true - }, BI.stripEL(o.items[j]))); - w.element.css("position", "relative");//vertical布局下position要改成relative + var w = this.container._addElement(j, BI.extend({root: true}, BI.stripEL(o.items[j]))); currentFragment.appendChild(w.element[0]); } this.cache[i].destroyed = false; } } - this._scrollLock = true; this.container.element.prepend(firstFragment); this.container.element.append(lastFragment); this.topBlank.setHeight(this.cache[start < 0 ? 0 : start].scrollTop); @@ -146,7 +137,6 @@ BI.VirtualList = BI.inherit(BI.Widget, { BI.each(needDestroyed, function (i, child) { child && child._destroy(); }); - this._debounceRelease(); }, _populate: function (items) { @@ -171,6 +161,7 @@ BI.VirtualList = BI.inherit(BI.Widget, { this.renderedIndex = -1; this._clearChildren(); this.cache = {}; + this.options.scrollTop = 0; }, populate: function (items) { diff --git a/src/core/controller/controller.floatbox.js b/src/core/controller/controller.floatbox.js index f721a8fac1..413526caeb 100644 --- a/src/core/controller/controller.floatbox.js +++ b/src/core/controller/controller.floatbox.js @@ -47,7 +47,7 @@ BI.FloatBoxController = BI.inherit(BI.Controller, { } this.floatContainer[name] = BI.createWidget({ type: "bi.absolute", - cls: "bi-list-view", + cls: "bi-popup-view", items: [{ el: (this.floatLayer[name] = BI.createWidget({ type: 'bi.absolute', diff --git a/src/core/controller/controller.layer.js b/src/core/controller/controller.layer.js index e42d938af2..fd644d4699 100644 --- a/src/core/controller/controller.layer.js +++ b/src/core/controller/controller.layer.js @@ -93,7 +93,7 @@ BI.LayerController = BI.inherit(BI.Controller, { }] }); if (w) { - layout.element.addClass("bi-list-view"); + layout.element.addClass("bi-popup-view"); layout.element.css({ left: w.offset().left + (offset.left || 0), top: w.offset().top + (offset.top || 0), diff --git a/src/css/base/view/popupview.css b/src/css/base/view/popupview.css index b30d1eb054..272a716bfd 100644 --- a/src/css/base/view/popupview.css +++ b/src/css/base/view/popupview.css @@ -2,30 +2,30 @@ /****** common color(常用颜色,可用于普遍场景) *****/ /**** custom color(自定义颜色,用于特定场景) ****/ /**********BI.BIListView*************/ -.bi-list-view { +.bi-popup-view { position: fixed !important; overflow-y: visible !important; overflow-x: visible !important; overflow: visible !important; cursor: default; } -.bi-list-view .list-view-outer { +.bi-popup-view .list-view-outer { -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; } -.bi-list-view .list-view-toolbar { +.bi-popup-view .list-view-toolbar { line-height: 30px; } -.bi-list-view .list-view-toolbar > .center-element { +.bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #d4dadd; } -.bi-list-view .list-view-toolbar > .first-element { +.bi-popup-view .list-view-toolbar > .first-element { border-left: none; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .center-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .center-element { border-left: 1px solid #525466; } -.bi-theme-dark .bi-list-view .list-view-toolbar > .first-element { +.bi-theme-dark .bi-popup-view .list-view-toolbar > .first-element { border-left: none; } diff --git a/src/less/base/view/popupview.less b/src/less/base/view/popupview.less index 527d87cb43..66e49d57bf 100644 --- a/src/less/base/view/popupview.less +++ b/src/less/base/view/popupview.less @@ -1,7 +1,7 @@ @import "../../bibase"; /**********BI.BIListView*************/ -.bi-list-view { +.bi-popup-view { position: fixed !important; overflow-y: visible !important; overflow-x: visible !important; @@ -22,7 +22,7 @@ } .bi-theme-dark { - .bi-list-view { + .bi-popup-view { & .list-view-toolbar { & > .center-element { border-left: 1px solid @color-bi-border-line-theme-dark; From 23860d03fb8ffb264c7cb30bcf3725db2d245a35 Mon Sep 17 00:00:00 2001 From: windy <1374721899@qq.com> Date: Tue, 23 May 2017 09:38:07 +0800 Subject: [PATCH 21/27] =?UTF-8?q?class=E5=86=99=E9=94=99=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bi/widget.js | 4 ++-- docs/widget.js | 4 ++-- src/component/allvaluechooser/abstract.allvaluechooser.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bi/widget.js b/bi/widget.js index 778e5221f4..37afe2e44c 100644 --- a/bi/widget.js +++ b/bi/widget.js @@ -16978,7 +16978,7 @@ BI.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo);/** * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.AllValueChooserCombo + * @class BI.AbstractAllValueChooser * @extends BI.Widget */ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { @@ -16988,7 +16988,7 @@ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { }, _defaultConfig: function () { - return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + return BI.extend(BI.AbstractAllValueChooser.superclass._defaultConfig.apply(this, arguments), { width: 200, height: 30, items: null, diff --git a/docs/widget.js b/docs/widget.js index 778e5221f4..37afe2e44c 100644 --- a/docs/widget.js +++ b/docs/widget.js @@ -16978,7 +16978,7 @@ BI.shortcut('bi.year_quarter_combo', BI.YearQuarterCombo);/** * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.AllValueChooserCombo + * @class BI.AbstractAllValueChooser * @extends BI.Widget */ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { @@ -16988,7 +16988,7 @@ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { }, _defaultConfig: function () { - return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + return BI.extend(BI.AbstractAllValueChooser.superclass._defaultConfig.apply(this, arguments), { width: 200, height: 30, items: null, diff --git a/src/component/allvaluechooser/abstract.allvaluechooser.js b/src/component/allvaluechooser/abstract.allvaluechooser.js index fadfd6d3f8..5183a27fa7 100644 --- a/src/component/allvaluechooser/abstract.allvaluechooser.js +++ b/src/component/allvaluechooser/abstract.allvaluechooser.js @@ -3,7 +3,7 @@ * 封装了字段处理逻辑 * * Created by GUY on 2015/10/29. - * @class BI.AllValueChooserCombo + * @class BI.AbstractAllValueChooser * @extends BI.Widget */ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { @@ -13,7 +13,7 @@ BI.AbstractAllValueChooser = BI.inherit(BI.Widget, { }, _defaultConfig: function () { - return BI.extend(BI.AllValueChooserCombo.superclass._defaultConfig.apply(this, arguments), { + return BI.extend(BI.AbstractAllValueChooser.superclass._defaultConfig.apply(this, arguments), { width: 200, height: 30, items: null, From ea531c9a42b6efec3a1e5f3b03ed2807279b29be Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 23 May 2017 14:25:03 +0800 Subject: [PATCH 22/27] add --- bi/case.js | 17 +++++++++-------- bi/core.js | 11 +++++++---- demo/version.js | 4 ++-- docs/case.js | 17 +++++++++-------- docs/core.js | 11 +++++++---- docs/demo.js | 4 ++-- src/case/zclip/zclip.js | 17 +++++++++-------- src/core/widget.js | 11 +++++++---- 8 files changed, 52 insertions(+), 40 deletions(-) diff --git a/bi/case.js b/bi/case.js index 240ab1d94f..f9b5bc7f15 100644 --- a/bi/case.js +++ b/bi/case.js @@ -11743,17 +11743,18 @@ BI.ZeroClip = BI.inherit(BI.BasicButton, { afterCopy: BI.emptyFn }) }, + _init: function () { BI.ZeroClip.superclass._init.apply(this, arguments); - var self = this, o = this.options; + }, - BI.nextTick(function () { - self.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); + mounted: function () { + var self = this, o = this.options; + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy }); } }); diff --git a/bi/core.js b/bi/core.js index b922588ac0..b5300f68ee 100644 --- a/bi/core.js +++ b/bi/core.js @@ -4365,9 +4365,10 @@ BI.Widget = BI.inherit(BI.OB, { this._initRoot(); this._initElementWidth(); this._initElementHeight(); - this._initVisualEffects(); + this._initVisual(); this._initState(); this._initElement(); + this._initEffects(); this.created && this.created(); }, @@ -4422,21 +4423,23 @@ BI.Widget = BI.inherit(BI.OB, { } }, - _initVisualEffects: function () { + _initVisual: function () { var o = this.options; if (o.invisible) { //用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性 this.element.css("display", "none"); } + }, + + _initEffects: function () { + var o = this.options; if (o.disabled || o.invalid) { - // BI.nextTick(BI.bind(function () { if (this.options.disabled) { this.setEnable(false); } if (this.options.invalid) { this.setValid(false); } - // }, this)); } }, diff --git a/demo/version.js b/demo/version.js index 5e16777ec5..b1075f22df 100644 --- a/demo/version.js +++ b/demo/version.js @@ -6,6 +6,6 @@ BI.i18n = { "BI-Basic_OK": "确定" }; -BI.servletURL = "dist/"; -BI.resourceURL = "dist/resource/"; +BI.servletURL = "docs/"; +BI.resourceURL = "docs/resource/"; BI.i18n = {}; \ No newline at end of file diff --git a/docs/case.js b/docs/case.js index 240ab1d94f..f9b5bc7f15 100644 --- a/docs/case.js +++ b/docs/case.js @@ -11743,17 +11743,18 @@ BI.ZeroClip = BI.inherit(BI.BasicButton, { afterCopy: BI.emptyFn }) }, + _init: function () { BI.ZeroClip.superclass._init.apply(this, arguments); - var self = this, o = this.options; + }, - BI.nextTick(function () { - self.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); + mounted: function () { + var self = this, o = this.options; + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy }); } }); diff --git a/docs/core.js b/docs/core.js index ce382815e3..44c9a2757a 100644 --- a/docs/core.js +++ b/docs/core.js @@ -14367,9 +14367,10 @@ BI.Widget = BI.inherit(BI.OB, { this._initRoot(); this._initElementWidth(); this._initElementHeight(); - this._initVisualEffects(); + this._initVisual(); this._initState(); this._initElement(); + this._initEffects(); this.created && this.created(); }, @@ -14424,21 +14425,23 @@ BI.Widget = BI.inherit(BI.OB, { } }, - _initVisualEffects: function () { + _initVisual: function () { var o = this.options; if (o.invisible) { //用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性 this.element.css("display", "none"); } + }, + + _initEffects: function () { + var o = this.options; if (o.disabled || o.invalid) { - // BI.nextTick(BI.bind(function () { if (this.options.disabled) { this.setEnable(false); } if (this.options.invalid) { this.setValid(false); } - // }, this)); } }, diff --git a/docs/demo.js b/docs/demo.js index 3db7d72868..59416a3043 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -6,8 +6,8 @@ BI.i18n = { "BI-Basic_OK": "确定" }; -BI.servletURL = "dist/"; -BI.resourceURL = "dist/resource/"; +BI.servletURL = "docs/"; +BI.resourceURL = "docs/resource/"; BI.i18n = {};$(function () { var ref; BI.createWidget({ diff --git a/src/case/zclip/zclip.js b/src/case/zclip/zclip.js index 7a7d99132c..266cc68a6f 100644 --- a/src/case/zclip/zclip.js +++ b/src/case/zclip/zclip.js @@ -13,17 +13,18 @@ BI.ZeroClip = BI.inherit(BI.BasicButton, { afterCopy: BI.emptyFn }) }, + _init: function () { BI.ZeroClip.superclass._init.apply(this, arguments); - var self = this, o = this.options; + }, - BI.nextTick(function () { - self.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); + mounted: function () { + var self = this, o = this.options; + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy }); } }); diff --git a/src/core/widget.js b/src/core/widget.js index 3e217a5c3f..dd9f56b3c4 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -45,9 +45,10 @@ BI.Widget = BI.inherit(BI.OB, { this._initRoot(); this._initElementWidth(); this._initElementHeight(); - this._initVisualEffects(); + this._initVisual(); this._initState(); this._initElement(); + this._initEffects(); this.created && this.created(); }, @@ -102,21 +103,23 @@ BI.Widget = BI.inherit(BI.OB, { } }, - _initVisualEffects: function () { + _initVisual: function () { var o = this.options; if (o.invisible) { //用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性 this.element.css("display", "none"); } + }, + + _initEffects: function () { + var o = this.options; if (o.disabled || o.invalid) { - // BI.nextTick(BI.bind(function () { if (this.options.disabled) { this.setEnable(false); } if (this.options.invalid) { this.setValid(false); } - // }, this)); } }, From cb298712ab638fe5f79eac84e3048fd49e6fadd7 Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 23 May 2017 15:15:59 +0800 Subject: [PATCH 23/27] add --- bi/base.js | 8 ++++---- docs/base.js | 8 ++++---- src/base/single/button/button.basic.js | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bi/base.js b/bi/base.js index 4e6604dba2..9f79c10d19 100644 --- a/bi/base.js +++ b/bi/base.js @@ -797,7 +797,7 @@ BI.BasicButton = BI.inherit(BI.Single, { if (!self.isEnabled() || (self.isOnce() && self.isSelected())) { return; } - onClick.apply(self); + onClick.apply(self, arguments); } }, @@ -816,13 +816,13 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - _doClick: function () { + _doClick: function (e) { if (this.isValid()) { - this.beforeClick(); + this.beforeClick(e); } this._trigger(); if (this.isValid()) { - this.doClick(); + this.doClick(e); } }, diff --git a/docs/base.js b/docs/base.js index 4e6604dba2..9f79c10d19 100644 --- a/docs/base.js +++ b/docs/base.js @@ -797,7 +797,7 @@ BI.BasicButton = BI.inherit(BI.Single, { if (!self.isEnabled() || (self.isOnce() && self.isSelected())) { return; } - onClick.apply(self); + onClick.apply(self, arguments); } }, @@ -816,13 +816,13 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - _doClick: function () { + _doClick: function (e) { if (this.isValid()) { - this.beforeClick(); + this.beforeClick(e); } this._trigger(); if (this.isValid()) { - this.doClick(); + this.doClick(e); } }, diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js index 636fb51d4b..c5de615f56 100644 --- a/src/base/single/button/button.basic.js +++ b/src/base/single/button/button.basic.js @@ -214,7 +214,7 @@ BI.BasicButton = BI.inherit(BI.Single, { if (!self.isEnabled() || (self.isOnce() && self.isSelected())) { return; } - onClick.apply(self); + onClick.apply(self, arguments); } }, @@ -233,13 +233,13 @@ BI.BasicButton = BI.inherit(BI.Single, { } }, - _doClick: function () { + _doClick: function (e) { if (this.isValid()) { - this.beforeClick(); + this.beforeClick(e); } this._trigger(); if (this.isValid()) { - this.doClick(); + this.doClick(e); } }, From 078a6b6a080a986fecc23e54993e93b3a82095ef Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 23 May 2017 17:37:33 +0800 Subject: [PATCH 24/27] add --- bi/core.js | 95 +++++++++++++++++++++------------------- demo/version.js | 4 +- docs/core.js | 95 +++++++++++++++++++++------------------- docs/demo.js | 4 +- src/core/proto/jquery.js | 95 +++++++++++++++++++++------------------- 5 files changed, 154 insertions(+), 139 deletions(-) diff --git a/bi/core.js b/bi/core.js index b5300f68ee..2e88efc9ba 100644 --- a/bi/core.js +++ b/bi/core.js @@ -6547,59 +6547,64 @@ Function.prototype.after = function (func) { * All rights reserved. */ if (jQuery) { - (function($){ + (function ($) { // richer:容器在其各个边缘留出的空间 - $.fn.insets = function () { - var p = this.padding(), - b = this.border(); - return { - 'top': p.top, - 'bottom': p.bottom + b.bottom + b.top, - 'left': p.left, - 'right': p.right + b.right + b.left + if (!$.fn.insets) { + $.fn.insets = function () { + var p = this.padding(), + b = this.border(); + return { + 'top': p.top, + 'bottom': p.bottom + b.bottom + b.top, + 'left': p.left, + 'right': p.right + b.right + b.left + }; }; - }; + } // richer:获取 && 设置jQuery元素的边界 - $.fn.bounds = function (value) { - var tmp = {hasIgnoredBounds : true}; + if (!$.fn.bounds) { + $.fn.bounds = function (value) { + var tmp = {hasIgnoredBounds: true}; - if (value) { - if (!isNaN(value.x)) { - tmp.left = value.x; - } - if (!isNaN(value.y)) { - tmp.top = value.y; - } - if (value.width != null) { - tmp.width = (value.width - (this.outerWidth(true) - this.width())); - tmp.width = (tmp.width >= 0) ? tmp.width : value.width; - // fix chrome - //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + return this; } - if (value.height != null) { - tmp.height = value.height - (this.outerHeight(true) - this.height()); - tmp.height = (tmp.height >= 0) ? tmp.height : value.height; - // fix chrome - //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + else { + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + return { + 'x': tmp.left, + 'y': tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + 'width': this.outerWidth(), + 'height': this.outerHeight() + }; } - this.css(tmp); - return this; - } - else { - // richer:注意此方法只对可见元素有效 - tmp = this.position(); - return { - 'x': tmp.left, - 'y': tmp.top, - // richer:这里计算外部宽度和高度的时候,都不包括边框 - 'width': this.outerWidth(), - 'height': this.outerHeight() - }; - } - }; + }; + } })(jQuery); -};if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || +} +;if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") { (function () { diff --git a/demo/version.js b/demo/version.js index b1075f22df..afe18ced1a 100644 --- a/demo/version.js +++ b/demo/version.js @@ -6,6 +6,6 @@ BI.i18n = { "BI-Basic_OK": "确定" }; -BI.servletURL = "docs/"; -BI.resourceURL = "docs/resource/"; +BI.servletURL = ""; +BI.resourceURL = "resource/"; BI.i18n = {}; \ No newline at end of file diff --git a/docs/core.js b/docs/core.js index 44c9a2757a..854962a550 100644 --- a/docs/core.js +++ b/docs/core.js @@ -24081,59 +24081,64 @@ Function.prototype.after = function (func) { * All rights reserved. */ if (jQuery) { - (function($){ + (function ($) { // richer:容器在其各个边缘留出的空间 - $.fn.insets = function () { - var p = this.padding(), - b = this.border(); - return { - 'top': p.top, - 'bottom': p.bottom + b.bottom + b.top, - 'left': p.left, - 'right': p.right + b.right + b.left + if (!$.fn.insets) { + $.fn.insets = function () { + var p = this.padding(), + b = this.border(); + return { + 'top': p.top, + 'bottom': p.bottom + b.bottom + b.top, + 'left': p.left, + 'right': p.right + b.right + b.left + }; }; - }; + } // richer:获取 && 设置jQuery元素的边界 - $.fn.bounds = function (value) { - var tmp = {hasIgnoredBounds : true}; + if (!$.fn.bounds) { + $.fn.bounds = function (value) { + var tmp = {hasIgnoredBounds: true}; - if (value) { - if (!isNaN(value.x)) { - tmp.left = value.x; - } - if (!isNaN(value.y)) { - tmp.top = value.y; - } - if (value.width != null) { - tmp.width = (value.width - (this.outerWidth(true) - this.width())); - tmp.width = (tmp.width >= 0) ? tmp.width : value.width; - // fix chrome - //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + return this; } - if (value.height != null) { - tmp.height = value.height - (this.outerHeight(true) - this.height()); - tmp.height = (tmp.height >= 0) ? tmp.height : value.height; - // fix chrome - //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + else { + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + return { + 'x': tmp.left, + 'y': tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + 'width': this.outerWidth(), + 'height': this.outerHeight() + }; } - this.css(tmp); - return this; - } - else { - // richer:注意此方法只对可见元素有效 - tmp = this.position(); - return { - 'x': tmp.left, - 'y': tmp.top, - // richer:这里计算外部宽度和高度的时候,都不包括边框 - 'width': this.outerWidth(), - 'height': this.outerHeight() - }; - } - }; + }; + } })(jQuery); -};if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || +} +;if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") { (function () { diff --git a/docs/demo.js b/docs/demo.js index 59416a3043..23accd576d 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -6,8 +6,8 @@ BI.i18n = { "BI-Basic_OK": "确定" }; -BI.servletURL = "docs/"; -BI.resourceURL = "docs/resource/"; +BI.servletURL = ""; +BI.resourceURL = "resource/"; BI.i18n = {};$(function () { var ref; BI.createWidget({ diff --git a/src/core/proto/jquery.js b/src/core/proto/jquery.js index 408285a4f9..522c9c31d5 100644 --- a/src/core/proto/jquery.js +++ b/src/core/proto/jquery.js @@ -6,56 +6,61 @@ * All rights reserved. */ if (jQuery) { - (function($){ + (function ($) { // richer:容器在其各个边缘留出的空间 - $.fn.insets = function () { - var p = this.padding(), - b = this.border(); - return { - 'top': p.top, - 'bottom': p.bottom + b.bottom + b.top, - 'left': p.left, - 'right': p.right + b.right + b.left + if (!$.fn.insets) { + $.fn.insets = function () { + var p = this.padding(), + b = this.border(); + return { + 'top': p.top, + 'bottom': p.bottom + b.bottom + b.top, + 'left': p.left, + 'right': p.right + b.right + b.left + }; }; - }; + } // richer:获取 && 设置jQuery元素的边界 - $.fn.bounds = function (value) { - var tmp = {hasIgnoredBounds : true}; + if (!$.fn.bounds) { + $.fn.bounds = function (value) { + var tmp = {hasIgnoredBounds: true}; - if (value) { - if (!isNaN(value.x)) { - tmp.left = value.x; - } - if (!isNaN(value.y)) { - tmp.top = value.y; - } - if (value.width != null) { - tmp.width = (value.width - (this.outerWidth(true) - this.width())); - tmp.width = (tmp.width >= 0) ? tmp.width : value.width; - // fix chrome - //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + if (value) { + if (!isNaN(value.x)) { + tmp.left = value.x; + } + if (!isNaN(value.y)) { + tmp.top = value.y; + } + if (value.width != null) { + tmp.width = (value.width - (this.outerWidth(true) - this.width())); + tmp.width = (tmp.width >= 0) ? tmp.width : value.width; + // fix chrome + //tmp.width = (tmp.width >= 0) ? tmp.width : 0; + } + if (value.height != null) { + tmp.height = value.height - (this.outerHeight(true) - this.height()); + tmp.height = (tmp.height >= 0) ? tmp.height : value.height; + // fix chrome + //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + } + this.css(tmp); + return this; } - if (value.height != null) { - tmp.height = value.height - (this.outerHeight(true) - this.height()); - tmp.height = (tmp.height >= 0) ? tmp.height : value.height; - // fix chrome - //tmp.height = (tmp.height >= 0) ? tmp.height : value.0; + else { + // richer:注意此方法只对可见元素有效 + tmp = this.position(); + return { + 'x': tmp.left, + 'y': tmp.top, + // richer:这里计算外部宽度和高度的时候,都不包括边框 + 'width': this.outerWidth(), + 'height': this.outerHeight() + }; } - this.css(tmp); - return this; - } - else { - // richer:注意此方法只对可见元素有效 - tmp = this.position(); - return { - 'x': tmp.left, - 'y': tmp.top, - // richer:这里计算外部宽度和高度的时候,都不包括边框 - 'width': this.outerWidth(), - 'height': this.outerHeight() - }; - } - }; + }; + } })(jQuery); -}; \ No newline at end of file +} +; \ No newline at end of file From cbe953d6b060fa9c1df798b9acf85bc135ad8df9 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 24 May 2017 01:33:04 +0800 Subject: [PATCH 25/27] =?UTF-8?q?=E5=A4=8D=E5=88=B6=E5=88=B0=E7=B2=98?= =?UTF-8?q?=E8=B4=B4=E6=9D=BF=E6=94=B9=E7=94=A8clipboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bi/case.js | 1343 +++++++++++++++++++------------ demo/js/case/demo.zclip.js | 10 +- demo/js/config/case.js | 4 +- docs/case.js | 1343 +++++++++++++++++++------------ docs/demo.js | 14 +- docs/resource/ZeroClipboard.swf | Bin 1071 -> 0 bytes src/case/clipboard/clipboard.js | 778 ++++++++++++++++++ src/case/clipboard/index.js | 37 + src/case/zclip/jquery.zclip.js | 495 ------------ src/case/zclip/zclip.js | 32 - 10 files changed, 2459 insertions(+), 1597 deletions(-) delete mode 100644 docs/resource/ZeroClipboard.swf create mode 100644 src/case/clipboard/clipboard.js create mode 100644 src/case/clipboard/index.js delete mode 100644 src/case/zclip/jquery.zclip.js delete mode 100644 src/case/zclip/zclip.js diff --git a/bi/case.js b/bi/case.js index f9b5bc7f15..7212e6106a 100644 --- a/bi/case.js +++ b/bi/case.js @@ -2222,7 +2222,820 @@ BI.TreeNodeCheckbox = BI.inherit(BI.IconButton, { } } }); -BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/** +BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/*! + * clipboard.js v1.6.1 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; + + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2.default)(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2.default)(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); + + return ClipboardAction; + }(); + + module.exports = ClipboardAction; + }); + +},{"select":5}],8:[function(require,module,exports){ + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; + + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + + var _goodListener2 = _interopRequireDefault(_goodListener); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); + + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); + + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } + + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ + + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2.default({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; + + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; + } + }]); + + return Clipboard; + }(_tinyEmitter2.default); + + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; + } + + return element.getAttribute(attribute); + } + + module.exports = Clipboard; + }); + +},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) +});/** + * 复制 + * Created by GUY on 2016/2/16. + * @class BI.ClipBoard + * @extends BI.BasicButton + */ +BI.ClipBoard = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-clipboard", + text: "", + afterCopy: BI.emptyFn + }) + }, + + _init: function () { + BI.ClipBoard.superclass._init.apply(this, arguments); + }, + + mounted: function () { + var self = this, o = this.options; + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.text) ? o.text() : o.text; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + }, + + destroyed: function () { + this.clipboard.destroy(); + } +}); + +BI.shortcut("bi.clipboard", BI.ClipBoard);/** * 自定义选色 * * Created by GUY on 2015/11/17. @@ -11233,530 +12046,4 @@ BI.SmallTextTrigger = BI.inherit(BI.Trigger, { this.text.setText(text); } }); -BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger);/* - * zClip :: jQuery ZeroClipboard v1.1.1 - * http://steamdev.com/zclip - * - * Copyright 2011, SteamDev - * Released under the MIT license. - * http://www.opensource.org/licenses/mit-license.php - * - * Date: Wed Jun 01, 2011 - */ - - -(function ($) { - - $.fn.zclip = function (params) { - - if (typeof params == "object" && !params.length) { - - var settings = $.extend({ - - path: 'ZeroClipboard.swf', - copy: null, - beforeCopy: null, - afterCopy: null, - clickAfter: true, - setHandCursor: true, - setCSSEffects: true - - }, params); - - - return this.each(function () { - - var o = $(this); - - if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { - - ZeroClipboard.setMoviePath(settings.path); - var clip = new ZeroClipboard.Client(); - - if($.isFunction(settings.copy)){ - o.bind('zClip_copy',settings.copy); - } - if($.isFunction(settings.beforeCopy)){ - o.bind('zClip_beforeCopy',settings.beforeCopy); - } - if($.isFunction(settings.afterCopy)){ - o.bind('zClip_afterCopy',settings.afterCopy); - } - - clip.setHandCursor(settings.setHandCursor); - clip.setCSSEffects(settings.setCSSEffects); - clip.addEventListener('mouseOver', function (client) { - o.trigger('mouseenter'); - }); - clip.addEventListener('mouseOut', function (client) { - o.trigger('mouseleave'); - }); - clip.addEventListener('mouseDown', function (client) { - - o.trigger('mousedown'); - - if(!$.isFunction(settings.copy)){ - clip.setText(settings.copy); - } else { - clip.setText(o.triggerHandler('zClip_copy')); - } - - if ($.isFunction(settings.beforeCopy)) { - o.trigger('zClip_beforeCopy'); - } - - }); - - clip.addEventListener('complete', function (client, text) { - - if ($.isFunction(settings.afterCopy)) { - - o.trigger('zClip_afterCopy'); - - } else { - if (text.length > 500) { - text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; - } - - o.removeClass('hover'); - alert("Copied text to clipboard:\n\n " + text); - } - - if (settings.clickAfter) { - o.trigger('click'); - } - - }); - - - clip.glue(o[0], o.parent()[0]); - - $(window).bind('load resize',function(){clip.reposition();}); - - - } - - }); - - } else if (typeof params == "string") { - - return this.each(function () { - - var o = $(this); - - params = params.toLowerCase(); - var zclipId = o.data('zclipId'); - var clipElm = $('#' + zclipId + '.zclip'); - - if (params == "remove") { - - clipElm.remove(); - o.removeClass('active hover'); - - } else if (params == "hide") { - - clipElm.hide(); - o.removeClass('active hover'); - - } else if (params == "show") { - - clipElm.show(); - - } - - }); - - } - - } - - - -})(jQuery); - - - - - - - -// ZeroClipboard -// Simple Set Clipboard System -// Author: Joseph Huckaby -var ZeroClipboard = { - - version: "1.0.7", - clients: {}, - // registered upload clients on page, indexed by id - moviePath: 'ZeroClipboard.swf', - // URL to movie - nextId: 1, - // ID of next movie - $: function (thingy) { - // simple DOM lookup utility function - if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); - if (!thingy.addClass) { - // extend element with a few useful methods - thingy.hide = function () { - this.style.display = 'none'; - }; - thingy.show = function () { - this.style.display = ''; - }; - thingy.addClass = function (name) { - this.removeClass(name); - this.className += ' ' + name; - }; - thingy.removeClass = function (name) { - var classes = this.className.split(/\s+/); - var idx = -1; - for (var k = 0; k < classes.length; k++) { - if (classes[k] == name) { - idx = k; - k = classes.length; - } - } - if (idx > -1) { - classes.splice(idx, 1); - this.className = classes.join(' '); - } - return this; - }; - thingy.hasClass = function (name) { - return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); - }; - } - return thingy; - }, - - setMoviePath: function (path) { - // set path to ZeroClipboard.swf - this.moviePath = path; - }, - - dispatch: function (id, eventName, args) { - // receive event from flash movie, send to client - var client = this.clients[id]; - if (client) { - client.receiveEvent(eventName, args); - } - }, - - register: function (id, client) { - // register new client to receive events - this.clients[id] = client; - }, - - getDOMObjectPosition: function (obj, stopObj) { - // get absolute coordinates for dom element - var info = { - left: 0, - top: 0, - width: obj.width ? obj.width : obj.offsetWidth, - height: obj.height ? obj.height : obj.offsetHeight - }; - - if (obj && (obj != stopObj)) { - info.left += obj.offsetLeft; - info.top += obj.offsetTop; - } - - return info; - }, - - Client: function (elem) { - // constructor for new simple upload client - this.handlers = {}; - - // unique ID - this.id = ZeroClipboard.nextId++; - this.movieId = 'ZeroClipboardMovie_' + this.id; - - // register client with singleton to receive flash events - ZeroClipboard.register(this.id, this); - - // create movie - if (elem) this.glue(elem); - } -}; - -ZeroClipboard.Client.prototype = { - - id: 0, - // unique ID for us - ready: false, - // whether movie is ready to receive events or not - movie: null, - // reference to movie object - clipText: '', - // text to copy to clipboard - handCursorEnabled: true, - // whether to show hand cursor, or default pointer cursor - cssEffects: true, - // enable CSS mouse effects on dom container - handlers: null, - // user event handlers - glue: function (elem, appendElem, stylesToAdd) { - // glue to DOM element - // elem can be ID or actual DOM element object - this.domElement = ZeroClipboard.$(elem); - - // float just above object, or zIndex 99 if dom element isn't set - var zIndex = 99; - if (this.domElement.style.zIndex) { - zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; - } - - if (typeof(appendElem) == 'string') { - appendElem = ZeroClipboard.$(appendElem); - } else if (typeof(appendElem) == 'undefined') { - appendElem = document.getElementsByTagName('body')[0]; - } - - // find X/Y position of domElement - var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); - - // create floating DIV above element - this.div = document.createElement('div'); - this.div.className = "zclip"; - this.div.id = "zclip-" + this.movieId; - $(this.domElement).data('zclipId', 'zclip-' + this.movieId); - var style = this.div.style; - style.position = 'absolute'; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - style.width = '' + box.width + 'px'; - style.height = '' + box.height + 'px'; - style.zIndex = zIndex; - - if (typeof(stylesToAdd) == 'object') { - for (addedStyle in stylesToAdd) { - style[addedStyle] = stylesToAdd[addedStyle]; - } - } - - // style.backgroundColor = '#f00'; // debug - appendElem.appendChild(this.div); - - this.div.innerHTML = this.getHTML(box.width, box.height); - }, - - getHTML: function (width, height) { - // return HTML for movie - var html = ''; - var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; - - if (navigator.userAgent.match(/MSIE/)) { - // IE gets an OBJECT tag - var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; - html += ''; - } else { - // all other browsers get an EMBED tag - html += ''; - } - return html; - }, - - hide: function () { - // temporarily hide floater offscreen - if (this.div) { - this.div.style.left = '-2000px'; - } - }, - - show: function () { - // show ourselves after a call to hide() - this.reposition(); - }, - - destroy: function () { - // destroy control and floater - if (this.domElement && this.div) { - this.hide(); - this.div.innerHTML = ''; - - var body = document.getElementsByTagName('body')[0]; - try { - body.removeChild(this.div); - } catch (e) {; - } - - this.domElement = null; - this.div = null; - } - }, - - reposition: function (elem) { - // reposition our floating div, optionally to new container - // warning: container CANNOT change size, only position - if (elem) { - this.domElement = ZeroClipboard.$(elem); - if (!this.domElement) this.hide(); - } - - if (this.domElement && this.div) { - var box = ZeroClipboard.getDOMObjectPosition(this.domElement); - var style = this.div.style; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - } - }, - - setText: function (newText) { - // set text to be copied to clipboard - this.clipText = newText; - if (this.ready) { - this.movie.setText(newText); - } - }, - - addEventListener: function (eventName, func) { - // add user event listener for event - // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - if (!this.handlers[eventName]) { - this.handlers[eventName] = []; - } - this.handlers[eventName].push(func); - }, - - setHandCursor: function (enabled) { - // enable hand cursor (true), or default arrow cursor (false) - this.handCursorEnabled = enabled; - if (this.ready) { - this.movie.setHandCursor(enabled); - } - }, - - setCSSEffects: function (enabled) { - // enable or disable CSS effects on DOM container - this.cssEffects = !! enabled; - }, - - receiveEvent: function (eventName, args) { - // receive event from flash - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - - // special behavior for certain events - switch (eventName) { - case 'load': - // movie claims it is ready, but in IE this isn't always the case... - // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function - this.movie = document.getElementById(this.movieId); - if (!this.movie) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 1); - return; - } - - // firefox on pc needs a "kick" in order to set these in certain cases - if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 100); - this.ready = true; - return; - } - - this.ready = true; - try { - this.movie.setText(this.clipText); - } catch (e) {} - try { - this.movie.setHandCursor(this.handCursorEnabled); - } catch (e) {} - break; - - case 'mouseover': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('hover'); - if (this.recoverActive) { - this.domElement.addClass('active'); - } - - - } - - - break; - - case 'mouseout': - if (this.domElement && this.cssEffects) { - this.recoverActive = false; - if (this.domElement.hasClass('active')) { - this.domElement.removeClass('active'); - this.recoverActive = true; - } - this.domElement.removeClass('hover'); - - } - break; - - case 'mousedown': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('active'); - } - break; - - case 'mouseup': - if (this.domElement && this.cssEffects) { - this.domElement.removeClass('active'); - this.recoverActive = false; - } - break; - } // switch eventName - if (this.handlers[eventName]) { - for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { - var func = this.handlers[eventName][idx]; - - if (typeof(func) == 'function') { - // actual function reference - func(this, args); - } else if ((typeof(func) == 'object') && (func.length == 2)) { - // PHP style object + method, i.e. [myObject, 'myMethod'] - func[0][func[1]](this, args); - } else if (typeof(func) == 'string') { - // name of function - window[func](this, args); - } - } // foreach event handler defined - } // user defined handler for event - } - -}; - -/** - * 复制 - * Created by GUY on 2016/2/16. - * @class BI.ZeroClip - * @extends BI.BasicButton - */ -BI.ZeroClip = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.ZeroClip.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-zero-clip", - copy: BI.emptyFn, - beforeCopy: BI.emptyFn, - afterCopy: BI.emptyFn - }) - }, - - _init: function () { - BI.ZeroClip.superclass._init.apply(this, arguments); - }, - - mounted: function () { - var self = this, o = this.options; - this.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); - } -}); - -BI.shortcut("bi.zero_clip", BI.ZeroClip); \ No newline at end of file +BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger); \ No newline at end of file diff --git a/demo/js/case/demo.zclip.js b/demo/js/case/demo.zclip.js index 64b6af0361..17ea3cfecf 100644 --- a/demo/js/case/demo.zclip.js +++ b/demo/js/case/demo.zclip.js @@ -10,12 +10,12 @@ Demo.Func = BI.inherit(BI.Widget, { height: 30, value: "这是复制的内容" }); - var zclip = BI.createWidget({ - type: 'bi.zero_clip', + var clipboard = BI.createWidget({ + type: 'bi.clipboard', width: 100, height: 100, cls: 'layout-bg1', - copy: function () { + text: function () { return editor.getValue(); }, @@ -32,11 +32,11 @@ Demo.Func = BI.inherit(BI.Widget, { left: 100, top: 50, }, { - el: zclip, + el: clipboard, left: 100, top: 100 }] }) } }); -BI.shortcut("demo.zclip", Demo.Func); \ No newline at end of file +BI.shortcut("demo.clipboard", Demo.Func); \ No newline at end of file diff --git a/demo/js/config/case.js b/demo/js/config/case.js index be8bedf97d..959d69ff19 100644 --- a/demo/js/config/case.js +++ b/demo/js/config/case.js @@ -80,8 +80,8 @@ Demo.CASE_CONFIG = [{ value: "demo.calendar" }, { pId: 3, - text: "bi.zclip", - value: "demo.zclip" + text: "bi.clipboard", + value: "demo.clipboard" }, { pId: 3, text: "bi.complex_canvas", diff --git a/docs/case.js b/docs/case.js index f9b5bc7f15..7212e6106a 100644 --- a/docs/case.js +++ b/docs/case.js @@ -2222,7 +2222,820 @@ BI.TreeNodeCheckbox = BI.inherit(BI.IconButton, { } } }); -BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/** +BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/*! + * clipboard.js v1.6.1 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; + + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2.default)(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2.default)(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); + + return ClipboardAction; + }(); + + module.exports = ClipboardAction; + }); + +},{"select":5}],8:[function(require,module,exports){ + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; + + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + + var _goodListener2 = _interopRequireDefault(_goodListener); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); + + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); + + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } + + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ + + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2.default({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; + + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; + } + }]); + + return Clipboard; + }(_tinyEmitter2.default); + + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; + } + + return element.getAttribute(attribute); + } + + module.exports = Clipboard; + }); + +},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) +});/** + * 复制 + * Created by GUY on 2016/2/16. + * @class BI.ClipBoard + * @extends BI.BasicButton + */ +BI.ClipBoard = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-clipboard", + text: "", + afterCopy: BI.emptyFn + }) + }, + + _init: function () { + BI.ClipBoard.superclass._init.apply(this, arguments); + }, + + mounted: function () { + var self = this, o = this.options; + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.text) ? o.text() : o.text; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + }, + + destroyed: function () { + this.clipboard.destroy(); + } +}); + +BI.shortcut("bi.clipboard", BI.ClipBoard);/** * 自定义选色 * * Created by GUY on 2015/11/17. @@ -11233,530 +12046,4 @@ BI.SmallTextTrigger = BI.inherit(BI.Trigger, { this.text.setText(text); } }); -BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger);/* - * zClip :: jQuery ZeroClipboard v1.1.1 - * http://steamdev.com/zclip - * - * Copyright 2011, SteamDev - * Released under the MIT license. - * http://www.opensource.org/licenses/mit-license.php - * - * Date: Wed Jun 01, 2011 - */ - - -(function ($) { - - $.fn.zclip = function (params) { - - if (typeof params == "object" && !params.length) { - - var settings = $.extend({ - - path: 'ZeroClipboard.swf', - copy: null, - beforeCopy: null, - afterCopy: null, - clickAfter: true, - setHandCursor: true, - setCSSEffects: true - - }, params); - - - return this.each(function () { - - var o = $(this); - - if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { - - ZeroClipboard.setMoviePath(settings.path); - var clip = new ZeroClipboard.Client(); - - if($.isFunction(settings.copy)){ - o.bind('zClip_copy',settings.copy); - } - if($.isFunction(settings.beforeCopy)){ - o.bind('zClip_beforeCopy',settings.beforeCopy); - } - if($.isFunction(settings.afterCopy)){ - o.bind('zClip_afterCopy',settings.afterCopy); - } - - clip.setHandCursor(settings.setHandCursor); - clip.setCSSEffects(settings.setCSSEffects); - clip.addEventListener('mouseOver', function (client) { - o.trigger('mouseenter'); - }); - clip.addEventListener('mouseOut', function (client) { - o.trigger('mouseleave'); - }); - clip.addEventListener('mouseDown', function (client) { - - o.trigger('mousedown'); - - if(!$.isFunction(settings.copy)){ - clip.setText(settings.copy); - } else { - clip.setText(o.triggerHandler('zClip_copy')); - } - - if ($.isFunction(settings.beforeCopy)) { - o.trigger('zClip_beforeCopy'); - } - - }); - - clip.addEventListener('complete', function (client, text) { - - if ($.isFunction(settings.afterCopy)) { - - o.trigger('zClip_afterCopy'); - - } else { - if (text.length > 500) { - text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; - } - - o.removeClass('hover'); - alert("Copied text to clipboard:\n\n " + text); - } - - if (settings.clickAfter) { - o.trigger('click'); - } - - }); - - - clip.glue(o[0], o.parent()[0]); - - $(window).bind('load resize',function(){clip.reposition();}); - - - } - - }); - - } else if (typeof params == "string") { - - return this.each(function () { - - var o = $(this); - - params = params.toLowerCase(); - var zclipId = o.data('zclipId'); - var clipElm = $('#' + zclipId + '.zclip'); - - if (params == "remove") { - - clipElm.remove(); - o.removeClass('active hover'); - - } else if (params == "hide") { - - clipElm.hide(); - o.removeClass('active hover'); - - } else if (params == "show") { - - clipElm.show(); - - } - - }); - - } - - } - - - -})(jQuery); - - - - - - - -// ZeroClipboard -// Simple Set Clipboard System -// Author: Joseph Huckaby -var ZeroClipboard = { - - version: "1.0.7", - clients: {}, - // registered upload clients on page, indexed by id - moviePath: 'ZeroClipboard.swf', - // URL to movie - nextId: 1, - // ID of next movie - $: function (thingy) { - // simple DOM lookup utility function - if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); - if (!thingy.addClass) { - // extend element with a few useful methods - thingy.hide = function () { - this.style.display = 'none'; - }; - thingy.show = function () { - this.style.display = ''; - }; - thingy.addClass = function (name) { - this.removeClass(name); - this.className += ' ' + name; - }; - thingy.removeClass = function (name) { - var classes = this.className.split(/\s+/); - var idx = -1; - for (var k = 0; k < classes.length; k++) { - if (classes[k] == name) { - idx = k; - k = classes.length; - } - } - if (idx > -1) { - classes.splice(idx, 1); - this.className = classes.join(' '); - } - return this; - }; - thingy.hasClass = function (name) { - return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); - }; - } - return thingy; - }, - - setMoviePath: function (path) { - // set path to ZeroClipboard.swf - this.moviePath = path; - }, - - dispatch: function (id, eventName, args) { - // receive event from flash movie, send to client - var client = this.clients[id]; - if (client) { - client.receiveEvent(eventName, args); - } - }, - - register: function (id, client) { - // register new client to receive events - this.clients[id] = client; - }, - - getDOMObjectPosition: function (obj, stopObj) { - // get absolute coordinates for dom element - var info = { - left: 0, - top: 0, - width: obj.width ? obj.width : obj.offsetWidth, - height: obj.height ? obj.height : obj.offsetHeight - }; - - if (obj && (obj != stopObj)) { - info.left += obj.offsetLeft; - info.top += obj.offsetTop; - } - - return info; - }, - - Client: function (elem) { - // constructor for new simple upload client - this.handlers = {}; - - // unique ID - this.id = ZeroClipboard.nextId++; - this.movieId = 'ZeroClipboardMovie_' + this.id; - - // register client with singleton to receive flash events - ZeroClipboard.register(this.id, this); - - // create movie - if (elem) this.glue(elem); - } -}; - -ZeroClipboard.Client.prototype = { - - id: 0, - // unique ID for us - ready: false, - // whether movie is ready to receive events or not - movie: null, - // reference to movie object - clipText: '', - // text to copy to clipboard - handCursorEnabled: true, - // whether to show hand cursor, or default pointer cursor - cssEffects: true, - // enable CSS mouse effects on dom container - handlers: null, - // user event handlers - glue: function (elem, appendElem, stylesToAdd) { - // glue to DOM element - // elem can be ID or actual DOM element object - this.domElement = ZeroClipboard.$(elem); - - // float just above object, or zIndex 99 if dom element isn't set - var zIndex = 99; - if (this.domElement.style.zIndex) { - zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; - } - - if (typeof(appendElem) == 'string') { - appendElem = ZeroClipboard.$(appendElem); - } else if (typeof(appendElem) == 'undefined') { - appendElem = document.getElementsByTagName('body')[0]; - } - - // find X/Y position of domElement - var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); - - // create floating DIV above element - this.div = document.createElement('div'); - this.div.className = "zclip"; - this.div.id = "zclip-" + this.movieId; - $(this.domElement).data('zclipId', 'zclip-' + this.movieId); - var style = this.div.style; - style.position = 'absolute'; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - style.width = '' + box.width + 'px'; - style.height = '' + box.height + 'px'; - style.zIndex = zIndex; - - if (typeof(stylesToAdd) == 'object') { - for (addedStyle in stylesToAdd) { - style[addedStyle] = stylesToAdd[addedStyle]; - } - } - - // style.backgroundColor = '#f00'; // debug - appendElem.appendChild(this.div); - - this.div.innerHTML = this.getHTML(box.width, box.height); - }, - - getHTML: function (width, height) { - // return HTML for movie - var html = ''; - var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; - - if (navigator.userAgent.match(/MSIE/)) { - // IE gets an OBJECT tag - var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; - html += ''; - } else { - // all other browsers get an EMBED tag - html += ''; - } - return html; - }, - - hide: function () { - // temporarily hide floater offscreen - if (this.div) { - this.div.style.left = '-2000px'; - } - }, - - show: function () { - // show ourselves after a call to hide() - this.reposition(); - }, - - destroy: function () { - // destroy control and floater - if (this.domElement && this.div) { - this.hide(); - this.div.innerHTML = ''; - - var body = document.getElementsByTagName('body')[0]; - try { - body.removeChild(this.div); - } catch (e) {; - } - - this.domElement = null; - this.div = null; - } - }, - - reposition: function (elem) { - // reposition our floating div, optionally to new container - // warning: container CANNOT change size, only position - if (elem) { - this.domElement = ZeroClipboard.$(elem); - if (!this.domElement) this.hide(); - } - - if (this.domElement && this.div) { - var box = ZeroClipboard.getDOMObjectPosition(this.domElement); - var style = this.div.style; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - } - }, - - setText: function (newText) { - // set text to be copied to clipboard - this.clipText = newText; - if (this.ready) { - this.movie.setText(newText); - } - }, - - addEventListener: function (eventName, func) { - // add user event listener for event - // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - if (!this.handlers[eventName]) { - this.handlers[eventName] = []; - } - this.handlers[eventName].push(func); - }, - - setHandCursor: function (enabled) { - // enable hand cursor (true), or default arrow cursor (false) - this.handCursorEnabled = enabled; - if (this.ready) { - this.movie.setHandCursor(enabled); - } - }, - - setCSSEffects: function (enabled) { - // enable or disable CSS effects on DOM container - this.cssEffects = !! enabled; - }, - - receiveEvent: function (eventName, args) { - // receive event from flash - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - - // special behavior for certain events - switch (eventName) { - case 'load': - // movie claims it is ready, but in IE this isn't always the case... - // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function - this.movie = document.getElementById(this.movieId); - if (!this.movie) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 1); - return; - } - - // firefox on pc needs a "kick" in order to set these in certain cases - if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 100); - this.ready = true; - return; - } - - this.ready = true; - try { - this.movie.setText(this.clipText); - } catch (e) {} - try { - this.movie.setHandCursor(this.handCursorEnabled); - } catch (e) {} - break; - - case 'mouseover': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('hover'); - if (this.recoverActive) { - this.domElement.addClass('active'); - } - - - } - - - break; - - case 'mouseout': - if (this.domElement && this.cssEffects) { - this.recoverActive = false; - if (this.domElement.hasClass('active')) { - this.domElement.removeClass('active'); - this.recoverActive = true; - } - this.domElement.removeClass('hover'); - - } - break; - - case 'mousedown': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('active'); - } - break; - - case 'mouseup': - if (this.domElement && this.cssEffects) { - this.domElement.removeClass('active'); - this.recoverActive = false; - } - break; - } // switch eventName - if (this.handlers[eventName]) { - for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { - var func = this.handlers[eventName][idx]; - - if (typeof(func) == 'function') { - // actual function reference - func(this, args); - } else if ((typeof(func) == 'object') && (func.length == 2)) { - // PHP style object + method, i.e. [myObject, 'myMethod'] - func[0][func[1]](this, args); - } else if (typeof(func) == 'string') { - // name of function - window[func](this, args); - } - } // foreach event handler defined - } // user defined handler for event - } - -}; - -/** - * 复制 - * Created by GUY on 2016/2/16. - * @class BI.ZeroClip - * @extends BI.BasicButton - */ -BI.ZeroClip = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.ZeroClip.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-zero-clip", - copy: BI.emptyFn, - beforeCopy: BI.emptyFn, - afterCopy: BI.emptyFn - }) - }, - - _init: function () { - BI.ZeroClip.superclass._init.apply(this, arguments); - }, - - mounted: function () { - var self = this, o = this.options; - this.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); - } -}); - -BI.shortcut("bi.zero_clip", BI.ZeroClip); \ No newline at end of file +BI.shortcut("bi.small_text_trigger", BI.SmallTextTrigger); \ No newline at end of file diff --git a/docs/demo.js b/docs/demo.js index 23accd576d..f0e3b5f22f 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -1799,12 +1799,12 @@ BI.shortcut("demo.complex_canvas", Demo.Func);Demo.Func = BI.inherit(BI.Widget, height: 30, value: "这是复制的内容" }); - var zclip = BI.createWidget({ - type: 'bi.zero_clip', + var clipboard = BI.createWidget({ + type: 'bi.clipboard', width: 100, height: 100, cls: 'layout-bg1', - copy: function () { + text: function () { return editor.getValue(); }, @@ -1821,14 +1821,14 @@ BI.shortcut("demo.complex_canvas", Demo.Func);Demo.Func = BI.inherit(BI.Widget, left: 100, top: 50, }, { - el: zclip, + el: clipboard, left: 100, top: 100 }] }) } }); -BI.shortcut("demo.zclip", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { +BI.shortcut("demo.clipboard", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { props: { baseCls: "demo-func" }, @@ -2888,8 +2888,8 @@ BI.shortcut("demo.value_chooser_pane", Demo.ValueChooserPane);Demo.BASE_CONFIG = value: "demo.calendar" }, { pId: 3, - text: "bi.zclip", - value: "demo.zclip" + text: "bi.clipboard", + value: "demo.clipboard" }, { pId: 3, text: "bi.complex_canvas", diff --git a/docs/resource/ZeroClipboard.swf b/docs/resource/ZeroClipboard.swf deleted file mode 100644 index 13bf8e396202964e0048333d878f4b949a2f5e6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1071 zcmV+~1kn3KS5pay1^@tfoPAa6Qrkup-d$aeB-A-xFjKf1te)pFM-&Q&_dOT zp~-XxqP4X~YJ}vGWC;KAD1C=MKwiO_PG6^Vbs@z~r#qgr-}!Xr?4IxJ9P1kT4dpSa zmlT9hja*+}e;Cbih*6`(JT|+I(1(#NIVSiTL~Dq=|Lb=d5tOYL`L;_#dyQQ%FAAmI zcth~a_gzLk@xphk!Y?fFYp&C2`ZTZ#X}INt9hY9ojZWZ1Om23g$oC2%i(XLAs&#|V z5ArS7X}yhomj%SJGT~|rnZj|zM|I&j59e1QKqGxQN5!(ijWrx1S)ZN!RwWBwC`$uYc z!)028S7F4?l?H2dd39HKImh$+mv#S~I-YjmQ;P-rUfUM~-;Xr+ldpAXK+hS!b|@Ro zUs)@fv!kf9RjpFXZ?d(Pe_q{bY*sgP{Ykaib==7Da_N!X$Z^AwK5e&BZ5R56j>T=;_5DD$nR8}GiWShym;5A&x*eM;)Us-}<67Eb+@9n>sdlhm z`(coON!$a6H-ML=9U8}t-8aV1yD!xY9v@|7-FWq*lEUMka&b=Hq$X{>72}4eNl_P+ zccPJWGtXb!r#GbVPIO$}sN%oME%Yf<`b@|2f6G5y#$}-l zAR|D=L6`ti0Wt|N4P*v{Ss-&j?gE(yvY_TMkQE@SK-Pd%f#~WwXExMLZXW@84CD#m zFMxar!IU~i}ZGSTvX;GX_!`A@yKkIbSu*e=l_b9m*BF@hOB8SS;p?XkU4 z+#Y{FagI+_hF#pQ*y^c#B7H9*TQ=n-IvJZOQ*KYMV&e{u!2((~XOiIAy*Zr0yBr$x zqA6D~T{u}ZWn+;Cn@jC`refSD34E}PZ{YGaxq%P2g&VlCEyl30qM2Z<#-M2CQxMno zG_4J8H7mc8(VenQzJ;=@j=BiTh*RubMeS$61ORcM^S6!u6l;=?s|@ py1A~K8@jovn~!u;;=k8uI$3rc`gC{*rT-s&a~N%N=5J58nk1s|4c7nw diff --git a/src/case/clipboard/clipboard.js b/src/case/clipboard/clipboard.js new file mode 100644 index 0000000000..5606dd98a4 --- /dev/null +++ b/src/case/clipboard/clipboard.js @@ -0,0 +1,778 @@ +/*! + * clipboard.js v1.6.1 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; + + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2.default)(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2.default)(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); + + return ClipboardAction; + }(); + + module.exports = ClipboardAction; + }); + +},{"select":5}],8:[function(require,module,exports){ + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; + + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + + var _goodListener2 = _interopRequireDefault(_goodListener); + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } + + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); + + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); + + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } + + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ + + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2.default({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; + + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; + } + }]); + + return Clipboard; + }(_tinyEmitter2.default); + + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; + } + + return element.getAttribute(attribute); + } + + module.exports = Clipboard; + }); + +},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) +}); \ No newline at end of file diff --git a/src/case/clipboard/index.js b/src/case/clipboard/index.js new file mode 100644 index 0000000000..634311b1e2 --- /dev/null +++ b/src/case/clipboard/index.js @@ -0,0 +1,37 @@ +/** + * 复制 + * Created by GUY on 2016/2/16. + * @class BI.ClipBoard + * @extends BI.BasicButton + */ +BI.ClipBoard = BI.inherit(BI.BasicButton, { + _defaultConfig: function () { + return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { + extraCls: "bi-clipboard", + text: "", + afterCopy: BI.emptyFn + }) + }, + + _init: function () { + BI.ClipBoard.superclass._init.apply(this, arguments); + }, + + mounted: function () { + var self = this, o = this.options; + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.text) ? o.text() : o.text; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + }, + + destroyed: function () { + this.clipboard.destroy(); + } +}); + +BI.shortcut("bi.clipboard", BI.ClipBoard); \ No newline at end of file diff --git a/src/case/zclip/jquery.zclip.js b/src/case/zclip/jquery.zclip.js deleted file mode 100644 index 24192451d3..0000000000 --- a/src/case/zclip/jquery.zclip.js +++ /dev/null @@ -1,495 +0,0 @@ -/* - * zClip :: jQuery ZeroClipboard v1.1.1 - * http://steamdev.com/zclip - * - * Copyright 2011, SteamDev - * Released under the MIT license. - * http://www.opensource.org/licenses/mit-license.php - * - * Date: Wed Jun 01, 2011 - */ - - -(function ($) { - - $.fn.zclip = function (params) { - - if (typeof params == "object" && !params.length) { - - var settings = $.extend({ - - path: 'ZeroClipboard.swf', - copy: null, - beforeCopy: null, - afterCopy: null, - clickAfter: true, - setHandCursor: true, - setCSSEffects: true - - }, params); - - - return this.each(function () { - - var o = $(this); - - if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { - - ZeroClipboard.setMoviePath(settings.path); - var clip = new ZeroClipboard.Client(); - - if($.isFunction(settings.copy)){ - o.bind('zClip_copy',settings.copy); - } - if($.isFunction(settings.beforeCopy)){ - o.bind('zClip_beforeCopy',settings.beforeCopy); - } - if($.isFunction(settings.afterCopy)){ - o.bind('zClip_afterCopy',settings.afterCopy); - } - - clip.setHandCursor(settings.setHandCursor); - clip.setCSSEffects(settings.setCSSEffects); - clip.addEventListener('mouseOver', function (client) { - o.trigger('mouseenter'); - }); - clip.addEventListener('mouseOut', function (client) { - o.trigger('mouseleave'); - }); - clip.addEventListener('mouseDown', function (client) { - - o.trigger('mousedown'); - - if(!$.isFunction(settings.copy)){ - clip.setText(settings.copy); - } else { - clip.setText(o.triggerHandler('zClip_copy')); - } - - if ($.isFunction(settings.beforeCopy)) { - o.trigger('zClip_beforeCopy'); - } - - }); - - clip.addEventListener('complete', function (client, text) { - - if ($.isFunction(settings.afterCopy)) { - - o.trigger('zClip_afterCopy'); - - } else { - if (text.length > 500) { - text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; - } - - o.removeClass('hover'); - alert("Copied text to clipboard:\n\n " + text); - } - - if (settings.clickAfter) { - o.trigger('click'); - } - - }); - - - clip.glue(o[0], o.parent()[0]); - - $(window).bind('load resize',function(){clip.reposition();}); - - - } - - }); - - } else if (typeof params == "string") { - - return this.each(function () { - - var o = $(this); - - params = params.toLowerCase(); - var zclipId = o.data('zclipId'); - var clipElm = $('#' + zclipId + '.zclip'); - - if (params == "remove") { - - clipElm.remove(); - o.removeClass('active hover'); - - } else if (params == "hide") { - - clipElm.hide(); - o.removeClass('active hover'); - - } else if (params == "show") { - - clipElm.show(); - - } - - }); - - } - - } - - - -})(jQuery); - - - - - - - -// ZeroClipboard -// Simple Set Clipboard System -// Author: Joseph Huckaby -var ZeroClipboard = { - - version: "1.0.7", - clients: {}, - // registered upload clients on page, indexed by id - moviePath: 'ZeroClipboard.swf', - // URL to movie - nextId: 1, - // ID of next movie - $: function (thingy) { - // simple DOM lookup utility function - if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); - if (!thingy.addClass) { - // extend element with a few useful methods - thingy.hide = function () { - this.style.display = 'none'; - }; - thingy.show = function () { - this.style.display = ''; - }; - thingy.addClass = function (name) { - this.removeClass(name); - this.className += ' ' + name; - }; - thingy.removeClass = function (name) { - var classes = this.className.split(/\s+/); - var idx = -1; - for (var k = 0; k < classes.length; k++) { - if (classes[k] == name) { - idx = k; - k = classes.length; - } - } - if (idx > -1) { - classes.splice(idx, 1); - this.className = classes.join(' '); - } - return this; - }; - thingy.hasClass = function (name) { - return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); - }; - } - return thingy; - }, - - setMoviePath: function (path) { - // set path to ZeroClipboard.swf - this.moviePath = path; - }, - - dispatch: function (id, eventName, args) { - // receive event from flash movie, send to client - var client = this.clients[id]; - if (client) { - client.receiveEvent(eventName, args); - } - }, - - register: function (id, client) { - // register new client to receive events - this.clients[id] = client; - }, - - getDOMObjectPosition: function (obj, stopObj) { - // get absolute coordinates for dom element - var info = { - left: 0, - top: 0, - width: obj.width ? obj.width : obj.offsetWidth, - height: obj.height ? obj.height : obj.offsetHeight - }; - - if (obj && (obj != stopObj)) { - info.left += obj.offsetLeft; - info.top += obj.offsetTop; - } - - return info; - }, - - Client: function (elem) { - // constructor for new simple upload client - this.handlers = {}; - - // unique ID - this.id = ZeroClipboard.nextId++; - this.movieId = 'ZeroClipboardMovie_' + this.id; - - // register client with singleton to receive flash events - ZeroClipboard.register(this.id, this); - - // create movie - if (elem) this.glue(elem); - } -}; - -ZeroClipboard.Client.prototype = { - - id: 0, - // unique ID for us - ready: false, - // whether movie is ready to receive events or not - movie: null, - // reference to movie object - clipText: '', - // text to copy to clipboard - handCursorEnabled: true, - // whether to show hand cursor, or default pointer cursor - cssEffects: true, - // enable CSS mouse effects on dom container - handlers: null, - // user event handlers - glue: function (elem, appendElem, stylesToAdd) { - // glue to DOM element - // elem can be ID or actual DOM element object - this.domElement = ZeroClipboard.$(elem); - - // float just above object, or zIndex 99 if dom element isn't set - var zIndex = 99; - if (this.domElement.style.zIndex) { - zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; - } - - if (typeof(appendElem) == 'string') { - appendElem = ZeroClipboard.$(appendElem); - } else if (typeof(appendElem) == 'undefined') { - appendElem = document.getElementsByTagName('body')[0]; - } - - // find X/Y position of domElement - var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); - - // create floating DIV above element - this.div = document.createElement('div'); - this.div.className = "zclip"; - this.div.id = "zclip-" + this.movieId; - $(this.domElement).data('zclipId', 'zclip-' + this.movieId); - var style = this.div.style; - style.position = 'absolute'; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - style.width = '' + box.width + 'px'; - style.height = '' + box.height + 'px'; - style.zIndex = zIndex; - - if (typeof(stylesToAdd) == 'object') { - for (addedStyle in stylesToAdd) { - style[addedStyle] = stylesToAdd[addedStyle]; - } - } - - // style.backgroundColor = '#f00'; // debug - appendElem.appendChild(this.div); - - this.div.innerHTML = this.getHTML(box.width, box.height); - }, - - getHTML: function (width, height) { - // return HTML for movie - var html = ''; - var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; - - if (navigator.userAgent.match(/MSIE/)) { - // IE gets an OBJECT tag - var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; - html += ''; - } else { - // all other browsers get an EMBED tag - html += ''; - } - return html; - }, - - hide: function () { - // temporarily hide floater offscreen - if (this.div) { - this.div.style.left = '-2000px'; - } - }, - - show: function () { - // show ourselves after a call to hide() - this.reposition(); - }, - - destroy: function () { - // destroy control and floater - if (this.domElement && this.div) { - this.hide(); - this.div.innerHTML = ''; - - var body = document.getElementsByTagName('body')[0]; - try { - body.removeChild(this.div); - } catch (e) {; - } - - this.domElement = null; - this.div = null; - } - }, - - reposition: function (elem) { - // reposition our floating div, optionally to new container - // warning: container CANNOT change size, only position - if (elem) { - this.domElement = ZeroClipboard.$(elem); - if (!this.domElement) this.hide(); - } - - if (this.domElement && this.div) { - var box = ZeroClipboard.getDOMObjectPosition(this.domElement); - var style = this.div.style; - style.left = '' + box.left + 'px'; - style.top = '' + box.top + 'px'; - } - }, - - setText: function (newText) { - // set text to be copied to clipboard - this.clipText = newText; - if (this.ready) { - this.movie.setText(newText); - } - }, - - addEventListener: function (eventName, func) { - // add user event listener for event - // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - if (!this.handlers[eventName]) { - this.handlers[eventName] = []; - } - this.handlers[eventName].push(func); - }, - - setHandCursor: function (enabled) { - // enable hand cursor (true), or default arrow cursor (false) - this.handCursorEnabled = enabled; - if (this.ready) { - this.movie.setHandCursor(enabled); - } - }, - - setCSSEffects: function (enabled) { - // enable or disable CSS effects on DOM container - this.cssEffects = !! enabled; - }, - - receiveEvent: function (eventName, args) { - // receive event from flash - eventName = eventName.toString().toLowerCase().replace(/^on/, ''); - - // special behavior for certain events - switch (eventName) { - case 'load': - // movie claims it is ready, but in IE this isn't always the case... - // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function - this.movie = document.getElementById(this.movieId); - if (!this.movie) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 1); - return; - } - - // firefox on pc needs a "kick" in order to set these in certain cases - if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { - var self = this; - setTimeout(function () { - self.receiveEvent('load', null); - }, 100); - this.ready = true; - return; - } - - this.ready = true; - try { - this.movie.setText(this.clipText); - } catch (e) {} - try { - this.movie.setHandCursor(this.handCursorEnabled); - } catch (e) {} - break; - - case 'mouseover': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('hover'); - if (this.recoverActive) { - this.domElement.addClass('active'); - } - - - } - - - break; - - case 'mouseout': - if (this.domElement && this.cssEffects) { - this.recoverActive = false; - if (this.domElement.hasClass('active')) { - this.domElement.removeClass('active'); - this.recoverActive = true; - } - this.domElement.removeClass('hover'); - - } - break; - - case 'mousedown': - if (this.domElement && this.cssEffects) { - this.domElement.addClass('active'); - } - break; - - case 'mouseup': - if (this.domElement && this.cssEffects) { - this.domElement.removeClass('active'); - this.recoverActive = false; - } - break; - } // switch eventName - if (this.handlers[eventName]) { - for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { - var func = this.handlers[eventName][idx]; - - if (typeof(func) == 'function') { - // actual function reference - func(this, args); - } else if ((typeof(func) == 'object') && (func.length == 2)) { - // PHP style object + method, i.e. [myObject, 'myMethod'] - func[0][func[1]](this, args); - } else if (typeof(func) == 'string') { - // name of function - window[func](this, args); - } - } // foreach event handler defined - } // user defined handler for event - } - -}; - diff --git a/src/case/zclip/zclip.js b/src/case/zclip/zclip.js deleted file mode 100644 index 266cc68a6f..0000000000 --- a/src/case/zclip/zclip.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * 复制 - * Created by GUY on 2016/2/16. - * @class BI.ZeroClip - * @extends BI.BasicButton - */ -BI.ZeroClip = BI.inherit(BI.BasicButton, { - _defaultConfig: function () { - return BI.extend(BI.ZeroClip.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-zero-clip", - copy: BI.emptyFn, - beforeCopy: BI.emptyFn, - afterCopy: BI.emptyFn - }) - }, - - _init: function () { - BI.ZeroClip.superclass._init.apply(this, arguments); - }, - - mounted: function () { - var self = this, o = this.options; - this.element.zclip({ - path: BI.resourceURL + "/ZeroClipboard.swf", - copy: o.copy, - beforeCopy: o.beforeCopy, - afterCopy: o.afterCopy - }); - } -}); - -BI.shortcut("bi.zero_clip", BI.ZeroClip); \ No newline at end of file From 9a94cbcb5654bb9d39a5282596ed0daa681a0c2b Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 24 May 2017 01:34:47 +0800 Subject: [PATCH 26/27] add --- .../case/{demo.zclip.js => demo.clipboard.js} | 0 docs/demo.js | 82 +++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) rename demo/js/case/{demo.zclip.js => demo.clipboard.js} (100%) diff --git a/demo/js/case/demo.zclip.js b/demo/js/case/demo.clipboard.js similarity index 100% rename from demo/js/case/demo.zclip.js rename to demo/js/case/demo.clipboard.js diff --git a/docs/demo.js b/docs/demo.js index f0e3b5f22f..5f9326ce7a 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -1738,6 +1738,47 @@ BI.shortcut("demo.calendar", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { baseCls: "demo-func" }, + render: function () { + var editor = BI.createWidget({ + type: "bi.text_editor", + width: 200, + height: 30, + value: "这是复制的内容" + }); + var clipboard = BI.createWidget({ + type: 'bi.clipboard', + width: 100, + height: 100, + cls: 'layout-bg1', + text: function () { + return editor.getValue(); + }, + + afterCopy: function () { + BI.Msg.toast(editor.getValue()); + } + }); + + BI.createWidget({ + type: "bi.absolute", + element: this, + items: [{ + el: editor, + left: 100, + top: 50, + }, { + el: clipboard, + left: 100, + top: 100 + }] + }) + } +}); +BI.shortcut("demo.clipboard", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, + render: function () { return { type: "bi.absolute", @@ -1792,47 +1833,6 @@ BI.shortcut("demo.complex_canvas", Demo.Func);Demo.Func = BI.inherit(BI.Widget, baseCls: "demo-func" }, - render: function () { - var editor = BI.createWidget({ - type: "bi.text_editor", - width: 200, - height: 30, - value: "这是复制的内容" - }); - var clipboard = BI.createWidget({ - type: 'bi.clipboard', - width: 100, - height: 100, - cls: 'layout-bg1', - text: function () { - return editor.getValue(); - }, - - afterCopy: function () { - BI.Msg.toast(editor.getValue()); - } - }); - - BI.createWidget({ - type: "bi.absolute", - element: this, - items: [{ - el: editor, - left: 100, - top: 50, - }, { - el: clipboard, - left: 100, - top: 100 - }] - }) - } -}); -BI.shortcut("demo.clipboard", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { var relation = BI.createWidget({ type: "bi.branch_relation", From 007613a6430f1059d46b5d1fa01dc0d95a920985 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 24 May 2017 02:06:43 +0800 Subject: [PATCH 27/27] =?UTF-8?q?=E5=A4=8D=E5=88=B6=E5=88=B0=E7=B2=98?= =?UTF-8?q?=E8=B4=B4=E6=9D=BFIE8=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bi/case.js | 1852 ++++++++++++++++++++----------- demo/js/case/demo.clipboard.js | 2 +- docs/case.js | 1852 ++++++++++++++++++++----------- docs/demo.js | 2 +- docs/resource/ZeroClipboard.swf | Bin 0 -> 1071 bytes src/case/clipboard/clipboard.js | 1827 +++++++++++++++++++----------- src/case/clipboard/index.js | 29 +- 7 files changed, 3607 insertions(+), 1957 deletions(-) create mode 100644 docs/resource/ZeroClipboard.swf diff --git a/bi/case.js b/bi/case.js index 7212e6106a..b70256eb61 100644 --- a/bi/case.js +++ b/bi/case.js @@ -2228,778 +2228,1319 @@ BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/*! * * Licensed MIT © Zeno Rocha */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; - var _select2 = _interopRequireDefault(_select); + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2["default"])(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2["default"])(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; + return ClipboardAction; + }(); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } + module.exports = ClipboardAction; + }); - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } + }, {"select": 5}], 8: [function (require, module, exports) { + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); - var ClipboardAction = function () { - /** - * @param {Object} options - */ - function ClipboardAction(options) { - _classCallCheck(this, ClipboardAction); + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); - this.resolveOptions(options); - this.initSelection(); - } + var _goodListener2 = _interopRequireDefault(_goodListener); - /** - * Defines base properties passed from constructor. - * @param {Object} options - */ + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; + } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - _createClass(ClipboardAction, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - this.action = options.action; - this.emitter = options.emitter; - this.target = options.target; - this.text = options.text; - this.trigger = options.trigger; + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); - this.selectedText = ''; - } - }, { - key: 'initSelection', - value: function initSelection() { - if (this.text) { - this.selectFake(); - } else if (this.target) { - this.selectTarget(); - } - } - }, { - key: 'selectFake', - value: function selectFake() { - var _this = this; + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } - var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } - this.removeFake(); + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } - this.fakeHandlerCallback = function () { - return _this.removeFake(); - }; - this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; - - this.fakeElem = document.createElement('textarea'); - // Prevent zooming on iOS - this.fakeElem.style.fontSize = '12pt'; - // Reset box model - this.fakeElem.style.border = '0'; - this.fakeElem.style.padding = '0'; - this.fakeElem.style.margin = '0'; - // Move element out of screen horizontally - this.fakeElem.style.position = 'absolute'; - this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; - // Move element to the same position vertically - var yPosition = window.pageYOffset || document.documentElement.scrollTop; - this.fakeElem.style.top = yPosition + 'px'; - - this.fakeElem.setAttribute('readonly', ''); - this.fakeElem.value = this.text; - - document.body.appendChild(this.fakeElem); - - this.selectedText = (0, _select2.default)(this.fakeElem); - this.copyText(); - } - }, { - key: 'removeFake', - value: function removeFake() { - if (this.fakeHandler) { - document.body.removeEventListener('click', this.fakeHandlerCallback); - this.fakeHandler = null; - this.fakeHandlerCallback = null; + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - if (this.fakeElem) { - document.body.removeChild(this.fakeElem); - this.fakeElem = null; - } - } - }, { - key: 'selectTarget', - value: function selectTarget() { - this.selectedText = (0, _select2.default)(this.target); - this.copyText(); - } - }, { - key: 'copyText', - value: function copyText() { - var succeeded = void 0; + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); - try { - succeeded = document.execCommand(this.action); - } catch (err) { - succeeded = false; - } + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); - this.handleResult(succeeded); - } - }, { - key: 'handleResult', - value: function handleResult(succeeded) { - this.emitter.emit(succeeded ? 'success' : 'error', { - action: this.action, - text: this.selectedText, - trigger: this.trigger, - clearSelection: this.clearSelection.bind(this) - }); - } - }, { - key: 'clearSelection', - value: function clearSelection() { - if (this.target) { - this.target.blur(); - } + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); - window.getSelection().removeAllRanges(); - } - }, { - key: 'destroy', - value: function destroy() { - this.removeFake(); - } - }, { - key: 'action', - set: function set() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } - this._action = action; + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ - if (this._action !== 'copy' && this._action !== 'cut') { - throw new Error('Invalid "action" value, use either "copy" or "cut"'); - } - }, - get: function get() { - return this._action; - } - }, { - key: 'target', - set: function set(target) { - if (target !== undefined) { - if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { - if (this.action === 'copy' && target.hasAttribute('disabled')) { - throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2["default"])(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2["default"]({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; - if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { - throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; } + }]); - this._target = target; - } else { - throw new Error('Invalid "target" value, use a valid Element'); + return Clipboard; + }(_tinyEmitter2["default"]); + + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; } + + return element.getAttribute(attribute); } - }, - get: function get() { - return this._target; - } - }]); - return ClipboardAction; - }(); + module.exports = Clipboard; + }); - module.exports = ClipboardAction; + }, {"./clipboard-action": 7, "good-listener": 4, "tiny-emitter": 6}] + }, {}, [8])(8) }); +} catch (e) { + /* + * zClip :: jQuery ZeroClipboard v1.1.1 + * http://steamdev.com/zclip + * + * Copyright 2011, SteamDev + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Date: Wed Jun 01, 2011 + */ -},{"select":5}],8:[function(require,module,exports){ - (function (global, factory) { - if (typeof define === "function" && define.amd) { - define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); - } else if (typeof exports !== "undefined") { - factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); - } else { - var mod = { - exports: {} - }; - factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); - global.clipboard = mod.exports; - } - })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { - 'use strict'; - var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + (function ($) { - var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + $.fn.zclip = function (params) { - var _goodListener2 = _interopRequireDefault(_goodListener); + if (typeof params == "object" && !params.length) { - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + var settings = $.extend({ + + path: 'ZeroClipboard.swf', + copy: null, + beforeCopy: null, + afterCopy: null, + clickAfter: true, + setHandCursor: true, + setCSSEffects: true + + }, params); + + + return this.each(function () { + + var o = $(this); + + if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { + + ZeroClipboard.setMoviePath(settings.path); + var clip = new ZeroClipboard.Client(); + + if ($.isFunction(settings.copy)) { + o.bind('zClip_copy', settings.copy); + } + if ($.isFunction(settings.beforeCopy)) { + o.bind('zClip_beforeCopy', settings.beforeCopy); + } + if ($.isFunction(settings.afterCopy)) { + o.bind('zClip_afterCopy', settings.afterCopy); + } + + clip.setHandCursor(settings.setHandCursor); + clip.setCSSEffects(settings.setCSSEffects); + clip.addEventListener('mouseOver', function (client) { + o.trigger('mouseenter'); + }); + clip.addEventListener('mouseOut', function (client) { + o.trigger('mouseleave'); + }); + clip.addEventListener('mouseDown', function (client) { + + o.trigger('mousedown'); + + if (!$.isFunction(settings.copy)) { + clip.setText(settings.copy); + } else { + clip.setText(o.triggerHandler('zClip_copy')); + } + + if ($.isFunction(settings.beforeCopy)) { + o.trigger('zClip_beforeCopy'); + } + + }); + + clip.addEventListener('complete', function (client, text) { + + if ($.isFunction(settings.afterCopy)) { + + o.trigger('zClip_afterCopy'); + + } else { + if (text.length > 500) { + text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; + } + + o.removeClass('hover'); + alert("Copied text to clipboard:\n\n " + text); + } + + if (settings.clickAfter) { + o.trigger('click'); + } + + }); + + + clip.glue(o[0], o.parent()[0]); + + $(window).bind('load resize', function () { + clip.reposition(); + }); + + + } + + }); + + } else if (typeof params == "string") { + + return this.each(function () { + + var o = $(this); + + params = params.toLowerCase(); + var zclipId = o.data('zclipId'); + var clipElm = $('#' + zclipId + '.zclip'); + + if (params == "remove") { + + clipElm.remove(); + o.removeClass('active hover'); + + } else if (params == "hide") { + + clipElm.hide(); + o.removeClass('active hover'); + + } else if (params == "show") { + + clipElm.show(); + + } + + }); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); } + } - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } + + })(jQuery); + + +// ZeroClipboard +// Simple Set Clipboard System +// Author: Joseph Huckaby + var ZeroClipboard = { + + version: "1.0.7", + clients: {}, + // registered upload clients on page, indexed by id + moviePath: 'ZeroClipboard.swf', + // URL to movie + nextId: 1, + // ID of next movie + $: function (thingy) { + // simple DOM lookup utility function + if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); + if (!thingy.addClass) { + // extend element with a few useful methods + thingy.hide = function () { + this.style.display = 'none'; + }; + thingy.show = function () { + this.style.display = ''; + }; + thingy.addClass = function (name) { + this.removeClass(name); + this.className += ' ' + name; + }; + thingy.removeClass = function (name) { + var classes = this.className.split(/\s+/); + var idx = -1; + for (var k = 0; k < classes.length; k++) { + if (classes[k] == name) { + idx = k; + k = classes.length; + } + } + if (idx > -1) { + classes.splice(idx, 1); + this.className = classes.join(' '); + } + return this; + }; + thingy.hasClass = function (name) { + return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); + }; } + return thingy; + }, + + setMoviePath: function (path) { + // set path to ZeroClipboard.swf + this.moviePath = path; + }, - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; + dispatch: function (id, eventName, args) { + // receive event from flash movie, send to client + var client = this.clients[id]; + if (client) { + client.receiveEvent(eventName, args); + } + }, + + register: function (id, client) { + // register new client to receive events + this.clients[id] = client; + }, + + getDOMObjectPosition: function (obj, stopObj) { + // get absolute coordinates for dom element + var info = { + left: 0, + top: 0, + width: obj.width ? obj.width : obj.offsetWidth, + height: obj.height ? obj.height : obj.offsetHeight }; - }(); - function _possibleConstructorReturn(self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + if (obj && (obj != stopObj)) { + info.left += obj.offsetLeft; + info.top += obj.offsetTop; } - return call && (typeof call === "object" || typeof call === "function") ? call : self; + return info; + }, + + Client: function (elem) { + // constructor for new simple upload client + this.handlers = {}; + + // unique ID + this.id = ZeroClipboard.nextId++; + this.movieId = 'ZeroClipboardMovie_' + this.id; + + // register client with singleton to receive flash events + ZeroClipboard.register(this.id, this); + + // create movie + if (elem) this.glue(elem); } + }; - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + ZeroClipboard.Client.prototype = { + + id: 0, + // unique ID for us + ready: false, + // whether movie is ready to receive events or not + movie: null, + // reference to movie object + clipText: '', + // text to copy to clipboard + handCursorEnabled: true, + // whether to show hand cursor, or default pointer cursor + cssEffects: true, + // enable CSS mouse effects on dom container + handlers: null, + // user event handlers + glue: function (elem, appendElem, stylesToAdd) { + // glue to DOM element + // elem can be ID or actual DOM element object + this.domElement = ZeroClipboard.$(elem); + + // float just above object, or zIndex 99 if dom element isn't set + var zIndex = 99; + if (this.domElement.style.zIndex) { + zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; + } + + if (typeof(appendElem) == 'string') { + appendElem = ZeroClipboard.$(appendElem); + } else if (typeof(appendElem) == 'undefined') { + appendElem = document.getElementsByTagName('body')[0]; + } + + // find X/Y position of domElement + var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); + + // create floating DIV above element + this.div = document.createElement('div'); + this.div.className = "zclip"; + this.div.id = "zclip-" + this.movieId; + $(this.domElement).data('zclipId', 'zclip-' + this.movieId); + var style = this.div.style; + style.position = 'absolute'; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + style.width = '' + box.width + 'px'; + style.height = '' + box.height + 'px'; + style.zIndex = zIndex; + + if (typeof(stylesToAdd) == 'object') { + for (addedStyle in stylesToAdd) { + style[addedStyle] = stylesToAdd[addedStyle]; + } } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - } + // style.backgroundColor = '#f00'; // debug + appendElem.appendChild(this.div); - var Clipboard = function (_Emitter) { - _inherits(Clipboard, _Emitter); + this.div.innerHTML = this.getHTML(box.width, box.height); + }, - /** - * @param {String|HTMLElement|HTMLCollection|NodeList} trigger - * @param {Object} options - */ - function Clipboard(trigger, options) { - _classCallCheck(this, Clipboard); + getHTML: function (width, height) { + // return HTML for movie + var html = ''; + var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; - var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + if (navigator.userAgent.match(/MSIE/)) { + // IE gets an OBJECT tag + var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; + html += ''; + } else { + // all other browsers get an EMBED tag + html += ''; + } + return html; + }, - _this.resolveOptions(options); - _this.listenClick(trigger); - return _this; + hide: function () { + // temporarily hide floater offscreen + if (this.div) { + this.div.style.left = '-2000px'; } + }, + + show: function () { + // show ourselves after a call to hide() + this.reposition(); + }, - /** - * Defines if attributes would be resolved using internal setter functions - * or custom functions that were passed in the constructor. - * @param {Object} options - */ + destroy: function () { + // destroy control and floater + if (this.domElement && this.div) { + this.hide(); + this.div.innerHTML = ''; + + var body = document.getElementsByTagName('body')[0]; + try { + body.removeChild(this.div); + } catch (e) { + ; + } + this.domElement = null; + this.div = null; + } + }, - _createClass(Clipboard, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + reposition: function (elem) { + // reposition our floating div, optionally to new container + // warning: container CANNOT change size, only position + if (elem) { + this.domElement = ZeroClipboard.$(elem); + if (!this.domElement) this.hide(); + } - this.action = typeof options.action === 'function' ? options.action : this.defaultAction; - this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; - this.text = typeof options.text === 'function' ? options.text : this.defaultText; - } - }, { - key: 'listenClick', - value: function listenClick(trigger) { - var _this2 = this; + if (this.domElement && this.div) { + var box = ZeroClipboard.getDOMObjectPosition(this.domElement); + var style = this.div.style; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + } + }, - this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { - return _this2.onClick(e); - }); - } - }, { - key: 'onClick', - value: function onClick(e) { - var trigger = e.delegateTarget || e.currentTarget; + setText: function (newText) { + // set text to be copied to clipboard + this.clipText = newText; + if (this.ready) { + this.movie.setText(newText); + } + }, - if (this.clipboardAction) { - this.clipboardAction = null; - } + addEventListener: function (eventName, func) { + // add user event listener for event + // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + if (!this.handlers[eventName]) { + this.handlers[eventName] = []; + } + this.handlers[eventName].push(func); + }, - this.clipboardAction = new _clipboardAction2.default({ - action: this.action(trigger), - target: this.target(trigger), - text: this.text(trigger), - trigger: trigger, - emitter: this - }); - } - }, { - key: 'defaultAction', - value: function defaultAction(trigger) { - return getAttributeValue('action', trigger); - } - }, { - key: 'defaultTarget', - value: function defaultTarget(trigger) { - var selector = getAttributeValue('target', trigger); + setHandCursor: function (enabled) { + // enable hand cursor (true), or default arrow cursor (false) + this.handCursorEnabled = enabled; + if (this.ready) { + this.movie.setHandCursor(enabled); + } + }, - if (selector) { - return document.querySelector(selector); + setCSSEffects: function (enabled) { + // enable or disable CSS effects on DOM container + this.cssEffects = !!enabled; + }, + + receiveEvent: function (eventName, args) { + // receive event from flash + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + + // special behavior for certain events + switch (eventName) { + case 'load': + // movie claims it is ready, but in IE this isn't always the case... + // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function + this.movie = document.getElementById(this.movieId); + if (!this.movie) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 1); + return; } - } - }, { - key: 'defaultText', - value: function defaultText(trigger) { - return getAttributeValue('text', trigger); - } - }, { - key: 'destroy', - value: function destroy() { - this.listener.destroy(); - if (this.clipboardAction) { - this.clipboardAction.destroy(); - this.clipboardAction = null; + // firefox on pc needs a "kick" in order to set these in certain cases + if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 100); + this.ready = true; + return; } - } - }], [{ - key: 'isSupported', - value: function isSupported() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; - var actions = typeof action === 'string' ? [action] : action; - var support = !!document.queryCommandSupported; + this.ready = true; + try { + this.movie.setText(this.clipText); + } catch (e) { + } + try { + this.movie.setHandCursor(this.handCursorEnabled); + } catch (e) { + } + break; - actions.forEach(function (action) { - support = support && !!document.queryCommandSupported(action); - }); + case 'mouseover': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('hover'); + if (this.recoverActive) { + this.domElement.addClass('active'); + } - return support; - } - }]); - return Clipboard; - }(_tinyEmitter2.default); + } - /** - * Helper function to retrieve attribute value. - * @param {String} suffix - * @param {Element} element - */ - function getAttributeValue(suffix, element) { - var attribute = 'data-clipboard-' + suffix; - if (!element.hasAttribute(attribute)) { - return; - } + break; - return element.getAttribute(attribute); - } + case 'mouseout': + if (this.domElement && this.cssEffects) { + this.recoverActive = false; + if (this.domElement.hasClass('active')) { + this.domElement.removeClass('active'); + this.recoverActive = true; + } + this.domElement.removeClass('hover'); - module.exports = Clipboard; - }); + } + break; -},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) -});/** + case 'mousedown': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('active'); + } + break; + + case 'mouseup': + if (this.domElement && this.cssEffects) { + this.domElement.removeClass('active'); + this.recoverActive = false; + } + break; + } // switch eventName + if (this.handlers[eventName]) { + for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { + var func = this.handlers[eventName][idx]; + + if (typeof(func) == 'function') { + // actual function reference + func(this, args); + } else if ((typeof(func) == 'object') && (func.length == 2)) { + // PHP style object + method, i.e. [myObject, 'myMethod'] + func[0][func[1]](this, args); + } else if (typeof(func) == 'string') { + // name of function + window[func](this, args); + } + } // foreach event handler defined + } // user defined handler for event + } + + }; +}/** * 复制 * Created by GUY on 2016/2/16. * @class BI.ClipBoard @@ -3009,7 +3550,7 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-clipboard", - text: "", + copy: BI.emptyFn, afterCopy: BI.emptyFn }) }, @@ -3020,18 +3561,27 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { mounted: function () { var self = this, o = this.options; - this.clipboard = new Clipboard(this.element[0], { - text: function () { - return BI.isFunction(o.text) ? o.text() : o.text; - } - }); - this.clipboard.on("success", function (e) { - o.afterCopy(); - }) + if (window.Clipboard) { + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.copy) ? o.copy() : o.copy; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + } else { + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy + }); + } }, destroyed: function () { - this.clipboard.destroy(); + this.clipboard && this.clipboard.destroy(); } }); diff --git a/demo/js/case/demo.clipboard.js b/demo/js/case/demo.clipboard.js index 17ea3cfecf..d831b28d39 100644 --- a/demo/js/case/demo.clipboard.js +++ b/demo/js/case/demo.clipboard.js @@ -15,7 +15,7 @@ Demo.Func = BI.inherit(BI.Widget, { width: 100, height: 100, cls: 'layout-bg1', - text: function () { + copy: function () { return editor.getValue(); }, diff --git a/docs/case.js b/docs/case.js index 7212e6106a..b70256eb61 100644 --- a/docs/case.js +++ b/docs/case.js @@ -2228,778 +2228,1319 @@ BI.shortcut("bi.tree_node_checkbox", BI.TreeNodeCheckbox);/*! * * Licensed MIT © Zeno Rocha */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; - var _select2 = _interopRequireDefault(_select); + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2["default"])(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2["default"])(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; + return ClipboardAction; + }(); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } + module.exports = ClipboardAction; + }); - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } + }, {"select": 5}], 8: [function (require, module, exports) { + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); - var ClipboardAction = function () { - /** - * @param {Object} options - */ - function ClipboardAction(options) { - _classCallCheck(this, ClipboardAction); + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); - this.resolveOptions(options); - this.initSelection(); - } + var _goodListener2 = _interopRequireDefault(_goodListener); - /** - * Defines base properties passed from constructor. - * @param {Object} options - */ + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; + } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - _createClass(ClipboardAction, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - this.action = options.action; - this.emitter = options.emitter; - this.target = options.target; - this.text = options.text; - this.trigger = options.trigger; + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); - this.selectedText = ''; - } - }, { - key: 'initSelection', - value: function initSelection() { - if (this.text) { - this.selectFake(); - } else if (this.target) { - this.selectTarget(); - } - } - }, { - key: 'selectFake', - value: function selectFake() { - var _this = this; + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } - var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } - this.removeFake(); + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } - this.fakeHandlerCallback = function () { - return _this.removeFake(); - }; - this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; - - this.fakeElem = document.createElement('textarea'); - // Prevent zooming on iOS - this.fakeElem.style.fontSize = '12pt'; - // Reset box model - this.fakeElem.style.border = '0'; - this.fakeElem.style.padding = '0'; - this.fakeElem.style.margin = '0'; - // Move element out of screen horizontally - this.fakeElem.style.position = 'absolute'; - this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; - // Move element to the same position vertically - var yPosition = window.pageYOffset || document.documentElement.scrollTop; - this.fakeElem.style.top = yPosition + 'px'; - - this.fakeElem.setAttribute('readonly', ''); - this.fakeElem.value = this.text; - - document.body.appendChild(this.fakeElem); - - this.selectedText = (0, _select2.default)(this.fakeElem); - this.copyText(); - } - }, { - key: 'removeFake', - value: function removeFake() { - if (this.fakeHandler) { - document.body.removeEventListener('click', this.fakeHandlerCallback); - this.fakeHandler = null; - this.fakeHandlerCallback = null; + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - if (this.fakeElem) { - document.body.removeChild(this.fakeElem); - this.fakeElem = null; - } - } - }, { - key: 'selectTarget', - value: function selectTarget() { - this.selectedText = (0, _select2.default)(this.target); - this.copyText(); - } - }, { - key: 'copyText', - value: function copyText() { - var succeeded = void 0; + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); - try { - succeeded = document.execCommand(this.action); - } catch (err) { - succeeded = false; - } + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); - this.handleResult(succeeded); - } - }, { - key: 'handleResult', - value: function handleResult(succeeded) { - this.emitter.emit(succeeded ? 'success' : 'error', { - action: this.action, - text: this.selectedText, - trigger: this.trigger, - clearSelection: this.clearSelection.bind(this) - }); - } - }, { - key: 'clearSelection', - value: function clearSelection() { - if (this.target) { - this.target.blur(); - } + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); - window.getSelection().removeAllRanges(); - } - }, { - key: 'destroy', - value: function destroy() { - this.removeFake(); - } - }, { - key: 'action', - set: function set() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } - this._action = action; + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ - if (this._action !== 'copy' && this._action !== 'cut') { - throw new Error('Invalid "action" value, use either "copy" or "cut"'); - } - }, - get: function get() { - return this._action; - } - }, { - key: 'target', - set: function set(target) { - if (target !== undefined) { - if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { - if (this.action === 'copy' && target.hasAttribute('disabled')) { - throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2["default"])(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2["default"]({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; - if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { - throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; } + }]); - this._target = target; - } else { - throw new Error('Invalid "target" value, use a valid Element'); + return Clipboard; + }(_tinyEmitter2["default"]); + + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; } + + return element.getAttribute(attribute); } - }, - get: function get() { - return this._target; - } - }]); - return ClipboardAction; - }(); + module.exports = Clipboard; + }); - module.exports = ClipboardAction; + }, {"./clipboard-action": 7, "good-listener": 4, "tiny-emitter": 6}] + }, {}, [8])(8) }); +} catch (e) { + /* + * zClip :: jQuery ZeroClipboard v1.1.1 + * http://steamdev.com/zclip + * + * Copyright 2011, SteamDev + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Date: Wed Jun 01, 2011 + */ -},{"select":5}],8:[function(require,module,exports){ - (function (global, factory) { - if (typeof define === "function" && define.amd) { - define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); - } else if (typeof exports !== "undefined") { - factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); - } else { - var mod = { - exports: {} - }; - factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); - global.clipboard = mod.exports; - } - })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { - 'use strict'; - var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + (function ($) { - var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + $.fn.zclip = function (params) { - var _goodListener2 = _interopRequireDefault(_goodListener); + if (typeof params == "object" && !params.length) { - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + var settings = $.extend({ + + path: 'ZeroClipboard.swf', + copy: null, + beforeCopy: null, + afterCopy: null, + clickAfter: true, + setHandCursor: true, + setCSSEffects: true + + }, params); + + + return this.each(function () { + + var o = $(this); + + if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { + + ZeroClipboard.setMoviePath(settings.path); + var clip = new ZeroClipboard.Client(); + + if ($.isFunction(settings.copy)) { + o.bind('zClip_copy', settings.copy); + } + if ($.isFunction(settings.beforeCopy)) { + o.bind('zClip_beforeCopy', settings.beforeCopy); + } + if ($.isFunction(settings.afterCopy)) { + o.bind('zClip_afterCopy', settings.afterCopy); + } + + clip.setHandCursor(settings.setHandCursor); + clip.setCSSEffects(settings.setCSSEffects); + clip.addEventListener('mouseOver', function (client) { + o.trigger('mouseenter'); + }); + clip.addEventListener('mouseOut', function (client) { + o.trigger('mouseleave'); + }); + clip.addEventListener('mouseDown', function (client) { + + o.trigger('mousedown'); + + if (!$.isFunction(settings.copy)) { + clip.setText(settings.copy); + } else { + clip.setText(o.triggerHandler('zClip_copy')); + } + + if ($.isFunction(settings.beforeCopy)) { + o.trigger('zClip_beforeCopy'); + } + + }); + + clip.addEventListener('complete', function (client, text) { + + if ($.isFunction(settings.afterCopy)) { + + o.trigger('zClip_afterCopy'); + + } else { + if (text.length > 500) { + text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; + } + + o.removeClass('hover'); + alert("Copied text to clipboard:\n\n " + text); + } + + if (settings.clickAfter) { + o.trigger('click'); + } + + }); + + + clip.glue(o[0], o.parent()[0]); + + $(window).bind('load resize', function () { + clip.reposition(); + }); + + + } + + }); + + } else if (typeof params == "string") { + + return this.each(function () { + + var o = $(this); + + params = params.toLowerCase(); + var zclipId = o.data('zclipId'); + var clipElm = $('#' + zclipId + '.zclip'); + + if (params == "remove") { + + clipElm.remove(); + o.removeClass('active hover'); + + } else if (params == "hide") { + + clipElm.hide(); + o.removeClass('active hover'); + + } else if (params == "show") { + + clipElm.show(); + + } + + }); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); } + } - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } + + })(jQuery); + + +// ZeroClipboard +// Simple Set Clipboard System +// Author: Joseph Huckaby + var ZeroClipboard = { + + version: "1.0.7", + clients: {}, + // registered upload clients on page, indexed by id + moviePath: 'ZeroClipboard.swf', + // URL to movie + nextId: 1, + // ID of next movie + $: function (thingy) { + // simple DOM lookup utility function + if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); + if (!thingy.addClass) { + // extend element with a few useful methods + thingy.hide = function () { + this.style.display = 'none'; + }; + thingy.show = function () { + this.style.display = ''; + }; + thingy.addClass = function (name) { + this.removeClass(name); + this.className += ' ' + name; + }; + thingy.removeClass = function (name) { + var classes = this.className.split(/\s+/); + var idx = -1; + for (var k = 0; k < classes.length; k++) { + if (classes[k] == name) { + idx = k; + k = classes.length; + } + } + if (idx > -1) { + classes.splice(idx, 1); + this.className = classes.join(' '); + } + return this; + }; + thingy.hasClass = function (name) { + return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); + }; } + return thingy; + }, + + setMoviePath: function (path) { + // set path to ZeroClipboard.swf + this.moviePath = path; + }, - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; + dispatch: function (id, eventName, args) { + // receive event from flash movie, send to client + var client = this.clients[id]; + if (client) { + client.receiveEvent(eventName, args); + } + }, + + register: function (id, client) { + // register new client to receive events + this.clients[id] = client; + }, + + getDOMObjectPosition: function (obj, stopObj) { + // get absolute coordinates for dom element + var info = { + left: 0, + top: 0, + width: obj.width ? obj.width : obj.offsetWidth, + height: obj.height ? obj.height : obj.offsetHeight }; - }(); - function _possibleConstructorReturn(self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + if (obj && (obj != stopObj)) { + info.left += obj.offsetLeft; + info.top += obj.offsetTop; } - return call && (typeof call === "object" || typeof call === "function") ? call : self; + return info; + }, + + Client: function (elem) { + // constructor for new simple upload client + this.handlers = {}; + + // unique ID + this.id = ZeroClipboard.nextId++; + this.movieId = 'ZeroClipboardMovie_' + this.id; + + // register client with singleton to receive flash events + ZeroClipboard.register(this.id, this); + + // create movie + if (elem) this.glue(elem); } + }; - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + ZeroClipboard.Client.prototype = { + + id: 0, + // unique ID for us + ready: false, + // whether movie is ready to receive events or not + movie: null, + // reference to movie object + clipText: '', + // text to copy to clipboard + handCursorEnabled: true, + // whether to show hand cursor, or default pointer cursor + cssEffects: true, + // enable CSS mouse effects on dom container + handlers: null, + // user event handlers + glue: function (elem, appendElem, stylesToAdd) { + // glue to DOM element + // elem can be ID or actual DOM element object + this.domElement = ZeroClipboard.$(elem); + + // float just above object, or zIndex 99 if dom element isn't set + var zIndex = 99; + if (this.domElement.style.zIndex) { + zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; + } + + if (typeof(appendElem) == 'string') { + appendElem = ZeroClipboard.$(appendElem); + } else if (typeof(appendElem) == 'undefined') { + appendElem = document.getElementsByTagName('body')[0]; + } + + // find X/Y position of domElement + var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); + + // create floating DIV above element + this.div = document.createElement('div'); + this.div.className = "zclip"; + this.div.id = "zclip-" + this.movieId; + $(this.domElement).data('zclipId', 'zclip-' + this.movieId); + var style = this.div.style; + style.position = 'absolute'; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + style.width = '' + box.width + 'px'; + style.height = '' + box.height + 'px'; + style.zIndex = zIndex; + + if (typeof(stylesToAdd) == 'object') { + for (addedStyle in stylesToAdd) { + style[addedStyle] = stylesToAdd[addedStyle]; + } } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - } + // style.backgroundColor = '#f00'; // debug + appendElem.appendChild(this.div); - var Clipboard = function (_Emitter) { - _inherits(Clipboard, _Emitter); + this.div.innerHTML = this.getHTML(box.width, box.height); + }, - /** - * @param {String|HTMLElement|HTMLCollection|NodeList} trigger - * @param {Object} options - */ - function Clipboard(trigger, options) { - _classCallCheck(this, Clipboard); + getHTML: function (width, height) { + // return HTML for movie + var html = ''; + var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; - var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + if (navigator.userAgent.match(/MSIE/)) { + // IE gets an OBJECT tag + var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; + html += ''; + } else { + // all other browsers get an EMBED tag + html += ''; + } + return html; + }, - _this.resolveOptions(options); - _this.listenClick(trigger); - return _this; + hide: function () { + // temporarily hide floater offscreen + if (this.div) { + this.div.style.left = '-2000px'; } + }, + + show: function () { + // show ourselves after a call to hide() + this.reposition(); + }, - /** - * Defines if attributes would be resolved using internal setter functions - * or custom functions that were passed in the constructor. - * @param {Object} options - */ + destroy: function () { + // destroy control and floater + if (this.domElement && this.div) { + this.hide(); + this.div.innerHTML = ''; + + var body = document.getElementsByTagName('body')[0]; + try { + body.removeChild(this.div); + } catch (e) { + ; + } + this.domElement = null; + this.div = null; + } + }, - _createClass(Clipboard, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + reposition: function (elem) { + // reposition our floating div, optionally to new container + // warning: container CANNOT change size, only position + if (elem) { + this.domElement = ZeroClipboard.$(elem); + if (!this.domElement) this.hide(); + } - this.action = typeof options.action === 'function' ? options.action : this.defaultAction; - this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; - this.text = typeof options.text === 'function' ? options.text : this.defaultText; - } - }, { - key: 'listenClick', - value: function listenClick(trigger) { - var _this2 = this; + if (this.domElement && this.div) { + var box = ZeroClipboard.getDOMObjectPosition(this.domElement); + var style = this.div.style; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + } + }, - this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { - return _this2.onClick(e); - }); - } - }, { - key: 'onClick', - value: function onClick(e) { - var trigger = e.delegateTarget || e.currentTarget; + setText: function (newText) { + // set text to be copied to clipboard + this.clipText = newText; + if (this.ready) { + this.movie.setText(newText); + } + }, - if (this.clipboardAction) { - this.clipboardAction = null; - } + addEventListener: function (eventName, func) { + // add user event listener for event + // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + if (!this.handlers[eventName]) { + this.handlers[eventName] = []; + } + this.handlers[eventName].push(func); + }, - this.clipboardAction = new _clipboardAction2.default({ - action: this.action(trigger), - target: this.target(trigger), - text: this.text(trigger), - trigger: trigger, - emitter: this - }); - } - }, { - key: 'defaultAction', - value: function defaultAction(trigger) { - return getAttributeValue('action', trigger); - } - }, { - key: 'defaultTarget', - value: function defaultTarget(trigger) { - var selector = getAttributeValue('target', trigger); + setHandCursor: function (enabled) { + // enable hand cursor (true), or default arrow cursor (false) + this.handCursorEnabled = enabled; + if (this.ready) { + this.movie.setHandCursor(enabled); + } + }, - if (selector) { - return document.querySelector(selector); + setCSSEffects: function (enabled) { + // enable or disable CSS effects on DOM container + this.cssEffects = !!enabled; + }, + + receiveEvent: function (eventName, args) { + // receive event from flash + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + + // special behavior for certain events + switch (eventName) { + case 'load': + // movie claims it is ready, but in IE this isn't always the case... + // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function + this.movie = document.getElementById(this.movieId); + if (!this.movie) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 1); + return; } - } - }, { - key: 'defaultText', - value: function defaultText(trigger) { - return getAttributeValue('text', trigger); - } - }, { - key: 'destroy', - value: function destroy() { - this.listener.destroy(); - if (this.clipboardAction) { - this.clipboardAction.destroy(); - this.clipboardAction = null; + // firefox on pc needs a "kick" in order to set these in certain cases + if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 100); + this.ready = true; + return; } - } - }], [{ - key: 'isSupported', - value: function isSupported() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; - var actions = typeof action === 'string' ? [action] : action; - var support = !!document.queryCommandSupported; + this.ready = true; + try { + this.movie.setText(this.clipText); + } catch (e) { + } + try { + this.movie.setHandCursor(this.handCursorEnabled); + } catch (e) { + } + break; - actions.forEach(function (action) { - support = support && !!document.queryCommandSupported(action); - }); + case 'mouseover': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('hover'); + if (this.recoverActive) { + this.domElement.addClass('active'); + } - return support; - } - }]); - return Clipboard; - }(_tinyEmitter2.default); + } - /** - * Helper function to retrieve attribute value. - * @param {String} suffix - * @param {Element} element - */ - function getAttributeValue(suffix, element) { - var attribute = 'data-clipboard-' + suffix; - if (!element.hasAttribute(attribute)) { - return; - } + break; - return element.getAttribute(attribute); - } + case 'mouseout': + if (this.domElement && this.cssEffects) { + this.recoverActive = false; + if (this.domElement.hasClass('active')) { + this.domElement.removeClass('active'); + this.recoverActive = true; + } + this.domElement.removeClass('hover'); - module.exports = Clipboard; - }); + } + break; -},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) -});/** + case 'mousedown': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('active'); + } + break; + + case 'mouseup': + if (this.domElement && this.cssEffects) { + this.domElement.removeClass('active'); + this.recoverActive = false; + } + break; + } // switch eventName + if (this.handlers[eventName]) { + for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { + var func = this.handlers[eventName][idx]; + + if (typeof(func) == 'function') { + // actual function reference + func(this, args); + } else if ((typeof(func) == 'object') && (func.length == 2)) { + // PHP style object + method, i.e. [myObject, 'myMethod'] + func[0][func[1]](this, args); + } else if (typeof(func) == 'string') { + // name of function + window[func](this, args); + } + } // foreach event handler defined + } // user defined handler for event + } + + }; +}/** * 复制 * Created by GUY on 2016/2/16. * @class BI.ClipBoard @@ -3009,7 +3550,7 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-clipboard", - text: "", + copy: BI.emptyFn, afterCopy: BI.emptyFn }) }, @@ -3020,18 +3561,27 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { mounted: function () { var self = this, o = this.options; - this.clipboard = new Clipboard(this.element[0], { - text: function () { - return BI.isFunction(o.text) ? o.text() : o.text; - } - }); - this.clipboard.on("success", function (e) { - o.afterCopy(); - }) + if (window.Clipboard) { + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.copy) ? o.copy() : o.copy; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + } else { + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy + }); + } }, destroyed: function () { - this.clipboard.destroy(); + this.clipboard && this.clipboard.destroy(); } }); diff --git a/docs/demo.js b/docs/demo.js index 5f9326ce7a..a185cd476a 100644 --- a/docs/demo.js +++ b/docs/demo.js @@ -1750,7 +1750,7 @@ BI.shortcut("demo.calendar", Demo.Func);Demo.Func = BI.inherit(BI.Widget, { width: 100, height: 100, cls: 'layout-bg1', - text: function () { + copy: function () { return editor.getValue(); }, diff --git a/docs/resource/ZeroClipboard.swf b/docs/resource/ZeroClipboard.swf new file mode 100644 index 0000000000000000000000000000000000000000..13bf8e396202964e0048333d878f4b949a2f5e6a GIT binary patch literal 1071 zcmV+~1kn3KS5pay1^@tfoPAa6Qrkup-d$aeB-A-xFjKf1te)pFM-&Q&_dOT zp~-XxqP4X~YJ}vGWC;KAD1C=MKwiO_PG6^Vbs@z~r#qgr-}!Xr?4IxJ9P1kT4dpSa zmlT9hja*+}e;Cbih*6`(JT|+I(1(#NIVSiTL~Dq=|Lb=d5tOYL`L;_#dyQQ%FAAmI zcth~a_gzLk@xphk!Y?fFYp&C2`ZTZ#X}INt9hY9ojZWZ1Om23g$oC2%i(XLAs&#|V z5ArS7X}yhomj%SJGT~|rnZj|zM|I&j59e1QKqGxQN5!(ijWrx1S)ZN!RwWBwC`$uYc z!)028S7F4?l?H2dd39HKImh$+mv#S~I-YjmQ;P-rUfUM~-;Xr+ldpAXK+hS!b|@Ro zUs)@fv!kf9RjpFXZ?d(Pe_q{bY*sgP{Ykaib==7Da_N!X$Z^AwK5e&BZ5R56j>T=;_5DD$nR8}GiWShym;5A&x*eM;)Us-}<67Eb+@9n>sdlhm z`(coON!$a6H-ML=9U8}t-8aV1yD!xY9v@|7-FWq*lEUMka&b=Hq$X{>72}4eNl_P+ zccPJWGtXb!r#GbVPIO$}sN%oME%Yf<`b@|2f6G5y#$}-l zAR|D=L6`ti0Wt|N4P*v{Ss-&j?gE(yvY_TMkQE@SK-Pd%f#~WwXExMLZXW@84CD#m zFMxar!IU~i}ZGSTvX;GX_!`A@yKkIbSu*e=l_b9m*BF@hOB8SS;p?XkU4 z+#Y{FagI+_hF#pQ*y^c#B7H9*TQ=n-IvJZOQ*KYMV&e{u!2((~XOiIAy*Zr0yBr$x zqA6D~T{u}ZWn+;Cn@jC`refSD34E}PZ{YGaxq%P2g&VlCEyl30qM2Z<#-M2CQxMno zG_4J8H7mc8(VenQzJ;=@j=BiTh*RubMeS$61ORcM^S6!u6l;=?s|@ py1A~K8@jovn~!u;;=k8uI$3rc`gC{*rT-s&a~N%N=5J58nk1s|4c7nw literal 0 HcmV?d00001 diff --git a/src/case/clipboard/clipboard.js b/src/case/clipboard/clipboard.js index 5606dd98a4..fc699ebc78 100644 --- a/src/case/clipboard/clipboard.js +++ b/src/case/clipboard/clipboard.js @@ -4,775 +4,1316 @@ * * Licensed MIT © Zeno Rocha */ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; - return this; - } - }; + this.action = options.action; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; - module.exports = E; + this.selectedText = ''; + } + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + document.body.appendChild(this.fakeElem); + + this.selectedText = (0, _select2["default"])(this.fakeElem); + this.copyText(); + } + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + document.body.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + document.body.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2["default"])(this.target); + this.copyText(); + } + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.target) { + this.target.blur(); + } + + window.getSelection().removeAllRanges(); + } + }, { + key: 'destroy', + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + }, + get: function get() { + return this._action; + } + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + }, + get: function get() { + return this._target; + } + }]); -},{}],7:[function(require,module,exports){ - (function (global, factory) { - if (typeof define === "function" && define.amd) { - define(['module', 'select'], factory); - } else if (typeof exports !== "undefined") { - factory(module, require('select')); - } else { - var mod = { - exports: {} - }; - factory(mod, global.select); - global.clipboardAction = mod.exports; - } - })(this, function (module, _select) { - 'use strict'; + return ClipboardAction; + }(); - var _select2 = _interopRequireDefault(_select); + module.exports = ClipboardAction; + }); - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + }, {"select": 5}], 8: [function (require, module, exports) { + (function (global, factory) { + if (typeof define === "function" && define.amd) { + define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); + } else if (typeof exports !== "undefined") { + factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); + } else { + var mod = { + exports: {} + }; + factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); + global.clipboard = mod.exports; + } + })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { + 'use strict'; - var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; + var _clipboardAction2 = _interopRequireDefault(_clipboardAction); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } + var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } + var _goodListener2 = _interopRequireDefault(_goodListener); - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; + } - var ClipboardAction = function () { - /** - * @param {Object} options - */ - function ClipboardAction(options) { - _classCallCheck(this, ClipboardAction); + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - this.resolveOptions(options); - this.initSelection(); - } + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - /** - * Defines base properties passed from constructor. - * @param {Object} options - */ + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } - _createClass(ClipboardAction, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return call && (typeof call === "object" || typeof call === "function") ? call : self; + } - this.action = options.action; - this.emitter = options.emitter; - this.target = options.target; - this.text = options.text; - this.trigger = options.trigger; + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } - this.selectedText = ''; - } - }, { - key: 'initSelection', - value: function initSelection() { - if (this.text) { - this.selectFake(); - } else if (this.target) { - this.selectTarget(); + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - } - }, { - key: 'selectFake', - value: function selectFake() { - var _this = this; - var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); - this.removeFake(); + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); - this.fakeHandlerCallback = function () { - return _this.removeFake(); - }; - this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true; - - this.fakeElem = document.createElement('textarea'); - // Prevent zooming on iOS - this.fakeElem.style.fontSize = '12pt'; - // Reset box model - this.fakeElem.style.border = '0'; - this.fakeElem.style.padding = '0'; - this.fakeElem.style.margin = '0'; - // Move element out of screen horizontally - this.fakeElem.style.position = 'absolute'; - this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; - // Move element to the same position vertically - var yPosition = window.pageYOffset || document.documentElement.scrollTop; - this.fakeElem.style.top = yPosition + 'px'; - - this.fakeElem.setAttribute('readonly', ''); - this.fakeElem.value = this.text; - - document.body.appendChild(this.fakeElem); - - this.selectedText = (0, _select2.default)(this.fakeElem); - this.copyText(); - } - }, { - key: 'removeFake', - value: function removeFake() { - if (this.fakeHandler) { - document.body.removeEventListener('click', this.fakeHandlerCallback); - this.fakeHandler = null; - this.fakeHandlerCallback = null; - } + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); - if (this.fakeElem) { - document.body.removeChild(this.fakeElem); - this.fakeElem = null; - } - } - }, { - key: 'selectTarget', - value: function selectTarget() { - this.selectedText = (0, _select2.default)(this.target); - this.copyText(); - } - }, { - key: 'copyText', - value: function copyText() { - var succeeded = void 0; - - try { - succeeded = document.execCommand(this.action); - } catch (err) { - succeeded = false; - } + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } - this.handleResult(succeeded); - } - }, { - key: 'handleResult', - value: function handleResult(succeeded) { - this.emitter.emit(succeeded ? 'success' : 'error', { - action: this.action, - text: this.selectedText, - trigger: this.trigger, - clearSelection: this.clearSelection.bind(this) - }); - } - }, { - key: 'clearSelection', - value: function clearSelection() { - if (this.target) { - this.target.blur(); - } + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ - window.getSelection().removeAllRanges(); - } - }, { - key: 'destroy', - value: function destroy() { - this.removeFake(); - } - }, { - key: 'action', - set: function set() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; - this._action = action; + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - if (this._action !== 'copy' && this._action !== 'cut') { - throw new Error('Invalid "action" value, use either "copy" or "cut"'); - } - }, - get: function get() { - return this._action; - } - }, { - key: 'target', - set: function set(target) { - if (target !== undefined) { - if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { - if (this.action === 'copy' && target.hasAttribute('disabled')) { - throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; } + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2["default"])(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2["default"]({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + trigger: trigger, + emitter: this + }); + } + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + }, { + key: 'defaultText', + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; - if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { - throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; } + }]); + + return Clipboard; + }(_tinyEmitter2["default"]); - this._target = target; - } else { - throw new Error('Invalid "target" value, use a valid Element'); + /** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; } + + return element.getAttribute(attribute); } - }, - get: function get() { - return this._target; - } - }]); - return ClipboardAction; - }(); + module.exports = Clipboard; + }); - module.exports = ClipboardAction; + }, {"./clipboard-action": 7, "good-listener": 4, "tiny-emitter": 6}] + }, {}, [8])(8) }); +} catch (e) { + /* + * zClip :: jQuery ZeroClipboard v1.1.1 + * http://steamdev.com/zclip + * + * Copyright 2011, SteamDev + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Date: Wed Jun 01, 2011 + */ -},{"select":5}],8:[function(require,module,exports){ - (function (global, factory) { - if (typeof define === "function" && define.amd) { - define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); - } else if (typeof exports !== "undefined") { - factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); - } else { - var mod = { - exports: {} - }; - factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); - global.clipboard = mod.exports; - } - })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { - 'use strict'; - var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + (function ($) { - var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + $.fn.zclip = function (params) { - var _goodListener2 = _interopRequireDefault(_goodListener); + if (typeof params == "object" && !params.length) { - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - } + var settings = $.extend({ + + path: 'ZeroClipboard.swf', + copy: null, + beforeCopy: null, + afterCopy: null, + clickAfter: true, + setHandCursor: true, + setCSSEffects: true + + }, params); + + + return this.each(function () { + + var o = $(this); + + if (o.is(':visible') && (typeof settings.copy == 'string' || $.isFunction(settings.copy))) { + + ZeroClipboard.setMoviePath(settings.path); + var clip = new ZeroClipboard.Client(); + + if ($.isFunction(settings.copy)) { + o.bind('zClip_copy', settings.copy); + } + if ($.isFunction(settings.beforeCopy)) { + o.bind('zClip_beforeCopy', settings.beforeCopy); + } + if ($.isFunction(settings.afterCopy)) { + o.bind('zClip_afterCopy', settings.afterCopy); + } + + clip.setHandCursor(settings.setHandCursor); + clip.setCSSEffects(settings.setCSSEffects); + clip.addEventListener('mouseOver', function (client) { + o.trigger('mouseenter'); + }); + clip.addEventListener('mouseOut', function (client) { + o.trigger('mouseleave'); + }); + clip.addEventListener('mouseDown', function (client) { + + o.trigger('mousedown'); + + if (!$.isFunction(settings.copy)) { + clip.setText(settings.copy); + } else { + clip.setText(o.triggerHandler('zClip_copy')); + } + + if ($.isFunction(settings.beforeCopy)) { + o.trigger('zClip_beforeCopy'); + } + + }); + + clip.addEventListener('complete', function (client, text) { + + if ($.isFunction(settings.afterCopy)) { + + o.trigger('zClip_afterCopy'); + + } else { + if (text.length > 500) { + text = text.substr(0, 500) + "...\n\n(" + (text.length - 500) + " characters not shown)"; + } + + o.removeClass('hover'); + alert("Copied text to clipboard:\n\n " + text); + } + + if (settings.clickAfter) { + o.trigger('click'); + } + + }); + + + clip.glue(o[0], o.parent()[0]); + + $(window).bind('load resize', function () { + clip.reposition(); + }); + + + } + + }); + + } else if (typeof params == "string") { + + return this.each(function () { + + var o = $(this); + + params = params.toLowerCase(); + var zclipId = o.data('zclipId'); + var clipElm = $('#' + zclipId + '.zclip'); + + if (params == "remove") { + + clipElm.remove(); + o.removeClass('active hover'); + + } else if (params == "hide") { + + clipElm.hide(); + o.removeClass('active hover'); + + } else if (params == "show") { + + clipElm.show(); + + } + + }); - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); } + } - var _createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } + + })(jQuery); + + +// ZeroClipboard +// Simple Set Clipboard System +// Author: Joseph Huckaby + var ZeroClipboard = { + + version: "1.0.7", + clients: {}, + // registered upload clients on page, indexed by id + moviePath: 'ZeroClipboard.swf', + // URL to movie + nextId: 1, + // ID of next movie + $: function (thingy) { + // simple DOM lookup utility function + if (typeof(thingy) == 'string') thingy = document.getElementById(thingy); + if (!thingy.addClass) { + // extend element with a few useful methods + thingy.hide = function () { + this.style.display = 'none'; + }; + thingy.show = function () { + this.style.display = ''; + }; + thingy.addClass = function (name) { + this.removeClass(name); + this.className += ' ' + name; + }; + thingy.removeClass = function (name) { + var classes = this.className.split(/\s+/); + var idx = -1; + for (var k = 0; k < classes.length; k++) { + if (classes[k] == name) { + idx = k; + k = classes.length; + } + } + if (idx > -1) { + classes.splice(idx, 1); + this.className = classes.join(' '); + } + return this; + }; + thingy.hasClass = function (name) { + return !!this.className.match(new RegExp("\\s*" + name + "\\s*")); + }; } + return thingy; + }, - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; + setMoviePath: function (path) { + // set path to ZeroClipboard.swf + this.moviePath = path; + }, + + dispatch: function (id, eventName, args) { + // receive event from flash movie, send to client + var client = this.clients[id]; + if (client) { + client.receiveEvent(eventName, args); + } + }, + + register: function (id, client) { + // register new client to receive events + this.clients[id] = client; + }, + + getDOMObjectPosition: function (obj, stopObj) { + // get absolute coordinates for dom element + var info = { + left: 0, + top: 0, + width: obj.width ? obj.width : obj.offsetWidth, + height: obj.height ? obj.height : obj.offsetHeight }; - }(); - function _possibleConstructorReturn(self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + if (obj && (obj != stopObj)) { + info.left += obj.offsetLeft; + info.top += obj.offsetTop; } - return call && (typeof call === "object" || typeof call === "function") ? call : self; + return info; + }, + + Client: function (elem) { + // constructor for new simple upload client + this.handlers = {}; + + // unique ID + this.id = ZeroClipboard.nextId++; + this.movieId = 'ZeroClipboardMovie_' + this.id; + + // register client with singleton to receive flash events + ZeroClipboard.register(this.id, this); + + // create movie + if (elem) this.glue(elem); } + }; + + ZeroClipboard.Client.prototype = { + + id: 0, + // unique ID for us + ready: false, + // whether movie is ready to receive events or not + movie: null, + // reference to movie object + clipText: '', + // text to copy to clipboard + handCursorEnabled: true, + // whether to show hand cursor, or default pointer cursor + cssEffects: true, + // enable CSS mouse effects on dom container + handlers: null, + // user event handlers + glue: function (elem, appendElem, stylesToAdd) { + // glue to DOM element + // elem can be ID or actual DOM element object + this.domElement = ZeroClipboard.$(elem); + + // float just above object, or zIndex 99 if dom element isn't set + var zIndex = 99; + if (this.domElement.style.zIndex) { + zIndex = parseInt(this.domElement.style.zIndex, 10) + 1; + } - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + if (typeof(appendElem) == 'string') { + appendElem = ZeroClipboard.$(appendElem); + } else if (typeof(appendElem) == 'undefined') { + appendElem = document.getElementsByTagName('body')[0]; } - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true + // find X/Y position of domElement + var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem); + + // create floating DIV above element + this.div = document.createElement('div'); + this.div.className = "zclip"; + this.div.id = "zclip-" + this.movieId; + $(this.domElement).data('zclipId', 'zclip-' + this.movieId); + var style = this.div.style; + style.position = 'absolute'; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + style.width = '' + box.width + 'px'; + style.height = '' + box.height + 'px'; + style.zIndex = zIndex; + + if (typeof(stylesToAdd) == 'object') { + for (addedStyle in stylesToAdd) { + style[addedStyle] = stylesToAdd[addedStyle]; } - }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - } + } - var Clipboard = function (_Emitter) { - _inherits(Clipboard, _Emitter); + // style.backgroundColor = '#f00'; // debug + appendElem.appendChild(this.div); - /** - * @param {String|HTMLElement|HTMLCollection|NodeList} trigger - * @param {Object} options - */ - function Clipboard(trigger, options) { - _classCallCheck(this, Clipboard); + this.div.innerHTML = this.getHTML(box.width, box.height); + }, - var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + getHTML: function (width, height) { + // return HTML for movie + var html = ''; + var flashvars = 'id=' + this.id + '&width=' + width + '&height=' + height; + + if (navigator.userAgent.match(/MSIE/)) { + // IE gets an OBJECT tag + var protocol = location.href.match(/^https/i) ? 'https://' : 'http://'; + html += ''; + } else { + // all other browsers get an EMBED tag + html += ''; + } + return html; + }, - _this.resolveOptions(options); - _this.listenClick(trigger); - return _this; + hide: function () { + // temporarily hide floater offscreen + if (this.div) { + this.div.style.left = '-2000px'; } + }, - /** - * Defines if attributes would be resolved using internal setter functions - * or custom functions that were passed in the constructor. - * @param {Object} options - */ + show: function () { + // show ourselves after a call to hide() + this.reposition(); + }, + destroy: function () { + // destroy control and floater + if (this.domElement && this.div) { + this.hide(); + this.div.innerHTML = ''; + + var body = document.getElementsByTagName('body')[0]; + try { + body.removeChild(this.div); + } catch (e) { + ; + } - _createClass(Clipboard, [{ - key: 'resolveOptions', - value: function resolveOptions() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.domElement = null; + this.div = null; + } + }, - this.action = typeof options.action === 'function' ? options.action : this.defaultAction; - this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; - this.text = typeof options.text === 'function' ? options.text : this.defaultText; - } - }, { - key: 'listenClick', - value: function listenClick(trigger) { - var _this2 = this; + reposition: function (elem) { + // reposition our floating div, optionally to new container + // warning: container CANNOT change size, only position + if (elem) { + this.domElement = ZeroClipboard.$(elem); + if (!this.domElement) this.hide(); + } - this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { - return _this2.onClick(e); - }); - } - }, { - key: 'onClick', - value: function onClick(e) { - var trigger = e.delegateTarget || e.currentTarget; + if (this.domElement && this.div) { + var box = ZeroClipboard.getDOMObjectPosition(this.domElement); + var style = this.div.style; + style.left = '' + box.left + 'px'; + style.top = '' + box.top + 'px'; + } + }, - if (this.clipboardAction) { - this.clipboardAction = null; - } + setText: function (newText) { + // set text to be copied to clipboard + this.clipText = newText; + if (this.ready) { + this.movie.setText(newText); + } + }, - this.clipboardAction = new _clipboardAction2.default({ - action: this.action(trigger), - target: this.target(trigger), - text: this.text(trigger), - trigger: trigger, - emitter: this - }); - } - }, { - key: 'defaultAction', - value: function defaultAction(trigger) { - return getAttributeValue('action', trigger); - } - }, { - key: 'defaultTarget', - value: function defaultTarget(trigger) { - var selector = getAttributeValue('target', trigger); + addEventListener: function (eventName, func) { + // add user event listener for event + // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + if (!this.handlers[eventName]) { + this.handlers[eventName] = []; + } + this.handlers[eventName].push(func); + }, - if (selector) { - return document.querySelector(selector); + setHandCursor: function (enabled) { + // enable hand cursor (true), or default arrow cursor (false) + this.handCursorEnabled = enabled; + if (this.ready) { + this.movie.setHandCursor(enabled); + } + }, + + setCSSEffects: function (enabled) { + // enable or disable CSS effects on DOM container + this.cssEffects = !!enabled; + }, + + receiveEvent: function (eventName, args) { + // receive event from flash + eventName = eventName.toString().toLowerCase().replace(/^on/, ''); + + // special behavior for certain events + switch (eventName) { + case 'load': + // movie claims it is ready, but in IE this isn't always the case... + // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function + this.movie = document.getElementById(this.movieId); + if (!this.movie) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 1); + return; } - } - }, { - key: 'defaultText', - value: function defaultText(trigger) { - return getAttributeValue('text', trigger); - } - }, { - key: 'destroy', - value: function destroy() { - this.listener.destroy(); - if (this.clipboardAction) { - this.clipboardAction.destroy(); - this.clipboardAction = null; + // firefox on pc needs a "kick" in order to set these in certain cases + if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) { + var self = this; + setTimeout(function () { + self.receiveEvent('load', null); + }, 100); + this.ready = true; + return; } - } - }], [{ - key: 'isSupported', - value: function isSupported() { - var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; - var actions = typeof action === 'string' ? [action] : action; - var support = !!document.queryCommandSupported; + this.ready = true; + try { + this.movie.setText(this.clipText); + } catch (e) { + } + try { + this.movie.setHandCursor(this.handCursorEnabled); + } catch (e) { + } + break; + + case 'mouseover': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('hover'); + if (this.recoverActive) { + this.domElement.addClass('active'); + } - actions.forEach(function (action) { - support = support && !!document.queryCommandSupported(action); - }); - return support; - } - }]); + } - return Clipboard; - }(_tinyEmitter2.default); - /** - * Helper function to retrieve attribute value. - * @param {String} suffix - * @param {Element} element - */ - function getAttributeValue(suffix, element) { - var attribute = 'data-clipboard-' + suffix; + break; - if (!element.hasAttribute(attribute)) { - return; - } + case 'mouseout': + if (this.domElement && this.cssEffects) { + this.recoverActive = false; + if (this.domElement.hasClass('active')) { + this.domElement.removeClass('active'); + this.recoverActive = true; + } + this.domElement.removeClass('hover'); - return element.getAttribute(attribute); - } + } + break; - module.exports = Clipboard; - }); + case 'mousedown': + if (this.domElement && this.cssEffects) { + this.domElement.addClass('active'); + } + break; -},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) -}); \ No newline at end of file + case 'mouseup': + if (this.domElement && this.cssEffects) { + this.domElement.removeClass('active'); + this.recoverActive = false; + } + break; + } // switch eventName + if (this.handlers[eventName]) { + for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) { + var func = this.handlers[eventName][idx]; + + if (typeof(func) == 'function') { + // actual function reference + func(this, args); + } else if ((typeof(func) == 'object') && (func.length == 2)) { + // PHP style object + method, i.e. [myObject, 'myMethod'] + func[0][func[1]](this, args); + } else if (typeof(func) == 'string') { + // name of function + window[func](this, args); + } + } // foreach event handler defined + } // user defined handler for event + } + + }; +} \ No newline at end of file diff --git a/src/case/clipboard/index.js b/src/case/clipboard/index.js index 634311b1e2..1b9327d08d 100644 --- a/src/case/clipboard/index.js +++ b/src/case/clipboard/index.js @@ -8,7 +8,7 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { _defaultConfig: function () { return BI.extend(BI.ClipBoard.superclass._defaultConfig.apply(this, arguments), { extraCls: "bi-clipboard", - text: "", + copy: BI.emptyFn, afterCopy: BI.emptyFn }) }, @@ -19,18 +19,27 @@ BI.ClipBoard = BI.inherit(BI.BasicButton, { mounted: function () { var self = this, o = this.options; - this.clipboard = new Clipboard(this.element[0], { - text: function () { - return BI.isFunction(o.text) ? o.text() : o.text; - } - }); - this.clipboard.on("success", function (e) { - o.afterCopy(); - }) + if (window.Clipboard) { + this.clipboard = new Clipboard(this.element[0], { + text: function () { + return BI.isFunction(o.copy) ? o.copy() : o.copy; + } + }); + this.clipboard.on("success", function (e) { + o.afterCopy(); + }) + } else { + this.element.zclip({ + path: BI.resourceURL + "/ZeroClipboard.swf", + copy: o.copy, + beforeCopy: o.beforeCopy, + afterCopy: o.afterCopy + }); + } }, destroyed: function () { - this.clipboard.destroy(); + this.clipboard && this.clipboard.destroy(); } });