Table form item 支持验证

This commit is contained in:
liaoxuezhi 2019-06-25 17:49:25 +08:00
parent 12274362e4
commit 4e98015357
7 changed files with 87 additions and 15 deletions

View File

@ -15,6 +15,7 @@ import Copyable from './Copyable';
export interface CardProps extends RendererProps { export interface CardProps extends RendererProps {
onCheck: (item: IItem) => void; onCheck: (item: IItem) => void;
itemIndex?: number;
multiple?: boolean; multiple?: boolean;
highlightClassName?: string; highlightClassName?: string;
hideCheckToggler?: boolean; hideCheckToggler?: boolean;
@ -191,7 +192,7 @@ export class Card extends React.Component<CardProps> {
} }
renderFeild(region: string, field: any, key: any, props: any) { renderFeild(region: string, field: any, key: any, props: any) {
const {render, classnames: cx} = props; const {render, classnames: cx, itemIndex} = props;
const data = this.props.data; const data = this.props.data;
const $$id = field.$$id ? `${field.$$id}-field` : ''; const $$id = field.$$id ? `${field.$$id}-field` : '';
@ -213,6 +214,8 @@ export class Card extends React.Component<CardProps> {
}, },
{ {
className: cx('Card-fieldValue', field.className), className: cx('Card-fieldValue', field.className),
rowIndex: itemIndex,
colIndex: key,
value: field.name ? resolveVariable(field.name, data) : undefined, value: field.name ? resolveVariable(field.name, data) : undefined,
popOverContainer: this.getPopOverContainer, popOverContainer: this.getPopOverContainer,
onAction: this.handleAction, onAction: this.handleAction,

View File

@ -693,6 +693,7 @@ export default class Cards extends React.Component<GridProps, object> {
'is-moved': item.moved, 'is-moved': item.moved,
}), }),
item, item,
intemIndex: item.index,
multiple, multiple,
hideCheckToggler, hideCheckToggler,
selectable: store.selectable, selectable: store.selectable,

View File

@ -71,7 +71,9 @@ export default class FormTable extends React.Component<TableProps, TableState> {
"deleteApi" "deleteApi"
]; ];
entries:Array<any> = []; entries:Map<any, number>;
entityId: number = 0;
subForms:any = {}
constructor(props:TableProps) { constructor(props:TableProps) {
super(props); super(props);
@ -80,12 +82,51 @@ export default class FormTable extends React.Component<TableProps, TableState> {
editIndex: -1 editIndex: -1
}; };
this.entries = new Map();
this.buildItemProps = this.buildItemProps.bind(this); this.buildItemProps = this.buildItemProps.bind(this);
this.confirmEdit = this.confirmEdit.bind(this); this.confirmEdit = this.confirmEdit.bind(this);
this.cancelEdit = this.cancelEdit.bind(this); this.cancelEdit = this.cancelEdit.bind(this);
this.handleSaveTableOrder = this.handleSaveTableOrder.bind(this); this.handleSaveTableOrder = this.handleSaveTableOrder.bind(this);
this.handleTableSave = this.handleTableSave.bind(this); this.handleTableSave = this.handleTableSave.bind(this);
this.getEntryId = this.getEntryId.bind(this); this.getEntryId = this.getEntryId.bind(this);
this.subFormRef = this.subFormRef.bind(this);
}
componentWillUnmount() {
this.entries.clear();
}
subFormRef(form:any, x:number, y:number) {
console.log(form, x, y);
this.subForms[`${x}-${y}`] = form;
}
validate():any {
const {
value,
minLength,
maxLength
} = this.props;
if (minLength && (!Array.isArray(value) || value.length < minLength)) {
return `组合表单成员数量不够,低于最小的设定${minLength}个,请添加更多的成员。`;
} else if (maxLength && Array.isArray(value) && value.length > maxLength) {
return `组合表单成员数量超出,超出最大的设定${maxLength}个,请删除多余的成员。`;
} else {
const subForms:Array<any> = [];
Object.keys(this.subForms).forEach(key => this.subForms[key] && subForms.push(this.subForms[key]));
if (subForms.length) {
return Promise
.all(subForms.map(item => item.validate()))
.then((values) => {
if (~values.indexOf(false)) {
return '内部表单验证失败';
}
return;
})
}
}
} }
doAction(action:Action, ctx:RendererData, ...rest:Array<any>) { doAction(action:Action, ctx:RendererData, ...rest:Array<any>) {
@ -487,19 +528,17 @@ export default class FormTable extends React.Component<TableProps, TableState> {
} }
removeEntry(entry:any) { removeEntry(entry:any) {
const idx = this.entries.indexOf(entry); if (this.entries.has(entry)) {
~idx && this.entries.splice(idx, 1); this.entries.delete(entry);
}
} }
getEntryId(entry:any) { getEntryId(entry:any) {
let idx = this.entries.indexOf(entry); if (!this.entries.has(entry)) {
this.entries.set(entry, this.entityId++);
if (!~idx) {
idx = this.entries.length;
this.entries.push(entry);
} }
return String(idx); return String(this.entries.get(entry));
} }
render() { render() {
@ -530,7 +569,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
getEntryId: this.getEntryId, getEntryId: this.getEntryId,
onSave: this.handleTableSave, onSave: this.handleTableSave,
onSaveOrder: this.handleSaveTableOrder, onSaveOrder: this.handleSaveTableOrder,
buildItemProps: this.buildItemProps buildItemProps: this.buildItemProps,
quickEditFormRef: this.subFormRef
})} })}
</div> </div>
);; );;

