forked from fanruan/fineui
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
429 lines
11 KiB
429 lines
11 KiB
import { |
|
Selection, |
|
CenterLayout, |
|
shortcut, |
|
Widget, |
|
Controller, |
|
extend, |
|
createWidget, |
|
createWidgets, |
|
each, |
|
isFunction, |
|
isKey, |
|
isNotEmptyArray, |
|
createItems, |
|
isArray, |
|
remove, |
|
map, |
|
stripEL, |
|
makeArrayByArray, |
|
clone, |
|
deepClone, |
|
formatEL, |
|
isEmpty, |
|
concat, |
|
removeAt, |
|
deepContains, |
|
has, |
|
any, |
|
BehaviorFactory, |
|
Events |
|
} from "@/core"; |
|
import { TextButton } from "../single"; |
|
|
|
/** |
|
* Created by GUY on 2015/6/26. |
|
* @class ButtonGroup |
|
* @extends Widget |
|
*/ |
|
|
|
@shortcut() |
|
export class ButtonGroup extends Widget { |
|
static xtype = "bi.button_group"; |
|
|
|
static EVENT_CHANGE = "EVENT_CHANGE"; |
|
|
|
static CHOOSE_TYPE_SINGLE = Selection.Single; |
|
static CHOOSE_TYPE_MULTI = Selection.Multi; |
|
static CHOOSE_TYPE_ALL = Selection.All; |
|
static CHOOSE_TYPE_NONE = Selection.None; |
|
static CHOOSE_TYPE_DEFAULT = Selection.Default; |
|
|
|
_defaultConfig() { |
|
return extend(super._defaultConfig(...arguments), { |
|
baseCls: "bi-button-group", |
|
behaviors: {}, |
|
items: [], |
|
value: "", |
|
chooseType: Selection.Single, |
|
layouts: [ |
|
{ |
|
type: CenterLayout.xtype, |
|
hgap: 0, |
|
vgap: 0, |
|
} |
|
], |
|
}); |
|
} |
|
|
|
render() { |
|
const { behaviors: optionsBehaviors, items: optionsItems, value } = this.options; |
|
const behaviors = {}; |
|
each(optionsBehaviors, (key, rule) => { |
|
behaviors[key] = BehaviorFactory.createBehavior(key, { |
|
rule, |
|
}); |
|
}); |
|
this.behaviors = behaviors; |
|
const items = isFunction(optionsItems) |
|
? this.__watch(optionsItems, (context, newValue) => { |
|
this.populate(newValue); |
|
}) |
|
: optionsItems; |
|
this.populate(items); |
|
this.options.value = isFunction(value) |
|
? this.__watch(value, (context, newValue) => { |
|
this.setValue(newValue); |
|
}) |
|
: value; |
|
if (isKey(value) || isNotEmptyArray(value)) { |
|
this.setValue(value); |
|
} |
|
} |
|
|
|
_createBtns(items) { |
|
let btns; |
|
Widget.execWithContext(this, () => { |
|
btns = createWidgets( |
|
createItems(items, { |
|
type: TextButton.xtype, |
|
}) |
|
); |
|
}); |
|
|
|
return btns; |
|
} |
|
|
|
_btnsCreator(items) { |
|
const args = Array.prototype.slice.call(arguments); |
|
const { chooseType } = this.options; |
|
const buttons = this._createBtns(items); |
|
args[0] = buttons; |
|
|
|
each(this.behaviors, (i, behavior) => { |
|
behavior.doBehavior(...args); |
|
}); |
|
each(buttons, (i, btn) => { |
|
btn.on(Controller.EVENT_CHANGE, (...arg) => { |
|
const [type, value, obj] = arg; |
|
if (type === Events.CLICK) { |
|
switch (chooseType) { |
|
case ButtonGroup.CHOOSE_TYPE_SINGLE: |
|
this.setValue(btn.getValue()); |
|
break; |
|
case ButtonGroup.CHOOSE_TYPE_NONE: |
|
this.setValue([]); |
|
break; |
|
default: |
|
break; |
|
} |
|
this.fireEvent(Controller.EVENT_CHANGE, ...arg); |
|
this.fireEvent(ButtonGroup.EVENT_CHANGE, value, obj); |
|
} else { |
|
this.fireEvent(Controller.EVENT_CHANGE, ...arg); |
|
} |
|
}); |
|
btn.on(Events.DESTROY, () => { |
|
remove(this.buttons, btn); |
|
}); |
|
}); |
|
|
|
return buttons; |
|
} |
|
|
|
_packageBtns(btns) { |
|
const { layouts: optionsLayouts } = this.options; |
|
const layouts = isArray(optionsLayouts) ? optionsLayouts : [optionsLayouts]; |
|
for (let i = layouts.length - 1; i > 0; i--) { |
|
btns = map(btns, (k, it) => |
|
extend({}, layouts[i], { |
|
items: [ |
|
extend({}, layouts[i].el, { |
|
el: it, |
|
}) |
|
], |
|
}) |
|
); |
|
} |
|
|
|
return btns; |
|
} |
|
|
|
_packageSimpleItems(btns) { |
|
const { items } = this.options; |
|
|
|
return map(items, (i, item) => { |
|
if (stripEL(item) === item) { |
|
return btns[i]; |
|
} |
|
|
|
return extend({}, item, { |
|
el: btns[i], |
|
}); |
|
}); |
|
} |
|
|
|
_packageItems(items, packBtns) { |
|
return createItems(makeArrayByArray(items, {}), clone(packBtns)); |
|
} |
|
|
|
_packageLayout(items) { |
|
const { layouts } = this.options; |
|
const layout = deepClone(isArray(layouts) ? layouts[0] : layouts); |
|
|
|
let lay = formatEL(layout).el; |
|
while (lay && lay.items && !isEmpty(lay.items)) { |
|
lay = formatEL(lay.items[0]).el; |
|
} |
|
lay.items = items; |
|
|
|
return layout; |
|
} |
|
|
|
// 如果是一个简单的layout |
|
_isSimpleLayout() { |
|
const { layouts, items } = this.options; |
|
|
|
return isArray(layouts) ? layouts.length === 1 && !isArray(items[0]) : true; |
|
} |
|
|
|
doBehavior() { |
|
const args = Array.prototype.slice.call(arguments); |
|
args.unshift(this.buttons); |
|
each(this.behaviors, (i, behavior) => { |
|
behavior.doBehavior(...args); |
|
}); |
|
} |
|
|
|
prependItems(items) { |
|
const btns = this._btnsCreator(...arguments); |
|
this.buttons = concat(btns, this.buttons); |
|
|
|
if (this._isSimpleLayout() && this.layouts && this.layouts.prependItems) { |
|
this.layouts.prependItems(btns); |
|
|
|
return; |
|
} |
|
|
|
items = this._packageItems(items, this._packageBtns(btns)); |
|
this.layouts.prependItems(this._packageLayout(items).items); |
|
} |
|
|
|
addItems(items) { |
|
const btns = this._btnsCreator(...arguments); |
|
this.buttons = concat(this.buttons, btns); |
|
|
|
// 如果是一个简单的layout |
|
if (this._isSimpleLayout() && this.layouts && this.layouts.addItems) { |
|
this.layouts.addItems(btns); |
|
|
|
return; |
|
} |
|
|
|
items = this._packageItems(items, this._packageBtns(btns)); |
|
this.layouts.addItems(this._packageLayout(items).items); |
|
} |
|
|
|
removeItemAt(indexes) { |
|
removeAt(this.buttons, indexes); |
|
this.layouts.removeItemAt(indexes); |
|
} |
|
|
|
removeItems(values) { |
|
values = isArray(values) ? values : [values]; |
|
const deleted = []; |
|
each(this.buttons, (i, button) => { |
|
if (deepContains(values, button.getValue())) { |
|
deleted.push(i); |
|
} |
|
}); |
|
removeAt(this.buttons, deleted); |
|
this.layouts.removeItemAt(deleted); |
|
} |
|
|
|
populate(items) { |
|
items = items || []; |
|
this.empty(); |
|
this.options.items = items; |
|
|
|
this.buttons = this._btnsCreator(...arguments); |
|
if (this._isSimpleLayout()) { |
|
items = this._packageSimpleItems(this.buttons); |
|
} else { |
|
items = this._packageItems(items, this._packageBtns(this.buttons)); |
|
} |
|
|
|
this.layouts = createWidget(extend({ element: this }, this._packageLayout(items))); |
|
} |
|
|
|
setNotSelectedValue(v) { |
|
v = isArray(v) ? v : [v]; |
|
each(this.buttons, (i, item) => { |
|
if (deepContains(v, item.getValue())) { |
|
item.setSelected && item.setSelected(false); |
|
} else { |
|
item.setSelected && item.setSelected(true); |
|
} |
|
}); |
|
} |
|
|
|
setEnabledValue(v) { |
|
v = isArray(v) ? v : [v]; |
|
each(this.buttons, (i, item) => { |
|
if (deepContains(v, item.getValue())) { |
|
item.setEnable(true); |
|
} else { |
|
item.setEnable(false); |
|
} |
|
}); |
|
} |
|
|
|
setValue(v) { |
|
v = isArray(v) ? v : [v]; |
|
each(this.buttons, (i, item) => { |
|
if (deepContains(v, item.getValue())) { |
|
item.setSelected && item.setSelected(true); |
|
} else { |
|
item.setSelected && item.setSelected(false); |
|
} |
|
}); |
|
} |
|
|
|
setValueMap(map) { |
|
map = map || {}; |
|
each(this.buttons, (i, item) => { |
|
if (has(map, item.getValue())) { |
|
item.setSelected && item.setSelected(true); |
|
} else { |
|
item.setSelected && item.setSelected(false); |
|
} |
|
}); |
|
} |
|
|
|
setAllSelected(v) { |
|
each(this.getAllButtons(), (i, btn) => { |
|
(btn.setSelected || btn.setAllSelected).apply(btn, [v]); |
|
}); |
|
} |
|
|
|
getNotSelectedValue() { |
|
const v = []; |
|
each(this.buttons, (i, item) => { |
|
if (item.isEnabled() && !(item.isSelected && item.isSelected())) { |
|
v.push(item.getValue()); |
|
} |
|
}); |
|
|
|
return v; |
|
} |
|
|
|
getValue() { |
|
const v = []; |
|
each(this.buttons, (i, item) => { |
|
if (item.isEnabled() && item.isSelected && item.isSelected()) { |
|
v.push(item.getValue()); |
|
} |
|
}); |
|
|
|
return v; |
|
} |
|
|
|
getAllButtons() { |
|
return this.buttons; |
|
} |
|
|
|
getAllLeaves() { |
|
return this.buttons; |
|
} |
|
|
|
getSelectedButtons() { |
|
const btns = []; |
|
each(this.buttons, (i, item) => { |
|
if (item.isSelected && item.isSelected()) { |
|
btns.push(item); |
|
} |
|
}); |
|
|
|
return btns; |
|
} |
|
|
|
getNotSelectedButtons() { |
|
const btns = []; |
|
each(this.buttons, (i, item) => { |
|
if (item.isSelected && !item.isSelected()) { |
|
btns.push(item); |
|
} |
|
}); |
|
|
|
return btns; |
|
} |
|
|
|
getIndexByValue(value) { |
|
let index = -1; |
|
any(this.buttons, (i, item) => { |
|
if (item.isEnabled() && item.getValue() === value) { |
|
index = i; |
|
|
|
return true; |
|
} |
|
}); |
|
|
|
return index; |
|
} |
|
|
|
getNodeById(id) { |
|
let node; |
|
any(this.buttons, (i, item) => { |
|
if (item.isEnabled() && item.options.id === id) { |
|
node = item; |
|
|
|
return true; |
|
} |
|
}); |
|
|
|
return node; |
|
} |
|
|
|
getNodeByValue(value) { |
|
let node; |
|
any(this.buttons, (i, item) => { |
|
if (item.isEnabled() && item.getValue() === value) { |
|
node = item; |
|
|
|
return true; |
|
} |
|
}); |
|
|
|
return node; |
|
} |
|
|
|
/** |
|
* 滚动到指定的节点 |
|
*/ |
|
scrollToValue(value, scrollIntoViewOptions) { |
|
const node = this.getNodeByValue(value); |
|
if (node) { |
|
node.element[0].scrollIntoView(scrollIntoViewOptions); |
|
} |
|
} |
|
|
|
empty() { |
|
super.empty(arguments); |
|
this.options.items = []; |
|
} |
|
|
|
destroy() { |
|
super.destroy(arguments); |
|
this.options.items = []; |
|
} |
|
}
|
|
|