Combo 支持分支

This commit is contained in:
liaoxuezhi 2019-06-26 17:57:23 +08:00
parent 8ddfc7b76c
commit 3dd1b3dfd5
8 changed files with 879 additions and 471 deletions

View File

@ -3,374 +3,624 @@ export default {
title: "Combo 示例",
body: [
{
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
// debug: true,
controls: [
type: "tabs",
tabs: [
{
type: 'text',
label: '文本',
name: 'a'
},
{
type: 'divider'
},
{
type: "combo",
name: "combo1",
label: "组合多条多行",
multiple: true,
multiLine: true,
value: [{}],
controls: [
title: "基本用法",
hash: 'basic',
body: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"],
size: 'full'
}
]
},
{
type: "button",
label: "独立排序",
level: "dark",
className: "m-t-n-xs",
size: "sm",
actionType: "dialog",
visibleOn: "data.combo1.length > 1",
dialog: {
title: "对 Combo 进行 拖拽排序",
body: {
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
{
type: 'text',
label: '文本',
name: 'a'
},
{
type: 'divider'
},
{
type: "combo",
name: "combo1",
label: false,
label: "组合多条多行",
multiple: true,
draggable: true,
addable: false,
removable: false,
multiLine: true,
value: [{}],
controls: [
{
name: "a",
type: "static",
tpl: "${a} - ${b}"
label: "文本",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"],
size: 'full'
}
]
},
{
type: "button",
label: "独立排序",
level: "dark",
className: "m-t-n-xs",
size: "sm",
actionType: "dialog",
visibleOn: "data.combo1.length > 1",
dialog: {
title: "对 Combo 进行 拖拽排序",
body: {
type: "form",
controls: [
{
type: "combo",
name: "combo1",
label: false,
multiple: true,
draggable: true,
addable: false,
removable: false,
value: [{}],
controls: [
{
name: "a",
type: "static",
tpl: "${a} - ${b}"
}
]
}
]
},
actions: [
{
type: "submit",
mergeData: true,
label: "确认",
level: "primary"
},
{
type: "button",
actionType: "close",
label: "取消"
}
]
}
},
{
type: "combo",
name: "combo2",
label: "组合多条单行",
multiple: true,
value: [{}],
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo3",
label: "组合单条多行",
multiLine: true,
controls: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: "combo",
name: "combo4",
label: "组合单条单行",
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
}
]
},
actions: [
{
type: "submit",
mergeData: true,
label: "确认",
level: "primary"
},
{
type: "button",
actionType: "close",
label: "取消"
}
]
}
},
{
type: "combo",
name: "combo2",
label: "组合多条单行",
multiple: true,
value: [{}],
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo3",
label: "组合单条多行",
multiLine: true,
controls: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: "combo",
name: "combo4",
label: "组合单条单行",
controls: [
title: "内联样式",
hash: 'inline',
body: [
{
name: "a",
type: "text",
placeholder: "文本",
value: '',
size: 'full'
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
controls: [
{
type: "combo",
name: "combo11",
label: "组合多条多行内联",
multiple: true,
multiLine: true,
inline: true,
value: [{}],
controls: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: "combo",
name: "combo22",
label: "组合多条单行内联",
multiple: true,
inline: true,
value: [{}],
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo33",
label: "组合单条多行内联",
multiLine: true,
inline: true,
controls: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: "combo",
name: "combo44",
label: "组合单条单行内联",
inline: true,
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
}
]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo11",
label: "组合多条多行内联",
multiple: true,
multiLine: true,
inline: true,
value: [{}],
controls: [
title: "唯一验证",
hash: 'unique',
body: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
{
type: "combo",
name: "combo666",
label: "组合多条唯一",
multiple: true,
value: [{}],
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: '',
unique: true
},
{
name: "b",
type: "select",
options: ["a", "b", "c"],
unique: true
}
]
}
]
}
]
},
{
type: "combo",
name: "combo22",
label: "组合多条单行内联",
multiple: true,
inline: true,
value: [{}],
controls: [
title: "可拖拽排序",
hash: 'sortable',
body: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo33",
label: "组合单条多行内联",
multiLine: true,
inline: true,
controls: [
{
name: "a",
label: "文本",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
label: "选项",
type: "select",
options: ["a", "b", "c"]
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
{
type: "combo",
name: "combo777",
label: "可拖拽排序",
multiple: true,
value: [{a: '1', b: "a"}, {a: '2', b: "b"}],
draggable: true,
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
unique: true
},
{
name: "b",
type: "select",
options: ["a", "b", "c"],
unique: true
}
]
}
]
}
]
},
{
type: "combo",
name: "combo44",
label: "组合单条单行内联",
inline: true,
controls: [
title: "值打平",
hash: 'flat',
body: [
{
name: "a",
type: "text",
placeholder: "文本",
value: ''
},
{
name: "b",
type: "select",
options: ["a", "b", "c"]
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
{
type: "combo",
name: "combo888",
label: "可打平只存储值",
multiple: true,
flat: true,
value: ["red", "pink"],
draggable: true,
controls: [
{
name: "a",
type: "color",
placeholder: "选取颜色"
}
]
},
{
type: "static",
name: "combo888",
label: "当前值",
tpl: "<pre>${combo888|json}</pre>"
}
]
}
]
},
{
type: 'divider'
},
title: "条件",
hash: 'conditions',
body: [
{
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
'<p class="m-b-xl">添加时可选择类型,比如这个栗子,可以选择是文本类型还是数字类型</p>',
{
type: 'combo',
name: 'combo-conditions1',
label: '单选',
value: {
type: "number"
},
multiLine: true,
conditions: [
{
label: '文本',
test: 'this.type === "text"',
scaffold: {
type: "text",
label: "文本",
name: ""
},
controls: [
{
label: "名称",
name: "label",
type: "text"
},
{
label: "字段名",
name: "name",
type: "text"
},
]
},
{
type: "combo",
name: "combo666",
label: "组合多条唯一",
multiple: true,
value: [{}],
controls: [
{
name: "a",
type: "text",
placeholder: "文本",
value: '',
unique: true
},
{
name: "b",
type: "select",
options: ["a", "b", "c"],
unique: true
{
label: '数字',
test: 'this.type === "number"',
scaffold: {
type: "number",
label: "数字",
name: ""
},
controls: [
{
label: "名称",
name: "label",
type: "text"
},
{
label: "字段名",
name: "name",
type: "text"
},
{
label: "最小值",
name: "min",
type: "number"
},
{
label: "最大值",
name: "max",
type: "number"
},
{
label: "步长",
name: "step",
type: "number"
}
]
}
],
},
{
type: 'combo',
name: 'combo-conditions2',
label: '多选',
value: [
{
type: "text"
}
],
multiLine: true,
multiple: true,
typeSwitchable: false,
conditions: [
{
label: '文本',
test: 'this.type === "text"',
scaffold: {
type: "text",
label: "文本",
name: ""
},
controls: [
{
label: "名称",
name: "label",
type: "text"
},
{
label: "字段名",
name: "name",
type: "text"
},
]
},
{
label: '数字',
test: 'this.type === "number"',
scaffold: {
type: "number",
label: "数字",
name: ""
},
controls: [
{
label: "名称",
name: "label",
type: "text"
},
{
label: "字段名",
name: "name",
type: "text"
},
{
label: "最小值",
name: "min",
type: "number"
},
{
label: "最大值",
name: "max",
type: "number"
},
{
label: "步长",
name: "step",
type: "number"
}
]
}
],
}
]
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo777",
label: "可拖拽排序",
multiple: true,
value: [{a: '1', b: "a"}, {a: '2', b: "b"}],
draggable: true,
controls: [
title: "其他",
hash: 'others',
body: [
{
name: "a",
type: "text",
placeholder: "文本",
unique: true
},
{
name: "b",
type: "select",
options: ["a", "b", "c"],
unique: true
}
]
},
{
type: 'divider'
},
{
type: "combo",
name: "combo888",
label: "可打平只存储值",
multiple: true,
flat: true,
value: ["red", "pink"],
draggable: true,
controls: [
{
name: "a",
type: "color",
placeholder: "选取颜色"
}
]
},
{
type: "static",
name: "combo888",
label: "当前值",
tpl: "<pre>${combo888|json}</pre>"
}, {
type: 'divider'
},
{
type: "hidden",
name: "a_super",
value: "123"
},
{
type: "combo",
name: "combo999",
label: "可获取父级数据",
multiple: true,
canAccessSuperData: true,
controls: [
{
name: "a_super",
type: "text"
}
]
},
{
type: "combo",
name: "combo9999",
label: "显示序号",
multiple: true,
controls: [
{
type: "tpl",
tpl: "<%= data.index + 1%>",
className: "p-t-xs",
mode: "inline"
},
{
name: "a",
type: "text"
type: "form",
api: "/api/mock2/saveForm?waitSeconds=2",
title: "",
mode: "horizontal",
wrapWithPanel: false,
className: "m-t",
// debug: true,
controls: [
{
type: "text",
disabled: true,
label: "父级值",
name: "a_super",
value: "123"
},
{
type: "combo",
name: "combo999",
label: "可获取父级数据",
multiple: true,
canAccessSuperData: true,
controls: [
{
name: "a_super",
type: "text"
}
]
},
{
type: "combo",
name: "combo9999",
label: "显示序号",
multiple: true,
controls: [
{
type: "tpl",
tpl: "<%= data.index + 1%>",
className: "p-t-xs",
mode: "inline"
},
{
name: "a",
type: "text"
}
]
}
]
}
]
}

View File

@ -38,163 +38,157 @@ export default {
type: 'combo',
multiple: true,
multiLine: true,
controls: [
typeSwitchable: false,
conditions: [
{
type: 'hidden',
name: '_type',
value: 'item'
},
{
type: 'group',
visibleOn: 'this._type === "item"',
label: "条件",
test: "!data.hasOwnProperty('connect')",
scaffold: {},
controls: [
{
name: 'key',
type: 'text',
placeholder: '字段名',
required: true
},
type: 'group',
className: 'm-b-none',
controls: [
{
name: 'key',
type: 'text',
placeholder: '字段名',
required: true
},
{
name: 'type',
type: 'select',
value: 0,
options: [
{
label: 'int64',
value: 0
},
{
label: 'double64',
value: 1
},
{
label: 'string',
value: 2
},
{
label: 'version',
value: 3
}
]
},
{
type: 'formula',
name: 'opt',
formula: '""',
condition: '${type}'
},
{
name: 'opt',
type: 'select',
placeholder: '请选择',
required: true,
options: [
{
label: '>',
value: '>',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '<',
value: '<',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '==',
value: '=='
},
{
label: '>=',
value: '>=',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '<=',
value: '<=',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: 'in',
value: 'in',
},
{
label: 'not in',
value: 'not in',
},
{
label: '!=',
value: '!='
},
]
},
{
name: 'val',
type: 'text',
placeholder: '值',
required: true,
visibleOn: '~[">", "<", ">=", "<=", "==", "!="].indexOf(this.opt)'
},
{
name: 'val',
type: 'array',
required: true,
minLength: 1,
value: [{}],
items: {
type: 'text',
placeholder: '值',
required: true,
},
visibleOn: '~["in", "not in"].indexOf(this.opt)'
}
]
}
]
},
{
label: "组合",
test: "data.hasOwnProperty('connect')",
scaffold: {
connect: "&",
exprs: [{}]
},
controls: [
{
name: 'type',
type: 'select',
value: 0,
type: "button-group",
name: 'connect',
value: '&',
clearable: false,
size: 'xs',
options: [
{
label: 'int64',
value: 0
label: 'AND',
value: '&'
},
{
label: 'double64',
value: 1
},
{
label: 'string',
value: 2
},
{
label: 'version',
value: 3
label: 'OR',
value: '|'
}
]
},
{
type: 'formula',
name: 'opt',
formula: '""',
condition: '${type}'
},
{
name: 'opt',
type: 'select',
placeholder: '请选择',
required: true,
options: [
{
label: '>',
value: '>',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '<',
value: '<',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '==',
value: '=='
},
{
label: '>=',
value: '>=',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: '<=',
value: '<=',
visibleOn: '~[0,1,3].indexOf(this.type)'
},
{
label: 'in',
value: 'in',
},
{
label: 'not in',
value: 'not in',
},
{
label: '!=',
value: '!='
},
]
},
{
name: 'val',
type: 'text',
placeholder: '值',
required: true,
visibleOn: '~[">", "<", ">=", "<=", "==", "!="].indexOf(this.opt)'
},
{
name: 'val',
type: 'array',
required: true,
$ref: 'queryItem',
name: 'exprs',
minLength: 1,
value: [{}],
items: {
type: 'text',
placeholder: '值',
required: true,
},
visibleOn: '~["in", "not in"].indexOf(this.opt)'
}
]
},
{
type: "button-group",
name: 'connect',
value: '&',
clearable: false,
size: 'xs',
visibleOn: 'this._type === "group"',
options: [
{
label: 'AND',
value: '&'
},
{
label: 'OR',
value: '|'
}
]
},
{
$ref: 'queryItem',
name: 'exprs',
visibleOn: 'this._type === "group"',
minLength: 1,
value: [{}]
},
{
name: '_type',
type: 'button-group',
size: 'xs',
options: [
{
label: 'Item',
value: 'item'
},
{
label: 'Group',
value: 'group'
value: [{}]
}
]
}
@ -210,6 +204,8 @@ export default {
type: "button-group",
name: 'connect',
value: '&',
// label: "",
// mode: 'inline',
clearable: false,
size: 'sm',
options: [
@ -265,6 +261,12 @@ export default {
name: 'q',
value: {},
label: 'Query'
},
{
type: "static",
name: "q",
label: "当前值",
tpl: "<pre>${q|json}</pre>"
}
]
},

View File

@ -68,6 +68,15 @@
flex-grow: 1;
}
.#{$ns}Combo-itemTag {
margin-right: $gap-sm;
label {
color: $info;
margin-right: $gap-sm;
}
}
.#{$ns}Combo-itemToolbar {
margin-left: $gap-xs;
display: flex;
@ -89,6 +98,15 @@
(-$Combo--vertical-item-gap * 2);
}
.#{$ns}Combo-itemTag {
text-align: right;
label {
color: $info;
margin-right: $gap-sm;
}
}
// 不严格点会命中 combo 里面嵌套 combo 的情况so sad.
> .#{$ns}Combo-item,
> .#{$ns}Combo-items > .#{$ns}Combo-item {

View File

@ -1,6 +1,7 @@
.#{$ns}Select {
display: inline-flex;
vertical-align: middle;
text-align: left;
outline: none;
position: relative;
border: $Form-select-borderWidth solid $Form-select-borderColor;

View File

@ -88,9 +88,9 @@ export class Action extends React.Component<ActionProps> {
handleAction(e: React.MouseEvent<any>) {
const {onAction, onClick, disabled} = this.props;
onClick && onClick(e, this.props);
const result:any = onClick && onClick(e, this.props);
if (disabled || e.isDefaultPrevented() || !onAction) {
if (disabled || e.isDefaultPrevented() || result === false || !onAction) {
return;
}

View File

@ -68,7 +68,7 @@ export default class DropDownButton extends React.Component<DropDownButtonProps,
let body = (
<RootCloseWrapper disabled={!this.state.isOpened} onRootClose={this.close}>
<ul className={cx('DropDown-menu')}>
<ul className={cx('DropDown-menu')} onClick={this.close}>
{children
? children
: Array.isArray(buttons)
@ -132,6 +132,7 @@ export default class DropDownButton extends React.Component<DropDownButtonProps,
caretIcon,
align,
iconOnly,
icon,
data,
} = this.props;
@ -159,6 +160,7 @@ export default class DropDownButton extends React.Component<DropDownButtonProps,
size ? `Button--${size}` : ''
)}
>
{icon ? (<i className={cx(icon, 'm-r-xs')} />) : null}
{typeof label === 'string' ? filter(label, data) : label}
<i className={cx('DropDown-caret', caretIcon)} />
</button>

View File

@ -18,12 +18,24 @@ import {
createObject} from '../../utils/helper';
import Sortable = require('sortablejs');
import { evalExpression, filter } from '../../utils/tpl';
import find = require('lodash/find');
import Select from '../../components/Select';
import { dataMapping } from '../../utils/tpl-builtin';
export interface Condition {
test: string;
controls: Array<Schema>;
label: string;
scaffold?: any;
mode?: string;
}
export interface ComboProps extends FormControlProps {
placeholder?: string;
flat?: boolean; // 是否把值打平,即原来是对象现在只有对象中的值。
draggable?: boolean; // 是否可拖拽
controls: Array<Schema>;
controls?: Array<Schema>;
conditions?: Array<Condition>;
multiple?: boolean;
multiLine?: boolean;
minLength?: number;
@ -33,6 +45,7 @@ export interface ComboProps extends FormControlProps {
formClassName?: string;
addButtonText?: string;
addable?: boolean;
typeSwitchable?: boolean;
removable?: boolean;
deleteApi?: Api,
deleteConfirmText?: string;
@ -77,7 +90,8 @@ export default class ComboControl extends React.Component<ComboProps> {
"addIcon",
"dragIcon",
"deleteIcon",
"noBorder"
"noBorder",
"conditions"
];
subForms:Array<any> = [];
@ -95,6 +109,7 @@ export default class ComboControl extends React.Component<ComboProps> {
this.addItem = this.addItem.bind(this);
this.removeItem = this.removeItem.bind(this);
this.dragTipRef = this.dragTipRef.bind(this);
this.handleComboTypeChange = this.handleComboTypeChange.bind(this);
this.defaultValue = {
...props.scaffold
};
@ -151,6 +166,33 @@ export default class ComboControl extends React.Component<ComboProps> {
return value;
}
addItemWith(condition:Condition) {
const {
flat,
joinValues,
delimiter,
scaffold,
disabled
} = this.props;
if (disabled) {
return;
}
let value = this.getValueAsArray();
value.push(flat ? condition.scaffold || scaffold || '' : {
...condition.scaffold || scaffold
});
this.keys.push(guid());
if (flat && joinValues) {
value = value.join(delimiter || ',');
}
this.props.onChange(value);
}
addItem() {
const {
flat,
@ -375,13 +417,47 @@ export default class ComboControl extends React.Component<ComboProps> {
return createObject(createObject(data, {index, __index: index}), value);
}
pickCondition(value:any):Condition {
const conditions:Array<Condition> = this.props.conditions as Array<Condition>;
return (find(conditions, (item) => item.test && evalExpression(item.test, value)) || conditions[0]) as Condition;
}
handleComboTypeChange(index:number, selection:any) {
const {
multiple,
onChange,
value,
flat
} = this.props;
const conditions:Array<Condition> = this.props.conditions as Array<Condition>;
const condition = find(conditions, item => item.label === selection.label);
if (!condition) {
return;
}
if (multiple) {
const newValue = this.getValueAsArray();
newValue.splice(index, 1, {
...dataMapping(condition.scaffold || {}, newValue[index])
});
// todo 支持 flat
onChange(newValue);
} else {
onChange({
...dataMapping(condition.scaffold || {}, value)
});
}
}
renderMultipe() {
const {
classPrefix: ns,
classnames: cx,
formClassName,
render,
controls,
multiLine,
addButtonClassName,
disabled,
@ -393,6 +469,7 @@ export default class ComboControl extends React.Component<ComboProps> {
addButtonText,
addable,
removable,
typeSwitchable,
itemRemovableOn,
delimiter,
canAccessSuperData,
@ -400,8 +477,10 @@ export default class ComboControl extends React.Component<ComboProps> {
dragIcon,
deleteIcon,
noBorder,
conditions
} = this.props;
let controls = this.props.controls;
let value = this.props.value;
if (flat && typeof value === 'string') {
@ -453,8 +532,16 @@ export default class ComboControl extends React.Component<ComboProps> {
);
}
const data = this.formatValue(value, index);
let condition:Condition | null = null;
if (Array.isArray(conditions) && conditions.length) {
condition = this.pickCondition(data);
controls = condition.controls;
}
let finnalControls = flat ? [{
...controls[0],
...controls && controls[0],
name: 'flat'
}] : controls;
@ -463,6 +550,16 @@ export default class ComboControl extends React.Component<ComboProps> {
className={cx(`Combo-item`)}
key={this.keys[index] || (this.keys[index] = guid())}
>
{condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}>
<label></label>
<Select
onChange={this.handleComboTypeChange.bind(this, index)}
options={(conditions as Array<Condition>).map(item => ({label: item.label , value: item.label}))}
value={condition.label}
/>
</div>
) : null}
<div className={cx(`Combo-itemInner`)}>
{render(`multiple/${index}`, {
type: 'form',
@ -474,7 +571,7 @@ export default class ComboControl extends React.Component<ComboProps> {
}, {
index,
disabled,
data: this.formatValue(value, index),
data,
onChange: this.handleChange.bind(this, index),
onAction: this.handleAction,
ref: (ref:any) => this.formRef(ref, index),
@ -490,7 +587,23 @@ export default class ComboControl extends React.Component<ComboProps> {
</div>
{!disabled ? (
<div className={cx(`Combo-toolbar`)}>
{store.addable && addable !== false ? (
{store.addable && addable !== false ? Array.isArray(conditions) && conditions.length ? (
render('add-button', {
type: 'dropdown-button',
icon: addIcon,
label: addButtonText || '新增',
level: 'info',
size: 'sm'
}, {
buttons: conditions.map(item => ({
label: item.label,
onClick: (e:any) => {
this.addItemWith(item)
return false;
}
}))
})
) : (
<button
type="button"
onClick={this.addItem}
@ -512,7 +625,7 @@ export default class ComboControl extends React.Component<ComboProps> {
renderSingle() {
const {
controls,
conditions,
classnames: cx,
render,
value,
@ -520,15 +633,35 @@ export default class ComboControl extends React.Component<ComboProps> {
formClassName,
canAccessSuperData,
noBorder,
disabled
disabled,
typeSwitchable
} = this.props;
let controls = this.props.controls;
const data = isObject(value) ? value : this.defaultValue;
let condition:Condition | null = null;
if (Array.isArray(conditions) && conditions.length) {
condition = this.pickCondition(data);
controls = condition.controls;
}
return (
<div
className={cx(`Combo Combo--single`, multiLine ? `Combo--ver` : `Combo--hor`, noBorder ? `Combo--noBorder` : '')}
>
<div className={cx(`Combo-item`)}>
{condition && typeSwitchable !== false ? (
<div className={cx('Combo-itemTag')}>
<label></label>
<Select
onChange={this.handleComboTypeChange.bind(this, 0)}
options={(conditions as Array<Condition>).map(item => ({label: item.label , value: item.label}))}
value={condition.label}
/>
</div>
) : null}
<div className={cx(`Combo-itemInner`)}>
{render('single', {
type: 'form',

View File

@ -376,6 +376,8 @@ export function dataMapping(to: any, from: PlainObject): any {
if (Array.isArray(to)) {
return to.map(item => dataMapping(item, from));
} else if (!to) {
return ret;
}
Object.keys(to).forEach(key => {