View File

@ -650,6 +650,7 @@ export default class List extends React.Component<ListProps, object> {
checkable: item.checkable, checkable: item.checkable,
multiple, multiple,
item, item,
itemIndex: item.index,
hideCheckToggler, hideCheckToggler,
checkOnItemClick, checkOnItemClick,
selected: item.checked, selected: item.checked,
@ -695,6 +696,7 @@ export class ListRenderer extends List {
export interface ListItemProps extends RendererProps { export interface ListItemProps extends RendererProps {
hideCheckToggler?: boolean; hideCheckToggler?: boolean;
item: IItem; item: IItem;
itemIndex?: number;
checkable?: boolean; checkable?: boolean;
checkOnItemClick?: boolean; checkOnItemClick?: boolean;
} }
@ -854,6 +856,7 @@ export class ListItem extends React.Component<ListItemProps> {
const render = props.render || this.props.render; const render = props.render || this.props.render;
const data = this.props.data; const data = this.props.data;
const cx = this.props.classnames; const cx = this.props.classnames;
const itemIndex = this.props.itemIndex;
const $$id = field.$$id ? `${field.$$id}-field` : ''; const $$id = field.$$id ? `${field.$$id}-field` : '';
@ -877,6 +880,8 @@ export class ListItem extends React.Component<ListItemProps> {
type: 'list-item-field', type: 'list-item-field',
}, },
{ {
rowIndex: itemIndex,
colIndex: key,
className: cx('ListItem-fieldValue', field.className), className: cx('ListItem-fieldValue', field.className),
value: field.name ? resolveVariable(field.name, data) : `-`, value: field.name ? resolveVariable(field.name, data) : `-`,
onAction: this.handleAction, onAction: this.handleAction,

View File

@ -62,6 +62,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
this.overlayRef = this.overlayRef.bind(this); this.overlayRef = this.overlayRef.bind(this);
this.handleWindowKeyPress = this.handleWindowKeyPress.bind(this); this.handleWindowKeyPress = this.handleWindowKeyPress.bind(this);
this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this); this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
this.formRef = this.formRef.bind(this);
this.state = { this.state = {
isOpened: false, isOpened: false,
@ -80,6 +81,22 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
document.body.addEventListener('keydown', this.handleWindowKeyDown); document.body.addEventListener('keydown', this.handleWindowKeyDown);
} }
formRef(ref:any) {
const {
quickEditFormRef,
rowIndex,
colIndex
} = this.props;
if (quickEditFormRef) {
while (ref && ref.getWrappedInstance) {
ref = ref.getWrappedInstance();
}
quickEditFormRef(ref, colIndex, rowIndex);
}
}
handleWindowKeyPress(e: Event) { handleWindowKeyPress(e: Event) {
const ns = this.props.classPrefix; const ns = this.props.classPrefix;
let el: HTMLElement = (e.target as HTMLElement).closest(`.${ns}Field--quickEditable`) as HTMLElement; let el: HTMLElement = (e.target as HTMLElement).closest(`.${ns}Field--quickEditable`) as HTMLElement;
@ -347,6 +364,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
onSubmit: this.handleSubmit, onSubmit: this.handleSubmit,
onAction: this.handleAction, onAction: this.handleAction,
onChange: null, onChange: null,
ref: this.formRef,
popOverContainer: popOverContainer ? () => this.overlay : null, popOverContainer: popOverContainer ? () => this.overlay : null,
})} })}
</div> </div>
@ -388,6 +406,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
{render('inline-form', this.buildSchema(), { {render('inline-form', this.buildSchema(), {
wrapperComponent: 'div', wrapperComponent: 'div',
className: cx('Form--quickEdit'), className: cx('Form--quickEdit'),
ref: this.formRef,
onChange: (values: object) => onChange: (values: object) =>
onQuickChange(values, (quickEdit as QuickEditConfig).saveImmediately), onQuickChange(values, (quickEdit as QuickEditConfig).saveImmediately),
})} })}

