@ -1 +1 @@
|
||||
Demo.CONFIG = Demo.LAYOUT_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG); |
||||
Demo.CONFIG = Demo.LAYOUT_CONFIG.concat(Demo.BASE_CONFIG).concat(Demo.CASE_CONFIG).concat(Demo.WIDGET_CONFIG).concat(Demo.COMPONENT_CONFIG); |
@ -0,0 +1,39 @@
|
||||
Demo.TreeValueChooser = BI.inherit(BI.Widget, { |
||||
props: { |
||||
baseCls: "demo-tree-value-chooser" |
||||
}, |
||||
render: function () { |
||||
|
||||
var tree = []; |
||||
for (var i = 0; i < 21; 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", |
||||
items: tree, |
||||
itemsCreator: function (op, callback) { |
||||
callback(tree); |
||||
} |
||||
}); |
||||
return { |
||||
type: "bi.vertical", |
||||
hgap: 200, |
||||
vgap: 10, |
||||
items: [widget] |
||||
}; |
||||
} |
||||
}); |
||||
$.shortcut("demo.tree_value_chooser", Demo.TreeValueChooser); |
@ -0,0 +1,15 @@
|
||||
/** |
||||
* Created by User on 2017/3/22. |
||||
*/ |
||||
Demo.COMPONENT_CONFIG = [{ |
||||
id: 15, |
||||
text: "部件" |
||||
}, { |
||||
pId: 15, |
||||
text: "bi.value_chooser_combo", |
||||
value: "demo.value_chooser_combo" |
||||
}, { |
||||
pId: 15, |
||||
text: "bi.tree_value_chooser_combo", |
||||
value: "demo.tree_value_chooser" |
||||
}]; |
@ -1,14 +0,0 @@
|
||||
/** |
||||
* Created by User on 2017/3/22. |
||||
*/ |
||||
Demo.MultiSelectTree = BI.inherit(BI.Widget, { |
||||
props: { |
||||
baseCls: "demo-multi-select-tree" |
||||
}, |
||||
render: function () { |
||||
return { |
||||
type: "bi.vertical", |
||||
} |
||||
} |
||||
}); |
||||
$.shortcut("demo.multi_select_tree", Demo.MultiSelectTree); |
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 45 B After Width: | Height: | Size: 45 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,599 @@
|
||||
/** |
||||
* 简单的复选下拉树控件, 适用于数据量少的情况 |
||||
* |
||||
* Created by GUY on 2015/10/29. |
||||
* @class BI.TreeValueChooserCombo |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.TreeValueChooserCombo = BI.inherit(BI.Widget, { |
||||
|
||||
_const: { |
||||
perPage: 10 |
||||
}, |
||||
|
||||
_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.element, |
||||
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); |
||||
}); |
||||
}, |
||||
|
||||
_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_CALCULATE_SELECT_DATA: |
||||
self._reqSelectedTreeNode(options, callback); |
||||
break; |
||||
case BI.TreeView.REQ_TYPE_SELECTED_DATA: |
||||
self._reqDisplayTreeNode(options, callback); |
||||
break; |
||||
default : |
||||
self._reqTreeNode(options, callback); |
||||
break; |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_reqDisplayTreeNode: function (op, callback) { |
||||
var self = this; |
||||
var result = []; |
||||
var selected_values = op.selected_values; |
||||
|
||||
if (selected_values == null || BI.isEmpty(selected_values)) { |
||||
callback({}); |
||||
return; |
||||
} |
||||
|
||||
doCheck(0, [], selected_values); |
||||
|
||||
callback({ |
||||
items: result |
||||
}); |
||||
|
||||
function doCheck(floor, parent_values, selected) { |
||||
if (floor >= self.floors) { |
||||
return; |
||||
} |
||||
if (selected == null || BI.isEmpty(selected)) { |
||||
var children = self._getChildren(parent_values); |
||||
BI.each(children, function (i, child) { |
||||
var newParents = BI.clone(parent_values); |
||||
newParents.push(child.value); |
||||
var llen = self._getChildCount(newParents); |
||||
createOneJson(child, llen); |
||||
doCheck(floor + 1, newParents, {}); |
||||
}); |
||||
return; |
||||
} |
||||
BI.each(selected, function (k) { |
||||
var node = self._getNode(k); |
||||
var newParents = BI.clone(parent_values); |
||||
newParents.push(node.value); |
||||
createOneJson(node, getCount(selected[k], newParents)); |
||||
doCheck(floor + 1, newParents, selected[k]); |
||||
}) |
||||
} |
||||
|
||||
function getCount(jo, parent_values) { |
||||
if (jo == null) { |
||||
return 0; |
||||
} |
||||
if (BI.isEmpty(jo)) { |
||||
return self._getChildCount(parent_values); |
||||
} |
||||
|
||||
return BI.size(jo); |
||||
} |
||||
|
||||
function createOneJson(node, llen) { |
||||
result.push({ |
||||
id: node.id, |
||||
pId: node.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 selected_values = op.selected_values; |
||||
var not_selected_value = op.not_selected_value || {}; |
||||
var keyword = op.keyword || ""; |
||||
var parent_values = op.parent_values || []; |
||||
|
||||
if (selected_values == null || BI.isEmpty(selected_values)) { |
||||
callback({}); |
||||
return; |
||||
} |
||||
|
||||
dealWithSelectedValues(selected_values); |
||||
callback(selected_values); |
||||
|
||||
|
||||
function dealWithSelectedValues(selected_values) { |
||||
var p = BI.clone(parent_values); |
||||
p.push(not_selected_value); |
||||
|
||||
if (isChild(selected_values, p)) { |
||||
var result = []; |
||||
var finded = search(parent_values.length + 1, parent_values, not_selected_value, result); |
||||
|
||||
if (finded === true) { |
||||
var next = selected_values; |
||||
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 === not_selected_value) { |
||||
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(selected_values, 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(selected_values, parents) { |
||||
var t = selected_values; |
||||
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 selected_values = op.selected_values; |
||||
if (selected_values == null || BI.isEmpty(selected_values)) { |
||||
callback({}); |
||||
return; |
||||
} |
||||
BI.each(selected_values, function (k, v) { |
||||
result.push([k]); |
||||
}); |
||||
|
||||
dealWithSelectedValues(selected_values, []); |
||||
|
||||
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 selected_values = op.selected_values; |
||||
var last_search_value = op.last_search_value || ""; |
||||
var output = search(); |
||||
BI.nextTick(function () { |
||||
callback({ |
||||
hasNext: output.length > self._const.perPage, |
||||
items: result, |
||||
last_search_value: BI.last(output) |
||||
}) |
||||
}); |
||||
|
||||
function search() { |
||||
var children = self._getChildren([]); |
||||
var start = children.length; |
||||
if (last_search_value !== "") { |
||||
for (var j = 0, len = start; j < len; j++) { |
||||
if (children[j].value === last_search_value) { |
||||
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, parent_values, current, isAllSelect, result) { |
||||
if (self._isMatch(current, keyword)) { |
||||
var checked = isAllSelect || isSelected(parent_values, current); |
||||
createOneJson(parent_values, current, false, checked, !isAllSelect && isHalf(parent_values, current), true, result); |
||||
return [true, checked]; |
||||
} |
||||
if (deep >= self.floors) { |
||||
return [false, false]; |
||||
} |
||||
var newParents = BI.clone(parent_values); |
||||
newParents.push(current); |
||||
var children = self._getChildren(newParents); |
||||
|
||||
var can = false, checked = false; |
||||
|
||||
var isCurAllSelected = isAllSelect || isAllSelected(parent_values, 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(parent_values, current) && checked); |
||||
createOneJson(parent_values, current, true, checked, false, false, result); |
||||
} |
||||
return [can, checked]; |
||||
} |
||||
|
||||
function createOneJson(parent_values, 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: parent_values.length + 1 < self.floors, |
||||
open: isOpen, |
||||
checked: checked, |
||||
halfCheck: half, |
||||
flag: flag |
||||
}); |
||||
} |
||||
|
||||
function isHalf(parent_values, value) { |
||||
var find = findSelectedObj(parent_values); |
||||
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(parent_values, value) { |
||||
var find = findSelectedObj(parent_values); |
||||
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(parent_values, value) { |
||||
var find = findSelectedObj(parent_values); |
||||
if (find == null) { |
||||
return false; |
||||
} |
||||
return BI.any(find, function (v) { |
||||
if (v === value) { |
||||
return true; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
function findSelectedObj(parent_values) { |
||||
var find = selected_values; |
||||
if (find == null) { |
||||
return null; |
||||
} |
||||
BI.every(parent_values, 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 check_state = op.check_state || {}; |
||||
var parent_values = op.parent_values || []; |
||||
var selected_values = op.selected_values; |
||||
var valueMap = {}; |
||||
if (judgeState(parent_values, selected_values, check_state)) { |
||||
valueMap = dealWidthSelectedValue(parent_values, selected_values); |
||||
} |
||||
var nodes = this._getChildren(parent_values); |
||||
for (var i = (times - 1) * this._const.perPage; nodes[i] && i < times * this._const.perPage; i++) { |
||||
var state = getCheckState(nodes[i].value, parent_values, valueMap, check_state); |
||||
result.push({ |
||||
id: nodes[i].id, |
||||
pId: nodes[i].pId, |
||||
value: nodes[i].value, |
||||
text: nodes[i].text, |
||||
times: 1, |
||||
isParent: parent_values.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(parent_values, selected_value, check_state) { |
||||
var checked = check_state.checked, half = check_state.half; |
||||
if (parent_values.length > 0 && !checked) { |
||||
return false; |
||||
} |
||||
return (parent_values.length === 0 || (checked && half) && !BI.isEmpty(selected_value)); |
||||
} |
||||
|
||||
function dealWidthSelectedValue(parent_values, selected_values) { |
||||
var valueMap = {}; |
||||
BI.each(parent_values, function (i, v) { |
||||
selected_values = selected_values[v]; |
||||
}); |
||||
BI.each(selected_values, 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, parent_values, valueMap, check_state) { |
||||
var checked = check_state.checked, half = check_state.half; |
||||
var hasChild = parent_values.length + 1 < self.floors; |
||||
var tempCheck = false, halfCheck = false; |
||||
if (BI.has(valueMap, current)) { |
||||
//可能是半选
|
||||
if (valueMap[current][0] === 1) { |
||||
var values = BI.clone(parent_values); |
||||
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 (parent_values) { |
||||
if (parent_values.length > 0) { |
||||
var value = BI.last(parent_values); |
||||
var parent = this.tree.search(value, "value"); |
||||
} else { |
||||
var parent = this.tree.getRoot(); |
||||
} |
||||
return parent.getChildren(); |
||||
}, |
||||
|
||||
_getChildCount: function (parent_values) { |
||||
return this._getChildren(parent_values).length; |
||||
}, |
||||
|
||||
setValue: function (v) { |
||||
this.combo.setValue(v); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
return this.combo.getValue(); |
||||
}, |
||||
|
||||
populate: function () { |
||||
this.combo.populate.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.TreeValueChooserCombo.EVENT_CONFIRM = "TreeValueChooserCombo.EVENT_CONFIRM"; |
||||
$.shortcut('bi.tree_value_chooser_combo', BI.TreeValueChooserCombo); |
@ -0,0 +1,127 @@
|
||||
/** |
||||
* 简单的复选下拉框控件, 适用于数据量少的情况 |
||||
* 封装了字段处理逻辑 |
||||
* |
||||
* Created by GUY on 2015/10/29. |
||||
* @class BI.ValueChooserCombo |
||||
* @extends BI.Widget |
||||
*/ |
||||
BI.ValueChooserCombo = BI.inherit(BI.Widget, { |
||||
|
||||
_const: { |
||||
perPage: 10 |
||||
}, |
||||
_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.element, |
||||
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; |
||||
}, |
||||
width: o.width, |
||||
height: o.height |
||||
}); |
||||
|
||||
this.combo.on(BI.MultiSelectCombo.EVENT_CONFIRM, function () { |
||||
self.fireEvent(BI.ValueChooserCombo.EVENT_CONFIRM); |
||||
}); |
||||
}, |
||||
|
||||
_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.selected_values) {//过滤
|
||||
var filter = BI.makeObject(options.selected_values, 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); |
||||
}, |
||||
|
||||
getValue: function () { |
||||
var val = this.combo.getValue() || {}; |
||||
return { |
||||
type: val.type, |
||||
value: val.value |
||||
} |
||||
}, |
||||
|
||||
populate: function () { |
||||
this.combo.populate.apply(this, arguments); |
||||
} |
||||
}); |
||||
BI.ValueChooserCombo.EVENT_CONFIRM = "ValueChooserCombo.EVENT_CONFIRM"; |
||||
$.shortcut('bi.value_chooser_combo', BI.ValueChooserCombo); |
@ -0,0 +1,591 @@
|
||||
BI.cjkEncode = function (text) { |
||||
// alex:如果非字符串,返回其本身(cjkEncode(234) 返回 ""是不对的)
|
||||
if (typeof text !== 'string') { |
||||
return text; |
||||
} |
||||
|
||||
var newText = ""; |
||||
for (var i = 0; i < text.length; i++) { |
||||
var code = text.charCodeAt(i); |
||||
if (code >= 128 || code === 91 || code === 93) {//91 is "[", 93 is "]".
|
||||
newText += "[" + code.toString(16) + "]"; |
||||
} else { |
||||
newText += text.charAt(i); |
||||
} |
||||
} |
||||
|
||||
return newText |
||||
}; |
||||
|
||||
BI.cjkEncodeDO = function (o) { |
||||
if (BI.isPlainObject(o)) { |
||||
var result = {}; |
||||
$.each(o, function (k, v) { |
||||
if (!(typeof v == "string")) { |
||||
v = BI.jsonEncode(v); |
||||
} |
||||
//wei:bug 43338,如果key是中文,cjkencode后o的长度就加了1,ie9以下版本死循环,所以新建对象result。
|
||||
k = BI.cjkEncode(k); |
||||
result[k] = BI.cjkEncode(v); |
||||
}); |
||||
return result; |
||||
} |
||||
return o; |
||||
}; |
||||
|
||||
BI.jsonEncode = function (o) { |
||||
//james:这个Encode是抄的EXT的
|
||||
var useHasOwn = {}.hasOwnProperty ? true : false; |
||||
|
||||
// crashes Safari in some instances
|
||||
//var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/;
|
||||
|
||||
var m = { |
||||
"\b": '\\b', |
||||
"\t": '\\t', |
||||
"\n": '\\n', |
||||
"\f": '\\f', |
||||
"\r": '\\r', |
||||
'"': '\\"', |
||||
"\\": '\\\\' |
||||
}; |
||||
|
||||
var encodeString = function (s) { |
||||
if (/["\\\x00-\x1f]/.test(s)) { |
||||
return '"' + s.replace(/([\x00-\x1f\\"])/g, function (a, b) { |
||||
var c = m[b]; |
||||
if (c) { |
||||
return c; |
||||
} |
||||
c = b.charCodeAt(); |
||||
return "\\u00" + |
||||
Math.floor(c / 16).toString(16) + |
||||
(c % 16).toString(16); |
||||
}) + '"'; |
||||
} |
||||
return '"' + s + '"'; |
||||
}; |
||||
|
||||
var encodeArray = function (o) { |
||||
var a = ["["], b, i, l = o.length, v; |
||||
for (i = 0; i < l; i += 1) { |
||||
v = o[i]; |
||||
switch (typeof v) { |
||||
case "undefined": |
||||
case "function": |
||||
case "unknown": |
||||
break; |
||||
default: |
||||
if (b) { |
||||
a.push(','); |
||||
} |
||||
a.push(v === null ? "null" : BI.jsonEncode(v)); |
||||
b = true; |
||||
} |
||||
} |
||||
a.push("]"); |
||||
return a.join(""); |
||||
}; |
||||
|
||||
if (typeof o == "undefined" || o === null) { |
||||
return "null"; |
||||
} else if (BI.isArray(o)) { |
||||
return encodeArray(o); |
||||
} else if (o instanceof Date) { |
||||
/* |
||||
* alex:原来只是把年月日时分秒简单地拼成一个String,无法decode |
||||
* 现在这么处理就可以decode了,但是JS.jsonDecode和Java.JSONObject也要跟着改一下 |
||||
*/ |
||||
return BI.jsonEncode({ |
||||
__time__: o.getTime() |
||||
}) |
||||
} else if (typeof o == "string") { |
||||
return encodeString(o); |
||||
} else if (typeof o == "number") { |
||||
return isFinite(o) ? String(o) : "null"; |
||||
} else if (typeof o == "boolean") { |
||||
return String(o); |
||||
} else if (BI.isFunction(o)) { |
||||
return String(o); |
||||
} else { |
||||
var a = ["{"], b, i, v; |
||||
for (i in o) { |
||||
if (!useHasOwn || o.hasOwnProperty(i)) { |
||||
v = o[i]; |
||||
switch (typeof v) { |
||||
case "undefined": |
||||
case "unknown": |
||||
break; |
||||
default: |
||||
if (b) { |
||||
a.push(','); |
||||
} |
||||
a.push(BI.jsonEncode(i), ":", |
||||
v === null ? "null" : BI.jsonEncode(v)); |
||||
b = true; |
||||
} |
||||
} |
||||
} |
||||
a.push("}"); |
||||
return a.join(""); |
||||
} |
||||
}; |
||||
|
||||
BI.contentFormat = function (cv, fmt) { |
||||
if (BI.isEmpty(cv)) { |
||||
//原值为空,返回空字符
|
||||
return ''; |
||||
} |
||||
var text = cv.toString(); |
||||
if (BI.isEmpty(fmt)) { |
||||
//格式为空,返回原字符
|
||||
return text; |
||||
} |
||||
if (fmt.match(/^T/)) { |
||||
//T - 文本格式
|
||||
return text; |
||||
} else if (fmt.match(/^D/)) { |
||||
//D - 日期(时间)格式
|
||||
if (!(cv instanceof Date)) { |
||||
if (typeof cv === 'number') { |
||||
//毫秒数类型
|
||||
cv = new Date(cv); |
||||
} else { |
||||
//字符串类型,如yyyyMMdd、MMddyyyy等这样无分隔符的结构
|
||||
cv = Date.parseDate(cv + "", Date.patterns.ISO8601Long); |
||||
} |
||||
} |
||||
if (!BI.isNull(cv)) { |
||||
var needTrim = fmt.match(/^DT/); |
||||
text = BI.date2Str(cv, fmt.substring(needTrim ? 2 : 1)); |
||||
} |
||||
} else if (fmt.match(/E/)) { |
||||
//科学计数格式
|
||||
text = BI._eFormat(text, fmt); |
||||
} else { |
||||
//数字格式
|
||||
text = BI._numberFormat(text, fmt); |
||||
} |
||||
//¤ - 货币格式
|
||||
text = text.replace(/¤/g, '¥'); |
||||
return text; |
||||
}; |
||||
|
||||
/** |
||||
* 把日期对象按照指定格式转化成字符串 |
||||
* |
||||
* @example |
||||
* var date = new Date('Thu Dec 12 2013 00:00:00 GMT+0800'); |
||||
* var result = BI.date2Str(date, 'yyyy-MM-dd');//2013-12-12
|
||||
* |
||||
* @class BI.date2Str |
||||
* @param date 日期 |
||||
* @param format 日期格式 |
||||
* @returns {String} |
||||
*/ |
||||
date2Str = function (date, format) { |
||||
if (!date) { |
||||
return ''; |
||||
} |
||||
// O(len(format))
|
||||
var len = format.length, result = ''; |
||||
if (len > 0) { |
||||
var flagch = format.charAt(0), start = 0, str = flagch; |
||||
for (var i = 1; i < len; i++) { |
||||
var ch = format.charAt(i); |
||||
if (flagch !== ch) { |
||||
result += compileJFmt({ |
||||
'char': flagch, |
||||
'str': str, |
||||
'len': i - start |
||||
}, date); |
||||
flagch = ch; |
||||
start = i; |
||||
str = flagch; |
||||
} else { |
||||
str += ch; |
||||
} |
||||
} |
||||
result += compileJFmt({ |
||||
'char': flagch, |
||||
'str': str, |
||||
'len': len - start |
||||
}, date); |
||||
} |
||||
return result; |
||||
|
||||
function compileJFmt(jfmt, date) { |
||||
var str = jfmt.str, len = jfmt.len, ch = jfmt['char']; |
||||
switch (ch) { |
||||
case 'E': //星期
|
||||
str = Date._DN[date.getDay()]; |
||||
break; |
||||
case 'y': //年
|
||||
if (len <= 3) { |
||||
str = (date.getFullYear() + '').slice(2, 4); |
||||
} else { |
||||
str = date.getFullYear(); |
||||
} |
||||
break; |
||||
case 'M': //月
|
||||
if (len > 2) { |
||||
str = Date._MN[date.getMonth()]; |
||||
} else if (len < 2) { |
||||
str = date.getMonth() + 1; |
||||
} else { |
||||
str = String.leftPad(date.getMonth() + 1 + '', 2, '0'); |
||||
} |
||||
break; |
||||
case 'd': //日
|
||||
if (len > 1) { |
||||
str = String.leftPad(date.getDate() + '', 2, '0'); |
||||
} else { |
||||
str = date.getDate(); |
||||
} |
||||
break; |
||||
case 'h': //时(12)
|
||||
var hour = date.getHours() % 12; |
||||
if (hour === 0) { |
||||
hour = 12; |
||||
} |
||||
if (len > 1) { |
||||
str = String.leftPad(hour + '', 2, '0'); |
||||
} else { |
||||
str = hour; |
||||
} |
||||
break; |
||||
case 'H': //时(24)
|
||||
if (len > 1) { |
||||
str = String.leftPad(date.getHours() + '', 2, '0'); |
||||
} else { |
||||
str = date.getHours(); |
||||
} |
||||
break; |
||||
case 'm': |
||||
if (len > 1) { |
||||
str = String.leftPad(date.getMinutes() + '', 2, '0'); |
||||
} else { |
||||
str = date.getMinutes(); |
||||
} |
||||
break; |
||||
case 's': |
||||
if (len > 1) { |
||||
str = String.leftPad(date.getSeconds() + '', 2, '0'); |
||||
} else { |
||||
str = date.getSeconds(); |
||||
} |
||||
break; |
||||
case 'a': |
||||
str = date.getHours() < 12 ? 'am' : 'pm'; |
||||
break; |
||||
case 'z': |
||||
str = date.getTimezone(); |
||||
break; |
||||
default: |
||||
str = jfmt.str; |
||||
break; |
||||
} |
||||
return str; |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 数字格式 |
||||
*/ |
||||
BI._numberFormat = function (text, format) { |
||||
var text = text + ''; |
||||
//数字格式,区分正负数
|
||||
var numMod = format.indexOf(';'); |
||||
if (numMod > -1) { |
||||
if (text >= 0) { |
||||
return BI._numberFormat(text + "", format.substring(0, numMod)); |
||||
} else { |
||||
return BI._numberFormat((-text) + "", format.substr(numMod + 1)); |
||||
} |
||||
} |
||||
var tp = text.split('.'), fp = format.split('.'), |
||||
tleft = tp[0] || '', fleft = fp[0] || '', |
||||
tright = tp[1] || '', fright = fp[1] || ''; |
||||
//百分比,千分比的小数点移位处理
|
||||
if (/[%‰]$/.test(format)) { |
||||
var paddingZero = /[%]$/.test(format) ? '00' : '000'; |
||||
tright += paddingZero; |
||||
tleft += tright.substr(0, paddingZero.length); |
||||
tleft = tleft.replace(/^0+/gi, ''); |
||||
tright = tright.substr(paddingZero.length).replace(/0+$/gi, ''); |
||||
} |
||||
var right = BI._dealWithRight(tright, fright); |
||||
if (right.leftPlus) { |
||||
//小数点后有进位
|
||||
tleft = parseInt(tleft) + 1 + ''; |
||||
|
||||
tleft = isNaN(tleft) ? '1' : tleft; |
||||
} |
||||
right = right.num; |
||||
var left = BI._dealWithLeft(tleft, fleft); |
||||
if (!(/[0-9]/.test(left))) { |
||||
left = left + '0'; |
||||
} |
||||
if (!(/[0-9]/.test(right))) { |
||||
return left + right; |
||||
} else { |
||||
return left + '.' + right; |
||||
} |
||||
}; |
||||
/** |
||||
* 处理小数点右边小数部分 |
||||
* @param tright 右边内容 |
||||
* @param fright 右边格式 |
||||
* @returns {JSON} 返回处理结果和整数部分是否需要进位 |
||||
* @private |
||||
*/ |
||||
BI._dealWithRight = function (tright, fright) { |
||||
var right = '', j = 0, i = 0; |
||||
for (var len = fright.length; i < len; i++) { |
||||
var ch = fright.charAt(i); |
||||
var c = tright.charAt(j); |
||||
switch (ch) { |
||||
case '0': |
||||
if (BI.isEmpty(c)) { |
||||
c = '0'; |
||||
} |
||||
right += c; |
||||
j++; |
||||
break; |
||||
case '#': |
||||
right += c; |
||||
j++; |
||||
break; |
||||
default : |
||||
right += ch; |
||||
break; |
||||
} |
||||
} |
||||
var rll = tright.substr(j); |
||||
var result = {}; |
||||
if (!BI.isEmpty(rll) && rll.charAt(0) > 4) { |
||||
//有多余字符,需要四舍五入
|
||||
result.leftPlus = true; |
||||
var numReg = right.match(/^[0-9]+/); |
||||
if (numReg) { |
||||
var num = numReg[0]; |
||||
var orilen = num.length; |
||||
var newnum = BI.parseINT(num) + 1 + ''; |
||||
//进位到整数部分
|
||||
if (newnum.length > orilen) { |
||||
newnum = newnum.substr(1); |
||||
} else { |
||||
newnum = BI.leftPad(newnum, orilen, '0'); |
||||
result.leftPlus = false; |
||||
} |
||||
right = right.replace(/^[0-9]+/, newnum); |
||||
} |
||||
} |
||||
result.num = right; |
||||
return result; |
||||
}; |
||||
|
||||
BI.parseINT = function (str) { |
||||
return parseInt(str, 10); |
||||
}; |
||||
|
||||
BI.leftPad = function (val, size, ch) { |
||||
var result = String(val); |
||||
if (!ch) { |
||||
ch = " "; |
||||
} |
||||
while (result.length < size) { |
||||
result = ch + result; |
||||
} |
||||
return result.toString(); |
||||
}; |
||||
|
||||
/** |
||||
* 处理小数点左边整数部分 |
||||
* @param tleft 左边内容 |
||||
* @param fleft 左边格式 |
||||
* @returns {string} 返回处理结果 |
||||
* @private |
||||
*/ |
||||
BI._dealWithLeft = function (tleft, fleft) { |
||||
var left = ''; |
||||
var j = tleft.length - 1; |
||||
var combo = -1, last = -1; |
||||
var i = fleft.length - 1; |
||||
for (; i >= 0; i--) { |
||||
var ch = fleft.charAt(i); |
||||
var c = tleft.charAt(j); |
||||
switch (ch) { |
||||
case '0': |
||||
if (BI.isEmpty(c)) { |
||||
c = '0'; |
||||
} |
||||
last = -1; |
||||
left = c + left; |
||||
j--; |
||||
break; |
||||
case '#': |
||||
last = i; |
||||
left = c + left; |
||||
j--; |
||||
break; |
||||
case ',': |
||||
if (!BI.isEmpty(c)) { |
||||
//计算一个,分隔区间的长度
|
||||
var com = fleft.match(/,[#0]+/); |
||||
if (com) { |
||||
combo = com[0].length - 1; |
||||
} |
||||
left = ',' + left; |
||||
} |
||||
break; |
||||
default : |
||||
left = ch + left; |
||||
break; |
||||
} |
||||
} |
||||
if (last > -1) { |
||||
//处理剩余字符
|
||||
var tll = tleft.substr(0, j + 1); |
||||
left = left.substr(0, last) + tll + left.substr(last); |
||||
} |
||||
if (combo > 0) { |
||||
//处理,分隔区间
|
||||
var res = left.match(/[0-9]+,/); |
||||
if (res) { |
||||
res = res[0]; |
||||
var newstr = '', n = res.length - 1 - combo; |
||||
for (; n >= 0; n = n - combo) { |
||||
newstr = res.substr(n, combo) + ',' + newstr; |
||||
} |
||||
var lres = res.substr(0, n + combo); |
||||
if (!BI.isEmpty(lres)) { |
||||
newstr = lres + ',' + newstr; |
||||
} |
||||
} |
||||
left = left.replace(/[0-9]+,/, newstr); |
||||
} |
||||
return left; |
||||
}; |
||||
|
||||
BI.object2Number = function (value) { |
||||
if (value == null) { |
||||
return 0; |
||||
} |
||||
if (typeof value == 'number') { |
||||
return value; |
||||
} else { |
||||
var str = value + ""; |
||||
if (str.indexOf(".") === -1) { |
||||
return parseInt(str); |
||||
} else { |
||||
return parseFloat(str); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
BI.object2Date = function (obj) { |
||||
if (obj == null) { |
||||
return new Date(); |
||||
} |
||||
if (obj instanceof Date) { |
||||
return obj; |
||||
} else if (typeof obj == 'number') { |
||||
return new Date(obj); |
||||
} else { |
||||
var str = obj + ""; |
||||
str = str.replace(/-/g, '/'); |
||||
var dt = new Date(str); |
||||
if (!BI.isInvalidDate(dt)) { |
||||
return dt; |
||||
} |
||||
|
||||
return new Date(); |
||||
} |
||||
}; |
||||
|
||||
BI.isArray = function (a) { |
||||
return Object.prototype.toString.call(a) == '[object Array]'; |
||||
}; |
||||
|
||||
BI.object2Time = function (obj) { |
||||
if (obj == null) { |
||||
return new Date(); |
||||
} |
||||
if (obj instanceof Date) { |
||||
return obj; |
||||
} else { |
||||
var str = obj + ""; |
||||
str = str.replace(/-/g, '/'); |
||||
var dt = new Date(str); |
||||
if (!BI.isInvalidDate(dt)) { |
||||
return dt; |
||||
} |
||||
if (str.indexOf('/') === -1 && str.indexOf(':') !== -1) { |
||||
dt = new Date("1970/01/01 " + str); |
||||
if (!BI.isInvalidDate(dt)) { |
||||
return dt; |
||||
} |
||||
} |
||||
dt = BI.str2Date(str, "HH:mm:ss"); |
||||
if (!BI.isInvalidDate(dt)) { |
||||
return dt; |
||||
} |
||||
return new Date(); |
||||
} |
||||
}; |
||||
|
||||
// 判断是否是无效的日期
|
||||
BI.isInvalidDate = function (date) { |
||||
return date == "Invalid Date" || date == "NaN"; |
||||
}; |
||||
|
||||
|
||||
/** |
||||
* 科学计数格式 |
||||
*/ |
||||
BI._eFormat = function (text, fmt) { |
||||
var e = fmt.indexOf("E"); |
||||
var eleft = fmt.substr(0, e), eright = fmt.substr(e + 1); |
||||
if (/^[0\.-]+$/.test(text)) { |
||||
text = BI._numberFormat(0.0, eleft) + 'E' + BI._numberFormat(0, eright) |
||||
} else { |
||||
var isNegative = text < 0; |
||||
if (isNegative) { |
||||
text = text.substr(1); |
||||
} |
||||
var elvl = (eleft.split('.')[0] || '').length; |
||||
var point = text.indexOf("."); |
||||
if (point < 0) { |
||||
point = text.length; |
||||
} |
||||
var i = 0; //第一个不为0的数的位置
|
||||
text = text.replace('.', ''); |
||||
for (var len = text.length; i < len; i++) { |
||||
var ech = text.charAt(i); |
||||
if (ech <= '9' && ech >= '1') { |
||||
break; |
||||
} |
||||
} |
||||
var right = point - i - elvl; |
||||
var left = text.substr(i, elvl); |
||||
var dis = i + elvl - text.length; |
||||
if (dis > 0) { |
||||
//末位补全0
|
||||
for (var k = 0; k < dis; k++) { |
||||
left += '0'; |
||||
} |
||||
} else { |
||||
left += '.' + text.substr(i + elvl); |
||||
} |
||||
left = left.replace(/^[0]+/, ''); |
||||
if (right < 0 && eright.indexOf('-') < 0) { |
||||
eright += ';-' + eright; |
||||
} |
||||
text = BI._numberFormat(left, eleft) + 'E' + BI._numberFormat(right, eright); |
||||
if (isNegative) { |
||||
text = '-' + text; |
||||
} |
||||
} |
||||
return text; |
||||
}; |