Custom field bindings
Custom bound fields simplify connecting UI controls to Appframe data objects. This guide builds a BoundNumberInput with useField, demonstrates validation, and shows how to commit changes.
Building a number input
Define a reusable NumberInput component that wraps MUI's TextField, handles step buttons, and exposes value and onChange props.
export type NumberInputProps = TextFieldProps & {
step?: number;
value: number | null;
onChange: (value: number | null) => void;
};Binding with useField
useFieldexport function BoundNumberInput({ field, ...props }: { field: string } & Omit<NumberInputProps, "value" | "onChange">) {
let { value, onChange, onKeyDown, error } = useField<number>(field);
return (
<NumberInput
{...props}
value={value}
onChange={(v) => onChange({ target: { value: v } })}
onKeyDown={onKeyDown}
error={!!error}
helperText={error}
/>
);
}Validation
useField attempts to coerce the input to the field's type. Invalid values set the error string so the component can display feedback. Pressing Escape cancels edits via the returned onKeyDown handler.
Commit operations
The hook writes values into the bound data object. Call dataObject.endEdit() to persist changes to the server. In accounting-products, the product page commits pending changes before loading a new record:
Example usage
The timekeeping-timereg app uses the component in its timesheet form:
Last updated
Was this helpful?