View File

@ -1223,12 +1223,13 @@ export default class Table extends React.Component<TableProps, object> {
return flatMap(rows, (item: IRow, rowIndex: number) => { return flatMap(rows, (item: IRow, rowIndex: number) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null; const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [ const doms = [
<TableRow <TableRow
{...itemProps} {...itemProps}
classPrefix={ns} classPrefix={ns}
checkOnItemClick={checkOnItemClick} checkOnItemClick={checkOnItemClick}
key={item.depth > 1 ? item.id : item.key} key={item.id}
itemIndex={rowIndex} itemIndex={rowIndex}
item={item} item={item}
itemClassName={rowClassName} itemClassName={rowClassName}
@ -1249,7 +1250,7 @@ export default class Table extends React.Component<TableProps, object> {
{...itemProps} {...itemProps}
classPrefix={ns} classPrefix={ns}
checkOnItemClick={checkOnItemClick} checkOnItemClick={checkOnItemClick}
key={`foot-${item.index}`} key={`foot-${item.id}`}
itemIndex={rowIndex} itemIndex={rowIndex}
item={item} item={item}
itemClassName={rowClassName} itemClassName={rowClassName}
@ -1492,6 +1493,7 @@ class TableRow extends React.Component<TableRowProps> {
...rest, ...rest,
width: null, width: null,
rowIndex: itemIndex, rowIndex: itemIndex,
colIndex: column.index,
key: column.index, key: column.index,
onAction: this.handleAction, onAction: this.handleAction,
onQuickChange: this.handleQuickChange, onQuickChange: this.handleQuickChange,
@ -1526,6 +1528,7 @@ class TableRow extends React.Component<TableRowProps> {
renderCell(`${itemIndex}/${column.index}`, column, item, { renderCell(`${itemIndex}/${column.index}`, column, item, {
...rest, ...rest,
rowIndex: itemIndex, rowIndex: itemIndex,
colIndex: column.index,
key: column.index, key: column.index,
onAction: this.handleAction, onAction: this.handleAction,
onQuickChange: this.handleQuickChange, onQuickChange: this.handleQuickChange,

View File

@ -340,10 +340,11 @@ export const FormStore = ServiceStore
item = self.items[self.items.length - 1] as IFormItemStore; item = self.items[self.items.length - 1] as IFormItemStore;
options && item.config(options);
// 默认值可能在原型上,把他挪到当前对象上。 // 默认值可能在原型上,把他挪到当前对象上。
setValueByName(item.name, item.value); setValueByName(item.name, item.value);
options && item.config(options);
return item; return item;
} }