快速搭建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.
 
 
 

943 lines
36 KiB

!(function () {
/**
* 多层级单选树增加无效值时状态,使用BI.config覆盖原组件,只能调用一次
* 新增watermark参数,表示空默认值,不传默认值为请选择,注意不能替代text,只是为了跟text区分开,text现在包含空默认值和暂不可用值两种情况。
* value存在且不存在于items中,为无效值,文本框标红
* value不存在,text不为watermark时,为暂不可用值,文本框不变,去除水印
*/
BI.config("bi.multilayer_single_tree_combo", function (config) {
var ERROR_CLASS = "combo-error";
var WATERMARK_CLASS = "bi-water-mark";
var WATERMARK = "请选择";
/**
* 判断是否是有效值
* @param {Object} config
* @param {String} value setValue传入的值
* @returns {Boolean}
*/
function isValueValid (options, value) {
if (!BI.isObject(options)) {
return true;
}
value = value || options.value;
// null/undefined/空字符串作为空值
if (BI.isNull(value) || (value === "")) {
return true;
}
var items = options.items || [];
var itemIds = [];
// 获取id列表
BI.each(items, function (i, item) {
item && item.value && itemIds.push(item.value);
});
return BI.contains(itemIds, value);
}
/**
* 增加/去除标红className
* @param {Object} widget
* @param {String} value setValue传入的值
*/
function changeInvalidClassName (widget, value) {
if (!BI.isObject(widget)) {
return;
}
var combo = widget.combo;
var trigger = widget.textTrigger && widget.textTrigger.trigger && widget.textTrigger.trigger.trigger && widget.textTrigger.trigger.trigger.text && widget.textTrigger.trigger.trigger.text.element;
var options = widget.options;
var watermark = options.watermark || WATERMARK;
if (isValueValid(options, value)) {
combo && combo.element.removeClass(ERROR_CLASS);
} else {
combo && combo.element.addClass(ERROR_CLASS);
}
if (options.text !== watermark) {
trigger.removeClass(WATERMARK_CLASS);
}
}
config.listeners = config.listeners || [];
// 新增mount生命周期回调
config.listeners.push({
eventName: BI.Events.MOUNT,
action: function () {
// 覆盖原setValue方法,调用原setValue前,修改样式
var _setValue = this.setValue;
this.setValue = function (value) {
_setValue.call(this, value);
changeInvalidClassName(this, value && value[0]);
};
// 立即触发一次样式变更,不需要传value
changeInvalidClassName(this);
}
});
return config;
});
var treeItems = [
{id: -1, pId: -2, value: "根目录", text: "根目录"},
{id: 1, pId: -1, value: "第一级目录1", text: "第一级目录1"},
{id: 11, pId: 1, value: "第二级文件1", text: "第二级文件1"},
{id: 12, pId: 1, value: "第二级目录2", text: "第二级目录2"},
{id: 121, pId: 12, value: "第三级目录1", text: "第三级目录1"},
{id: 122, pId: 12, value: "第三级文件1", text: "第三级文件1"},
{id: 1211, pId: 121, value: "第四级目录1", text: "第四级目录1"},
{id: 12111, pId: 1211, value: "第五级文件1", text: "第五级文件111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"},
{id: 2, pId: -1, value: "第一级目录2", text: "第一级目录2"},
{id: 21, pId: 2, value: "第二级目录3", text: "第二级目录3"},
{id: 22, pId: 2, value: "第二级文件2", text: "第二级文件2"},
{id: 211, pId: 21, value: "第三级目录2", text: "第三级目录2"},
{id: 212, pId: 21, value: "第三级文件2", text: "第三级文件2"},
{id: 2111, pId: 211, value: "第四级文件1", text: "第四级文件1"}
];
var TestTreeModel = BI.inherit(Fix.Model, {
state: function () {
return {
items: BI.deepClone(treeItems),
value: "第三级文件1"
};
},
childContext: ["items"]
});
BI.model("dec.amiba.test.tree.model", TestTreeModel);
var TestTree = BI.inherit(BI.Widget, {
_store: function () {
return BI.Models.getModel("dec.amiba.test.tree.model");
},
props: {
baseCls: "fine-test-tree"
},
watch: {
items: function (items) {
console.log("items", items);
this.treeRef.populate(items);
},
value: function (v) {
console.log("value", v);
}
},
render: function () {
var self = this, o = this.options;
return {
type: "bi.vertical",
height: 150,
lgap: 20,
tgap: 20,
mounted: function () {
// 测试增加树节点
var m = self.model;
var newItems = [
{id: 3, pId: -1, value: "第三级目录1", text: "第三级目录1"},
{id: 31, pId: 3, value: "第三级文件1", text: "第三级文件1"}
];
m.items = m.items.concat(newItems);
// 测试修改value;
setTimeout(function () {
console.log("setValue");
self.treeRef.setValue("不存在的值");
}, 3000);
},
items: [
{
type: "bi.label",
textAlign: "left",
text: "叶子节点单选"
},
{
type: "bi.multilayer_single_tree_combo",
text: "无效值",
watermark: "请选择",
allowEdit: false,
items: self.model.items,
ref: function (ref) {
self.treeRef = ref;
},
width: 250,
value: self.model.value,
listeners: [{
eventName: "EVENT_CHANGE",
action: function () {
self.model.value = self.treeRef.getValue()[0];
}
}]
}
]
};
}
});
BI.shortcut("dec.amiba.test.tree", TestTree);
})();!(function() {
/**
* 顶部组件,提供输入框添加todo项目
* 布局: bi.horizontal_auto 实现水平居中. bi.left_right_vertical_adapt 实现标题是输入框的靠左靠右垂直居中
*/
var ToDoListHeader = BI.inherit(BI.Widget, {
props: {
// 指定组件的className
baseCls: "my-todolist-header"
},
render: function() {
var self = this, o = this.options;
return {
type: "bi.horizontal_auto", // 水平居中布局
items: [
{
el: {
type: "bi.left_right_vertical_adapt", // 左右垂直居中布局
width: 600,
height: o.height,
items: {
left: [
{
el: {
type: "bi.label",
cls: "my-todolist-title",
text: "FineUI ToDoList",
height: o.height
}
}
],
right: [
{
el: {
type: "bi.editor",
ref: function(_ref) {
self.editor = _ref;
},
allowBlank: true,
cls: "my-todolist-header-editor",
watermark: "添加ToDo",
width: 300,
height: 24,
listeners: [
{ // 监听bi.editor 组件的"EVENT_ENTER"事件(即敲回车),触发事件ToDoListHeader.EVENT_ADD事件并将输入框值置空
eventName: "EVENT_ENTER",
action: function() {
// 注意:在这里this指向的是bi.editor的实例.通过bi.editor的getValue()方法获取输入框输入值.
self.fireEvent(ToDoListHeader.EVENT_ADD, this.getValue());
self.editor.setValue("");
}
}
]
}
}
]
}
}
}
]
};
}
});
ToDoListHeader.EVENT_ADD = "EVENT_ADD";
BI.shortcut("my.todolist.header", ToDoListHeader);
})();!(function() {
/**
* todo项列表
*
*/
var List = BI.inherit(BI.Widget, {
props: {
// 指定组件的className
baseCls: "my-todolist-list",
text: "正在进行"
},
render: function() {
var self = this, o = this.options;
return {
type: "bi.vertical",
items: [
{
el: {
type: "bi.vertical_adapt",
height: 40,
items: [
{
type: "bi.label",
cls: "my-todolist-list-text",
textAlign: "left",
text: o.text,
width: 580
}, {
type: "bi.center_adapt",
cls: "my-todolist-list-count-container",
width: 20,
height: 20,
items: [
{
el: {
type: "bi.label",
ref: function(_ref) {
self.count = _ref;
},
text: "0"
}
}
]
}
]
}
}, { // 用bi.vertical布局作为列表项的容器.
type: "bi.vertical",
vgap: 10,
ref: function(_ref) {
self.list = _ref;
},
items: this._createItems(o.items)
}
]
};
},
_createItems: function(items) {
var self = this;
return BI.map(items, function(index, item) {
return BI.extend(item, {
type: "bi.multi_select_item", // 节点采用复选节点展示
selected: item.done, // 已完成的todo项置为选中状态
disabled: item.done, // 已完成的todo项置为灰化状态
listeners: [
{ // 为每个todo项添加"EVENT_CHANGE"事件监听,触发组件自身"EVENT_CHANGE"事件
eventName: "EVENT_CHANGE",
action: function(v) {
self.fireEvent("EVENT_CHANGE", v);
}
}
]
});
});
},
_setCount: function(count) {
this.count.setText(count);
},
populate: function(items) {
this.list.populate(this._createItems(items));
this._setCount(items.length);
}
});
BI.shortcut("my.todolist.list", List);
})();!(function() {
/**
* todolist 组件
*/
var ToDoList = BI.inherit(BI.Widget, {
props: {
baseCls: "fine-to-do-list"
},
// 生命周期函数,在组件创建前
beforeCreate: function() {
// 初始化存储数据
this.list = localStorage.getItem("fine-todolist") ? JSON.parse(localStorage.getItem("fine-todolist")) : [];
},
render: function() {
var self = this, o = this.options;
return {
type: "bi.vtape", // vtape布局,顶部高度固定,下部分列表占满高度
items: [
{
el: {
type: "my.todolist.header", // 顶部组件
listeners: [
{ // 监听组件的EVENT_ADD事件,新建todo项
eventName: "EVENT_ADD",
action: function(v) {
self.addToDo(v);
}
}
],
height: 40
},
height: 40
}, {
type: "bi.horizontal_auto", // 水平居中布局
cls: "my-todolist-background", // 添加className
items: [
{
el: {
type: "my.todolist.list", // need todo项列表
ref: function(_ref) {
self.todolist = _ref;
},
items: this._getNeedTodoList(),
text: "正在进行",
listeners: [
{ // 监听EVENT_CHANGE事件,完成某一项todo
eventName: "EVENT_CHANGE",
action: function(v) {
self.finishTodo(v);
}
}
],
width: 600
}
}, {
el: {
type: "my.todolist.list", // 已经完成的todo项列表
text: "已经完成",
items: this._getAlreadyDoneList(),
ref: function(_ref) {
self.donelist = _ref;
},
width: 600
}
}
]
}
]
};
},
_updateLocalStorage: function() {
localStorage.setItem("fine-todolist", JSON.stringify(this.list));
},
_getNeedTodoList: function() {
return BI.filter(this.list, function(index, item) {
return !item.done;
});
},
_getAlreadyDoneList: function() {
return BI.filter(this.list, function(index, item) {
return item.done;
});
},
/**
* 添加todo项
* @param text todo项的内容
*/
addToDo: function(text) {
this.list.push({
value: BI.UUID(),
text: text,
done: false
});
this.todolist.populate(this._getNeedTodoList());
this._updateLocalStorage();
},
/**
* 完成某一项todo
* @param v todo项的value
*/
finishTodo: function(v) {
BI.some(this.list, function(index, item) {
if (item.value === v) {
item.done = true;
}
});
this.todolist.populate(this._getNeedTodoList());
this.donelist.populate(this._getAlreadyDoneList());
this._updateLocalStorage();
}
});
BI.shortcut("my.todolist", ToDoList);
})();
!(function () {
var originData = {
label: [
// "a7ed634a-0b59-4392-b92d-93a408803287"
],
labels: [
{
dimension: {
id: "4ac8a4f8-5798-4c18-9cdf-9b1b9e7f9372",
name: "部门",
status: 1,
description: null,
createTime: "2022-03-29 15:44:36.114"
},
labels: [
{
id: "85253c00-268c-4c77-a87d-6c532853ff1d",
name: "研发",
description: null,
dimensionId: "4ac8a4f8-5798-4c18-9cdf-9b1b9e7f9372",
createTime: "2022-03-29 15:45:18.348"
},
{
id: "f18d4479-9220-43f5-a696-b408b59c75c0",
name: "行政",
description: null,
dimensionId: "4ac8a4f8-5798-4c18-9cdf-9b1b9e7f9372",
createTime: "2022-03-29 15:45:07.412"
},
{
id: "a7ed634a-0b59-4392-b92d-93a408803287",
name: "财务",
description: null,
dimensionId: "4ac8a4f8-5798-4c18-9cdf-9b1b9e7f9372",
createTime: "2022-03-29 15:45:12.398"
}
]
}
]
};
var TestTreeSingleChooserModel = BI.inherit(Fix.Model, {
state: function () {
// 所有标签
var rawDimension = [], defaultDimension = {};
BI.each(originData.labels, function (i, item) {
var temp = {
text: item.dimension.name,
value: item.dimension.id,
children: BI.isNotEmptyArray(item.labels) ? BI.sortBy(BI.map(item.labels, function (i, label) {
return {
text: label.name,
value: label.id
};
}), [function (item) {
return BI.makeFirstPY(item["name"]);
}]) : []
};
rawDimension.push(temp);
});
rawDimension = BI.sortBy(rawDimension, [function (item) {
return BI.makeFirstPY(item["text"]);
}]);
!BI.isEmpty(defaultDimension) && rawDimension.unshift(defaultDimension);
console.log("state --> labels", rawDimension);
console.log("state --> label", originData.label);
return {
labels: rawDimension,
label: originData.label
};
}
});
BI.model("dec.amiba.test.tree.single.chooser.model", TestTreeSingleChooserModel);
var TestTreeSingleChooser = BI.inherit(BI.Widget, {
_store: function () {
return BI.Models.getModel("dec.amiba.test.tree.single.chooser.model");
},
watch: {
labels: function (v) {
console.log("labels", v);
},
label: function (v) {
console.log("label", v);
}
},
mounted: function () {
var _this = this;
setTimeout(function () {
console.log("_this.dataLabelRef", _this.dataLabelRef);
_this.dataLabelRef.setValue(["a7ed634a-0b59-4392-b92d-93a408803287"]);
}, 3000);
},
render: function () {
var _this = this, o = this.options, m = this.model;
console.log("_this.label", _this);
return {
type: "bi.vertical",
height: 150,
lgap: 20,
tgap: 20,
mounted: function () {},
items: [
{
type: "bi.label",
textAlign: "left",
text: "层级单选下拉框"
},
{
type: "dec.amiba.components.tree.single.chooser.combo",
watermark: "请选择",
text: "无效值",
width: 300,
height: 32,
value: m.label,
items: m.labels,
ref: function (ref) {
_this.dataLabelRef = ref;
},
listeners: [{
eventName: "EVENT_CHANGE",
action: function (value) {
m.label = value;
}
}]
}
]
};
}
});
BI.shortcut("dec.amiba.test.tree.single.chooser", TestTreeSingleChooser);
})();!(function () {
/**
* 组件说明:
* - 只支持两级展开
* - 第二级只允许单选
*
* 可用方法:
* setValue([] or '')
* getValue() => []
* populate() 刷新items
*
* 内部事件:
* EVENT_CHANGE,参数:value
*/
var SingleChooserPopup = BI.inherit(BI.Widget, {
props: function () {
return {
items: [],
value: [],
itemHeight: 32
};
},
mounted: function () {
BI.each(this.refGroupList, function (index, refGroup) {
refGroup.ref.element.hide();
});
},
render: function () {
var o = this.options;
var _this = this;
return {
type: "bi.button_group",
items: this._createItems(o.items),
layouts: [{
type: "bi.vertical",
vgap: 5
}],
ref: function (ref) {
_this.btnGroupRef = ref;
}
};
},
populate: function (items) {
this.btnGroupRef.populate(this._createItems(items));
},
getValue: function () {
var value = [];
BI.each(this.refGroupList, function (index, ref) {
BI.any(ref.selectRefs, function (index, selectRef) {
return (!BI.isNull(selectRef) && selectRef.isSelected()) ? (value.push(selectRef.getValue()), true) : false;
});
});
return value;
},
setValue: function (value) {
value = BI.isArray(value) ? value : [value];
BI.each(this.refGroupList, function (index, ref) {
BI.each(ref.selectRefs, function (index, selectRef) {
!BI.isNull(selectRef) && selectRef.setSelected(BI.contains(value, selectRef.getValue()));
});
});
},
_createItems: function (items) {
var o = this.options;
var _this = this;
this.refGroupList = BI.map(items, function () {
return {
ref: null,
selectRefs: []
};
});
if (BI.isNotEmptyArray(items)) {
return BI.map(items, function (index, item) {
var triggerRef = null;
return {
type: "bi.vertical",
items: [{
type: "bi.basic_button",
render: function () {
return {
type: "bi.htape",
cls: "bi-list-item",
height: o.itemHeight,
items: [{
width: 16,
lgap: 10,
el: {
type: "bi.icon_label",
baseCls: "fold-font",
height: o.itemHeight,
ref: function (ref) {
triggerRef = ref;
}
}
}, {
width: "fill",
lgap: 5,
el: {
type: "bi.label",
height: o.itemHeight,
text: item.text,
textAlign: "left"
}
}]
};
},
listeners: [{
eventName: "BasicButton.EVENT_CHANGE",
action: function () {
triggerRef.element.toggleClass("unfold-font fold-font");
_this.refGroupList[index].ref.element.toggle();
}
}]
}, {
el: {
type: "bi.button_group",
chooseType: BI.Selection.Multi,
ref: function (ref) {
_this.refGroupList[index].ref = ref;
},
items: BI.map(item.children, function (idx, child) {
return {
type: "bi.multi_select_item",
css: {
paddingLeft: "40px"
},
cls: "bi-list-item-active",
ref: function (ref) {
_this.refGroupList[index].selectRefs[idx] = ref;
},
height: o.itemHeight,
value: child.value,
text: child.text,
textLgap: 5,
listeners: [{
eventName: "EVENT_CHANGE",
action: function () {
if (this.isSelected()) {
var self = this;
var ref = _this.refGroupList[index];
BI.each(ref.selectRefs, function (index, selectRef) {
if (self !== selectRef && selectRef.isSelected()) {
selectRef.setSelected(false);
}
});
}
_this.fireEvent("EVENT_CHANGE", _this.getValue());
}
}],
logic: {
dynamic: true
}
};
}),
layouts: [{
type: "bi.vertical"
}]
}
}]
};
});
}
return [{
type: "bi.label",
height: 25,
disabled: true,
text: BI.i18nText("Fine-Plugin_AMB_Component_No_Available_Select_Items")
}];
}
});
BI.shortcut("dec.amiba.components.single.chooser.popup", SingleChooserPopup);
/**
* value:
* [value, ...]
*
* items:
* [{
* text: '',
* value: '',
* children: [{
* text: '',
* value: ''
* }],
* ...
* }]
*/
var SingleChooserCombo = BI.inherit(BI.Widget, {
props: {
itemHeight: 32,
text: null, // 显示值,在显示值为无效值的情况下表现为水印样式
value: null, // 真实值,真实值为空的时候显示水印值
watermark: null, // 提示水印
baseCls: "dec-amiba-components-tree-single-chooser-combo"
},
mounted: function () {
var o = this.options;
this.setValue(o.value, true);
},
render: function () {
var o = this.options;
var _this = this;
return {
type: "bi.combo",
cls: "bi-border",
isDefaultInit: true,
adjustLength: 2,
el: {
type: "bi.text_trigger",
ref: function (ref) {
_this.triggerRef = ref;
},
height: o.height,
readonly: o.readonly,
tipType: o.tipType,
warningTitle: o.warningTitle
},
popup: {
maxHeight: 240,
minHeight: 25,
el: {
type: "bi.vertical",
items: [{
type: "dec.amiba.components.single.chooser.popup",
ref: function (ref) {
_this.popupRef = ref;
},
items: o.items,
value: o.value,
itemHeight: o.itemHeight,
listeners: [{
eventName: "EVENT_CHANGE",
action: function (value) {
_this._adjustText(value, false);
_this.fireEvent("EVENT_CHANGE", value);
}
}]
}]
}
}
};
},
/**
*
* @param {array} value 选中值
* @param {boolean}[optional] init 是否初始状态,mounted生命周期传true,其余传false或不传
*/
setValue: function (value, init) {
this._adjustText(value, init);
this.popupRef.setValue(value);
},
getValue: function () {
return this.popupRef.getValue();
},
populate: function (items) {
this.popupRef.populate(items);
},
_digest: function (value, init, items) {
var o = this.options;
var text = BI.isFunction(o.watermark) ? o.watermark() : o.watermark, textCls = "bi-water-mark";
value = BI.isArray(value) ? value : [value];
var result = [];
BI.each(items, function (i, item) {
BI.each(item.children, function (i, leafItem) {
if (BI.contains(value, leafItem.value)) {
result.push(leafItem.text);
}
});
});
var showError = false;
var valueText = result.length > 0 ? result.join(",") : BI.emptyStr;
if (init && BI.isNotEmptyString(o.text)) {
text = o.text;
if (BI.isEqual(text, valueText)) {
textCls = BI.emptyStr;
} else {
showError = true;
}
} else if (BI.isNotEmptyString(valueText)) {
text = valueText;
textCls = BI.emptyStr;
}
this._applyComboClass(showError);
return {
text: text,
textCls: textCls
};
},
/**
* 初始状态下,设置的显示值的优先级最高,根据真实值构造出来的文本值次之,水印文本最末
* 非初始状态下,显示值不再有效
*
* @param {*} value 真实值
* @param {*} init 是否为初始状态
*/
_adjustText: function (value, init) {
var o = this.options;
var digestObj = this._digest(value, init, o.items);
this.triggerRef.setText(digestObj.text);
this.triggerRef.setTextCls(digestObj.textCls);
},
// 切换下拉树控件样式
_applyComboClass: function (showError) {
if (showError) {
this.element.addClass("combo-error");
} else {
this.element.removeClass("combo-error");
}
}
});
BI.shortcut("dec.amiba.components.tree.single.chooser.combo", SingleChooserCombo);
})();!(function () {
// 将todolist组件挂载到#wrapper上.
// BI.createWidget({
// type: "my.todolist",
// element: "#wrapper"
// });
// 挂载下拉树测试组件
// BI.createWidget({
// type: "dec.amiba.test.tree",
// element: "#wrapper"
// });
// 挂载每组单选下拉框组件
BI.createWidget({
type: "dec.amiba.test.tree.single.chooser",
element: "#wrapper"
});
})();