# useModifyForm > Form open/edit/add flow with dialog state and value normalization. ## Purpose Manages form dialog lifecycle including openAdd, openEdit, close operations with automatic value normalization for dict fields and proper cleanup. ## Signature ```typescript export function useModifyForm(options: Options): { flagOnClose: null; flagOnAdd: "add"; flagOnEdit: "edit"; data: { dialog: any; model: Record; }; clearModel: () => void; assignModel: (newModel: Record) => void; openAdd: (toAdd?: Record) => void; openEdit: (toEdit: Record) => void; close: () => void; onConfirm: () => Promise; onCancel: () => Promise; } ``` ## Options Interface ```typescript interface Options { props?: FormProp[]; formRef?: Ref; handleAdd?: (value) => Promise; handleEdit?: (value) => Promise; handleCancel?: () => Promise; handleError?: (kind: "validation" | "internal", err?) => void; handleClose?: () => void; init?: any; extraProps?: string[] | "any" | ((code: string) => boolean); } ``` ## FormProp Interface ```typescript export interface FormProp { code: string; name?: string; i18n?: string; dict?: string; slot?: boolean; [others: string]: any; } ``` ## Dialog Flow ``` openAdd() ──────► dialog = "add" │ ▼ onConfirm() ──► handleAdd(value) ──► close() │ onCancel() ───────────────────────────► close() │ openEdit() ──────► dialog = "edit" │ ▼ onConfirm() ──► handleEdit(value) ──► close() │ onCancel() ───────────────────────────► close() ``` ## Usage Pattern ```typescript // Example: plugs/composables/useModifyForm.ts const form = useModifyForm({ props: [ { code: "name", i18n: "user.name" }, { code: "status", dict: "statusDict" }, ], formRef, init: { status: 1 }, handleAdd: async (value) => { await api.create(value); }, handleEdit: async (value) => { await api.update(value); }, handleClose: () => { formRef.value?.resetFields(); }, }); form.openAdd({ name: "New User" }); form.openEdit({ id: 1, name: "Updated User" }); ``` ## Value Normalization The composable normalizes model values on assignment: 1. **Dict fields**: Parse string dict values to integers if numeric 2. **Extra props**: Filter allowed props based on `extraProps` setting 3. **Null removal**: Exclude null/undefined values from model ## Key Implementation Details 1. **Dialog flag pattern**: Uses string flags (`"add"`, `"edit"`, `null`) to track dialog state 2. **Model clearing**: Uses `clearAndAssign` utility to reset model without losing reactivity 3. **Form validation**: Calls `clearValidate()` on formRef when opening dialogs 4. **Deep copy**: Uses `deepCopy(toRaw())` before passing to handlers ## Dependencies - `vue` - `reactive`, `toRaw` - `plugs/element` - `showMessage` - `plugs/util/objectUtil` - `clearAndAssign`, `deepCopy` ## Anti-patterns - Do not directly mutate `data.model`; use `assignModel()` or `clearModel()` - Do not skip calling `onConfirm()` on submit; dialog state tracking depends on it