From a76d34a414722c812d598ba4ae648ec68c8ed3e1 Mon Sep 17 00:00:00 2001 From: xujiahao01 Date: Tue, 15 Feb 2022 16:15:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=B8=8B=E6=8B=89=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E7=B1=BB=E7=BB=84=E4=BB=B6=E6=96=B0=E5=A2=9E=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C&demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/EventAction/SelectEvent.jsx | 300 +++++++++++++++++- examples/components/Example.jsx | 2 +- src/renderers/Form/InputTag.tsx | 124 +++++--- src/renderers/Form/MatrixCheckboxes.tsx | 22 +- src/renderers/Form/Options.tsx | 33 +- src/renderers/Form/Radios.tsx | 25 +- src/renderers/Form/Select.tsx | 9 +- 7 files changed, 436 insertions(+), 79 deletions(-) diff --git a/examples/components/EventAction/SelectEvent.jsx b/examples/components/EventAction/SelectEvent.jsx index 2f38c5f39..69f787d37 100644 --- a/examples/components/EventAction/SelectEvent.jsx +++ b/examples/components/EventAction/SelectEvent.jsx @@ -1,3 +1,61 @@ +const change = { + actions: [ + { + actionType: 'dialog', + args: { + val: '${event.data.value}' + }, + dialog: { + title: '派发change事件', + data: { + val: '${val}' + }, + body: [ + { + type: 'tpl', + tpl: '值更新:${val}' + } + ] + } + } + ] +}; + +const blur = { + actions: [ + { + actionType: 'toast', + msgType: 'info', + msg: '派发blur事件' + } + ] +}; + +const focus = { + actions: [ + { + actionType: 'toast', + msgType: 'info', + msg: '派发focus事件' + } + ] +}; + +const options = [ + { + label: '选项A', + value: 'A' + }, + { + label: '选项B', + value: 'B' + }, + { + label: '选项C', + value: 'C' + } +]; + export default { type: 'page', title: '下拉框组件事件', @@ -43,24 +101,234 @@ export default { value: 'A,B,C', multiple: true, checkAll: true, - options: [ - { - label: '选项A', - value: 'A' - }, - { - label: '选项B', - value: 'B' - }, - { - label: '选项C', - value: 'C' - } - ] + options, + onEvent: { + change, + blur, + focus + } } ] } ] - } - ] + }, + { + type: 'tpl', + tpl: 'inputTag标签选择器', + inline: false, + wrapperComponent: 'h2' + }, + { + type: 'form', + debug: true, + body: [ + { + type: 'group', + body: [ + { + name: 'trigger2', + id: 'trigger2', + type: 'action', + label: 'clear触发器', + level: 'primary', + onEvent: { + click: { + actions: [ + { + actionType: 'clear', + componentId: 'clear-input-tag', + description: '点击清空指定下拉框选中值' + } + ] + } + } + }, + { + name: 'clear-input-tag', + id: 'clear-input-tag', + type: 'input-tag', + label: 'clear动作测试', + mode: 'row', + value: 'A,B', + multiple: true, + options, + onEvent: { + change, + blur, + focus + } + }, + + ] + } + ] + }, + { + type: 'tpl', + tpl: 'matrix-checkboxes矩阵勾选', + inline: false, + wrapperComponent: 'h2' + }, + { + type: 'form', + debug: true, + body: [ + { + type: 'group', + body: [ + { + name: 'trigger3', + id: 'trigger3', + type: 'action', + label: 'clear触发器', + level: 'primary', + onEvent: { + click: { + actions: [ + { + actionType: 'clear', + componentId: 'clear-matrix-checkboxes', + description: '点击清空指定下拉框选中值' + } + ] + } + } + }, + { + name: 'clear-matrix-checkboxes', + id: 'clear-matrix-checkboxes', + type: 'matrix-checkboxes', + rowLabel: "行标题说明", + columns: [ + { + label: '列1' + }, + { + label: '列2' + } + ], + rows: [ + { + label: '行1' + }, + { + label: '行2' + } + ], + onEvent: { + change + } + }, + + ] + } + ] + }, + { + type: 'tpl', + tpl: 'radios单选框', + inline: false, + wrapperComponent: 'h2' + }, + { + type: 'form', + debug: true, + body: [ + { + type: 'group', + body: [ + { + name: 'trigger4', + id: 'trigger4', + type: 'action', + label: 'clear触发器', + level: 'primary', + onEvent: { + click: { + actions: [ + { + actionType: 'clear', + componentId: 'clear-radios', + description: '点击清空指定下拉框选中值' + } + ] + } + } + }, + { + name: 'clear-radios', + id: 'clear-radios', + type: "radios", + options, + onEvent: { + change + } + }, + ] + } + ] + }, + { + type: 'tpl', + tpl: 'options类', + inline: false, + wrapperComponent: 'h2' + }, + { + type: 'form', + debug: true, + body: [ + { + type: 'group', + body: [ + { + name: 'trigger5', + id: 'trigger5', + type: 'action', + label: 'clear触发器', + level: 'primary', + onEvent: { + click: { + actions: [ + { + actionType: 'clear', + componentId: 'clear-options', + description: '点击清空指定下拉框选中值' + } + ] + } + } + }, + { + name: 'clear-options', + id: 'clear-options', + type: 'checkboxes', + options, + onEvent: { + change + } + }, + { + name: 'clear-options', + id: 'clear-options', + type: 'button-group-select', + options, + onEvent: { + change + } + }, + { + name: 'clear-options', + id: 'clear-options', + type: 'list-select', + options, + onEvent: { + change + } + }, + ] + } + ] + }, + ], }; diff --git a/examples/components/Example.jsx b/examples/components/Example.jsx index a2ebe2a02..0b2b6932d 100644 --- a/examples/components/Example.jsx +++ b/examples/components/Example.jsx @@ -550,7 +550,7 @@ export const examples = [ component: makeSchemaRenderer(UploadEventSchema) }, { - label: '下拉框', + label: '下拉选择类', path: '/examples/event/select', component: makeSchemaRenderer(SelectEventActionSchema) }, diff --git a/src/renderers/Form/InputTag.tsx b/src/renderers/Form/InputTag.tsx index cb8232853..b54d5940c 100644 --- a/src/renderers/Form/InputTag.tsx +++ b/src/renderers/Form/InputTag.tsx @@ -9,11 +9,12 @@ import Downshift from 'downshift'; import find from 'lodash/find'; import {findDOMNode} from 'react-dom'; import ResultBox from '../../components/ResultBox'; -import {autobind, filterTree} from '../../utils/helper'; +import {autobind, filterTree, createObject} from '../../utils/helper'; import Spinner from '../../components/Spinner'; import Overlay from '../../components/Overlay'; import PopOver from '../../components/PopOver'; import ListMenu from '../../components/ListMenu'; +import {Action} from '../../types'; /** * Tag 输入框 @@ -80,46 +81,86 @@ export default class TagControl extends React.PureComponent< } } - addItem(option: Option) { + doAction(action: Action, data: object, throwErrors: boolean) { + const {resetValue, onChange} = this.props; + if (action.actionType === 'clear') { + onChange(resetValue ?? ''); + } + } + + @autobind + async dispatchEvent(eventName: string, e: any = {}) { + const {dispatchEvent, options, data} = this.props; + const rendererEvent = await dispatchEvent( + eventName, + createObject(e, { + options, + ...data + }) + ); + // 返回阻塞标识 + return !!rendererEvent?.prevented; + } + + @autobind + getValue(type: 'push' | 'pop' = 'pop', option: any = {}) { const { selectedOptions, - onChange, joinValues, extractValue, delimiter, valueField } = this.props; + + const newValue = selectedOptions.concat(); + if (type === 'push') { + newValue.push(option); + } else { + newValue.pop(); + } + + const newValueRes = joinValues + ? newValue + .map(item => item[valueField || 'value']) + .join(delimiter || ',') + : extractValue + ? newValue.map(item => item[valueField || 'value']) + : newValue; + return newValueRes; + } + + async addItem(option: Option) { + const { + selectedOptions, + onChange + } = this.props; const newValue = selectedOptions.concat(); if (find(newValue, item => item.value == option.value)) { return; } - newValue.push(option); + const newValueRes = this.getValue('push', option); - onChange( - joinValues - ? newValue - .map(item => item[valueField || 'value']) - .join(delimiter || ',') - : extractValue - ? newValue.map(item => item[valueField || 'value']) - : newValue - ); + const isPrevented = await this.dispatchEvent('change', { + value: newValueRes + }); + isPrevented || onChange(newValueRes); } @autobind - handleFocus(e: any) { + async handleFocus(e: any) { this.setState({ isFocused: true, isOpened: true }); - this.props.onFocus?.(e); + const isPrevented = await this.dispatchEvent('focus', e); + isPrevented || this.props.onFocus?.(e); } @autobind - handleBlur(e: any) { + async handleBlur(e: any) { const { selectedOptions, onChange, @@ -130,7 +171,9 @@ export default class TagControl extends React.PureComponent< } = this.props; const value = this.state.inputValue.trim(); - this.props.onBlur?.(e); + + const isPrevented = await this.dispatchEvent('blur', e); + isPrevented || this.props.onBlur?.(e); this.setState( { isFocused: false, @@ -176,7 +219,7 @@ export default class TagControl extends React.PureComponent< } @autobind - handleChange(value: Array