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 {
onCheck: (item: IItem) => void;
itemIndex?: number;
multiple?: boolean;
highlightClassName?: string;
hideCheckToggler?: boolean;
@ -191,7 +192,7 @@ export class Card extends React.Component<CardProps> {
}
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 $$id = field.$$id ? `${field.$$id}-field` : '';
@ -213,6 +214,8 @@ export class Card extends React.Component<CardProps> {
},
{
className: cx('Card-fieldValue', field.className),
rowIndex: itemIndex,
colIndex: key,
value: field.name ? resolveVariable(field.name, data) : undefined,
popOverContainer: this.getPopOverContainer,
onAction: this.handleAction,

View File

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

View File

@ -71,7 +71,9 @@ export default class FormTable extends React.Component<TableProps, TableState> {
"deleteApi"
];
entries:Array<any> = [];
entries:Map<any, number>;
entityId: number = 0;
subForms:any = {}
constructor(props:TableProps) {
super(props);
@ -80,12 +82,51 @@ export default class FormTable extends React.Component<TableProps, TableState> {
editIndex: -1
};
this.entries = new Map();
this.buildItemProps = this.buildItemProps.bind(this);
this.confirmEdit = this.confirmEdit.bind(this);
this.cancelEdit = this.cancelEdit.bind(this);
this.handleSaveTableOrder = this.handleSaveTableOrder.bind(this);
this.handleTableSave = this.handleTableSave.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>) {
@ -487,19 +528,17 @@ export default class FormTable extends React.Component<TableProps, TableState> {
}
removeEntry(entry:any) {
const idx = this.entries.indexOf(entry);
~idx && this.entries.splice(idx, 1);
if (this.entries.has(entry)) {
this.entries.delete(entry);
}
}
getEntryId(entry:any) {
let idx = this.entries.indexOf(entry);
if (!~idx) {
idx = this.entries.length;
this.entries.push(entry);
if (!this.entries.has(entry)) {
this.entries.set(entry, this.entityId++);
}
return String(idx);
return String(this.entries.get(entry));
}
render() {
@ -530,7 +569,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
getEntryId: this.getEntryId,
onSave: this.handleTableSave,
onSaveOrder: this.handleSaveTableOrder,
buildItemProps: this.buildItemProps
buildItemProps: this.buildItemProps,
quickEditFormRef: this.subFormRef
})}
</div>
);;

View File

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

View File

@ -62,6 +62,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
this.overlayRef = this.overlayRef.bind(this);
this.handleWindowKeyPress = this.handleWindowKeyPress.bind(this);
this.handleWindowKeyDown = this.handleWindowKeyDown.bind(this);
this.formRef = this.formRef.bind(this);
this.state = {
isOpened: false,
@ -80,6 +81,22 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
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) {
const ns = this.props.classPrefix;
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,
onAction: this.handleAction,
onChange: null,
ref: this.formRef,
popOverContainer: popOverContainer ? () => this.overlay : null,
})}
</div>
@ -388,6 +406,7 @@ export const HocQuickEdit = (config: Partial<QuickEditConfig> = {}) => (Componen
{render('inline-form', this.buildSchema(), {
wrapperComponent: 'div',
className: cx('Form--quickEdit'),
ref: this.formRef,
onChange: (values: object) =>
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) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [
<TableRow
{...itemProps}
classPrefix={ns}
checkOnItemClick={checkOnItemClick}
key={item.depth > 1 ? item.id : item.key}
key={item.id}
itemIndex={rowIndex}
item={item}
itemClassName={rowClassName}
@ -1249,7 +1250,7 @@ export default class Table extends React.Component<TableProps, object> {
{...itemProps}
classPrefix={ns}
checkOnItemClick={checkOnItemClick}
key={`foot-${item.index}`}
key={`foot-${item.id}`}
itemIndex={rowIndex}
item={item}
itemClassName={rowClassName}
@ -1492,6 +1493,7 @@ class TableRow extends React.Component<TableRowProps> {
...rest,
width: null,
rowIndex: itemIndex,
colIndex: column.index,
key: column.index,
onAction: this.handleAction,
onQuickChange: this.handleQuickChange,
@ -1526,6 +1528,7 @@ class TableRow extends React.Component<TableRowProps> {
renderCell(`${itemIndex}/${column.index}`, column, item, {
...rest,
rowIndex: itemIndex,
colIndex: column.index,
key: column.index,
onAction: this.handleAction,
onQuickChange: this.handleQuickChange,

View File

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