mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 12:08:13 +08:00
autoFill 支持多选
This commit is contained in:
parent
845b7c266a
commit
c702f7bb3f
@ -143,6 +143,31 @@ order: 21
|
||||
|
||||
这样上传成功后,会把接口中的 `url` 变量,赋值给 `myUrl` 变量
|
||||
|
||||
**多选模式**
|
||||
|
||||
当表单项为多选模式时,不能再直接取选项中的值了,而是通过 `items` 变量来取,通过它可以获取当前选中的选项集合。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"debug": true,
|
||||
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
|
||||
"controls": [
|
||||
{
|
||||
"type": "file",
|
||||
"name": "file",
|
||||
"label": "File",
|
||||
"multiple": true,
|
||||
"receiver": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/upload/file",
|
||||
"autoFill": {
|
||||
"myUrl": "${items|pick:url}",
|
||||
"lastUrl": "${items|last|pick:url}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||
|
@ -156,6 +156,31 @@ order: 27
|
||||
|
||||
这样上传成功后,会把接口中的 `url` 变量,赋值给 `myUrl` 变量
|
||||
|
||||
**多选模式**
|
||||
|
||||
当表单项为多选模式时,不能再直接取选项中的值了,而是通过 `items` 变量来取,通过它可以获取当前选中的选项集合。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"debug": true,
|
||||
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
|
||||
"controls": [
|
||||
{
|
||||
"type": "image",
|
||||
"name": "image",
|
||||
"label": "image",
|
||||
"multiple": true,
|
||||
"receiver": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/upload/file",
|
||||
"autoFill": {
|
||||
"myUrl": "${items|pick:url}",
|
||||
"lastUrl": "${items|last|pick:url}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||
|
@ -1265,12 +1265,13 @@ order: 2
|
||||
|
||||
## 自动填充 autoFill
|
||||
|
||||
一些选择器组件,支持配置`autoFill`,将当前已选中的选项的某个字段的值,自动填充到表单中某个表单项中,**只在单选时有效**,支持[数据映射](../../../docs/concepts/data-mapping)
|
||||
一些选择器组件,支持配置`autoFill`,将当前已选中的选项的某个字段的值,自动填充到表单中某个表单项中,支持[数据映射](../../../docs/concepts/data-mapping)
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
|
||||
"debug": true,
|
||||
"controls": [
|
||||
{
|
||||
"type": "select",
|
||||
@ -1279,6 +1280,7 @@ order: 2
|
||||
"autoFill": {
|
||||
"option": "${label}"
|
||||
},
|
||||
"clearable": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "Option A",
|
||||
@ -1301,6 +1303,41 @@ order: 2
|
||||
|
||||
上例中我们配置了`"autoFill": {"option": "${label}"}`,表示将选中项中的`label`的值,自动填充到当前表单项中`name`为`option`的文本框中。
|
||||
|
||||
**多选模式**
|
||||
|
||||
当表单项为多选模式时,不能再直接取选项中的值了,而是通过 `items` 变量来取,通过它可以获取当前选中的选项集合。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm",
|
||||
"debug": true,
|
||||
"controls": [
|
||||
{
|
||||
"type": "select",
|
||||
"label": "选项",
|
||||
"name": "select",
|
||||
"autoFill": {
|
||||
"options": "${items|pick:label}",
|
||||
"firstOption": "${items|first|pick:label}"
|
||||
},
|
||||
"multiple": true,
|
||||
"clearable": true,
|
||||
"options": [
|
||||
{
|
||||
"label": "Option A",
|
||||
"value": "a"
|
||||
},
|
||||
{
|
||||
"label": "Option B",
|
||||
"value": "b"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
支持该配置项的有:ButtonGroup、List、NestedSelect、Picker、Radios、Select。
|
||||
|
||||
## 属性表
|
||||
|
@ -807,6 +807,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
||||
this.handleChange(item);
|
||||
}}
|
||||
disabled={item.disabled}
|
||||
size="sm"
|
||||
>
|
||||
{item.disabled
|
||||
? item[labelField]
|
||||
@ -867,6 +868,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
||||
checked={checkedPartial}
|
||||
partial={checkedPartial && !checkedAll}
|
||||
onChange={this.toggleCheckAll}
|
||||
size="sm"
|
||||
>
|
||||
{__(checkAllLabel)}
|
||||
</Checkbox>
|
||||
@ -874,7 +876,11 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
||||
) : null}
|
||||
|
||||
<div ref={this.menuItemRef} className={cx('Select-option invisible')}>
|
||||
<span>Placeholder</span>
|
||||
{multiple ? (
|
||||
<Checkbox size="sm">Placeholder</Checkbox>
|
||||
) : (
|
||||
<span>Placeholder</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{creatable && !disabled ? (
|
||||
|
@ -605,7 +605,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||
return;
|
||||
}
|
||||
|
||||
const {translate: __, multiple, autoFill, onBulkChange} = this.props;
|
||||
const {translate: __} = this.props;
|
||||
const nameField = this.props.nameField || 'name';
|
||||
const file = find(
|
||||
this.state.files,
|
||||
@ -647,17 +647,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||
error: error ? error : null,
|
||||
files: files
|
||||
},
|
||||
() => {
|
||||
// todo 这个逻辑应该移到 onChange 里面去,因为这个时候并不一定修改了表单项的值。
|
||||
const sendTo =
|
||||
!multiple &&
|
||||
autoFill &&
|
||||
!isEmpty(autoFill) &&
|
||||
dataMapping(autoFill, obj || {});
|
||||
sendTo && onBulkChange(sendTo);
|
||||
|
||||
this.tick();
|
||||
}
|
||||
this.tick
|
||||
);
|
||||
},
|
||||
progress => {
|
||||
@ -816,7 +806,9 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||
valueField,
|
||||
delimiter,
|
||||
resetValue,
|
||||
asBlob
|
||||
asBlob,
|
||||
autoFill,
|
||||
onBulkChange
|
||||
} = this.props;
|
||||
|
||||
const files = this.state.files.filter(
|
||||
@ -841,6 +833,18 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||
}
|
||||
|
||||
onChange((this.emitValue = value), undefined, changeImmediately);
|
||||
|
||||
if (!isEmpty(autoFill)) {
|
||||
const toSync = dataMapping(
|
||||
autoFill,
|
||||
multiple
|
||||
? {
|
||||
items: files
|
||||
}
|
||||
: files[0]
|
||||
);
|
||||
onBulkChange(toSync);
|
||||
}
|
||||
}
|
||||
|
||||
uploadFile(
|
||||
|
@ -571,7 +571,6 @@ export default class ImageControl extends React.Component<
|
||||
}
|
||||
|
||||
tick() {
|
||||
const {multiple, autoFill, onBulkChange} = this.props;
|
||||
if (this.current || !this.state.uploading) {
|
||||
return;
|
||||
}
|
||||
@ -632,17 +631,7 @@ export default class ImageControl extends React.Component<
|
||||
{
|
||||
files: (this.files = files)
|
||||
},
|
||||
() => {
|
||||
// todo 这个逻辑应该移到 onChange 里面去,因为这个时候并不一定修改了表单项的值。
|
||||
const sendTo =
|
||||
!multiple &&
|
||||
autoFill &&
|
||||
!isEmpty(autoFill) &&
|
||||
dataMapping(autoFill, newFile || {});
|
||||
sendTo && onBulkChange(sendTo);
|
||||
|
||||
this.tick();
|
||||
}
|
||||
this.tick
|
||||
);
|
||||
},
|
||||
progress => {
|
||||
@ -734,7 +723,9 @@ export default class ImageControl extends React.Component<
|
||||
joinValues,
|
||||
extractValue,
|
||||
delimiter,
|
||||
valueField
|
||||
valueField,
|
||||
autoFill,
|
||||
onBulkChange
|
||||
} = this.props;
|
||||
|
||||
const files = this.files.filter(
|
||||
@ -762,6 +753,18 @@ export default class ImageControl extends React.Component<
|
||||
}
|
||||
|
||||
onChange((this.emitValue = newValue || ''), undefined, changeImmediately);
|
||||
|
||||
if (!isEmpty(autoFill)) {
|
||||
const toSync = dataMapping(
|
||||
autoFill,
|
||||
multiple
|
||||
? {
|
||||
items: files
|
||||
}
|
||||
: files[0]
|
||||
);
|
||||
onBulkChange(toSync);
|
||||
}
|
||||
}
|
||||
|
||||
handleSelect() {
|
||||
|
@ -391,6 +391,7 @@ export const FormItemStore = StoreNode.named('FormItemStore')
|
||||
self.options = options;
|
||||
syncOptions(originOptions);
|
||||
let selectedOptions;
|
||||
let skipAyncAutoFill = false;
|
||||
|
||||
if (
|
||||
self.selectFirst &&
|
||||
@ -422,10 +423,11 @@ export const FormItemStore = StoreNode.named('FormItemStore')
|
||||
onChange(value);
|
||||
} else {
|
||||
changeValue(value, !form.inited);
|
||||
skipAyncAutoFill = true; // changeValue 里面本来就会调用 syncAutoFill 所以跳过
|
||||
}
|
||||
}
|
||||
|
||||
syncAutoFill(self.value, !form.inited);
|
||||
skipAyncAutoFill || syncAutoFill(self.value, !form.inited);
|
||||
}
|
||||
|
||||
let loadCancel: Function | null = null;
|
||||
@ -799,29 +801,35 @@ export const FormItemStore = StoreNode.named('FormItemStore')
|
||||
value: any = self.value,
|
||||
isPrintine: boolean = false
|
||||
) {
|
||||
if (
|
||||
!self.multiple &&
|
||||
self.autoFill &&
|
||||
!isEmpty(self.autoFill) &&
|
||||
self.options.length
|
||||
) {
|
||||
if (self.autoFill && !isEmpty(self.autoFill) && self.options.length) {
|
||||
const selectedOptions = self.getSelectedOptions(value);
|
||||
if (selectedOptions.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toSync = dataMapping(
|
||||
self.autoFill,
|
||||
createObject(
|
||||
{
|
||||
ancestors: getTreeAncestors(
|
||||
self.filteredOptions,
|
||||
selectedOptions[0],
|
||||
true
|
||||
self.multiple
|
||||
? {
|
||||
items: selectedOptions.map(item =>
|
||||
createObject(
|
||||
{
|
||||
ancestors: getTreeAncestors(
|
||||
self.filteredOptions,
|
||||
item,
|
||||
true
|
||||
)
|
||||
},
|
||||
item
|
||||
)
|
||||
)
|
||||
}
|
||||
: createObject(
|
||||
{
|
||||
ancestors: getTreeAncestors(
|
||||
self.filteredOptions,
|
||||
selectedOptions[0],
|
||||
true
|
||||
)
|
||||
},
|
||||
selectedOptions[0]
|
||||
)
|
||||
},
|
||||
selectedOptions[0]
|
||||
)
|
||||
);
|
||||
Object.keys(toSync).forEach(key => {
|
||||
const value = toSync[key];
|
||||
|
Loading…
Reference in New Issue
Block a user