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