# ElementForm



The `ElementForm` is a highly versatile component designed to create
or update any individual “element” within a quote, such as a vehicle,
driver, or insured property. It dynamically renders form fields based on
the provided `elementModel` and can handle complex data dependencies
through constraint evaluation, making it a cornerstone of the quoting
process.

Usage [#usage]

To render an `ElementForm`, you need to provide the specific
`elementModel` that defines its structure, the `element` object
being edited, the overall `dataModel`, and a `timezone`. For
advanced dependency-driven logic, a `dependencyMap` and a
`getEvaluatedConstraints` function are also required.

```ts
import { ElementForm } from '@socotra/ec-react-components';
import {
    ElementConfig,
    ElementResponse,
    DataModel,
    DependencyMapResponse,
    EvaluateConstraintsResponse,
    EvaluateConstraintsRequest,
} from '@socotra/ec-react-schemas';

// Example Usage
const MyElementEditor = ({
    elementModel,
    element,
    dataModel,
    dependencyMap,
}: {
    elementModel: ElementConfig,
    element: ElementResponse,
    dataModel: DataModel,
    dependencyMap: DependencyMapResponse,
}) => {
    const handleSubmit = (elementRequest) => {
        console.log('Element Update Request:', elementRequest);
        // Handle API call to update the element
    };

    const handleEvaluateConstraints = async (
        request: EvaluateConstraintsRequest,
    ): Promise<EvaluateConstraintsResponse | undefined> => {
        console.log('Evaluating constraints for:', request);
        // Replace with your actual API call
        return fetch(/*...- /constraints/evaluate ...*/).then(res => res.json());
    };

    return (
        <ElementForm
            elementModel={elementModel}
            element={element}
            dataModel={dataModel}
            timezone='America/New_York'
            handleSubmit={handleSubmit}
            dependencyMap={dependencyMap}
            getEvaluatedConstraints={handleEvaluateConstraints}
            submitButtonText='Update Element'
        />
    );
};
```

Props [#props]

| Prop                      | Type                                                                                        | Description                                                                                                    | Default      |
| ------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------ |
| `elementModel`            | `ElementConfig`                                                                             | The configuration object from the data model that defines this element’s fields and structure.                 | **Required** |
| `element`                 | `ElementResponse`                                                                           | The element object from the quote that is being edited.                                                        | **Required** |
| `dataModel`               | `DataModel`                                                                                 | The entire resolved data model.                                                                                | **Required** |
| `timezone`                | `string`                                                                                    | The timezone for the quote or policy, essential for correct date/time handling.                                | **Required** |
| `handleSubmit`            | `(data: ElementRequest) => void`                                                            | An optional callback triggered on submit with the `ElementRequest` payload.                                    | `undefined`  |
| `dataTypes`               | `DataTypeConfigRecord`                                                                      | Custom data types referenced by the element model.                                                             | `undefined`  |
| `coverageTerms`           | `CoverageTermsConfigRecord`                                                                 | The configuration for coverage terms available to this element.                                                | `undefined`  |
| `quote`                   | `QuoteResponse`                                                                             | The full quote object, used to enable conditional field rendering based on the state of other elements.        | `undefined`  |
| `dependencyMap`           | `DependencyMapResponse`                                                                     | An optional map of field dependencies. Required to enable the constraint evaluation feature.                   | `undefined`  |
| `getEvaluatedConstraints` | `(request, tenantLocator, locator) => Promise&lt;EvaluateConstraintsResponse \| undefined>` | An optional async function that calls the backend to evaluate constraints. Required for constraint evaluation. | `undefined`  |
| `hideAllFields`           | `boolean`                                                                                   | If `true`, hides all data fields in the form.                                                                  | `false`      |
| `hideCoverageTerms`       | `boolean`                                                                                   | If `true`, hides the coverage terms section, even if they are defined in the model.                            | `false`      |
| `disabled`                | `boolean`                                                                                   | When true, disables the entire form.                                                                           | `false`      |
| `isSubmitting`            | `boolean`                                                                                   | When true, disables the form to indicate a submission is in progress.                                          | `false`      |
| `submitButtonText`        | `string`                                                                                    | Custom text for the submit button.                                                                             | `'Update'`   |

…and other standard form control props (`preventFormResetOnDisabled`,
`validateOnSubmit`, `hideSubmitButton`, `id`, `titles`).

State Management [#state-management]

`ElementForm` relies on internal state managed by `useState` and
`useEffect` hooks.

* **Data Initialization:** Form data is initialized using the
  `getDefaultElementValues` utility, which populates fields from the
  `element` response and its associated `coverageTerms`.
* **Constraint Evaluation:** The mechanism is identical to
  `InitializedTransactionForm`. When a user changes a field that other
  fields depend on (as defined in `dependencyMap`), a `useEffect`
  hook calls the `getEvaluatedConstraints` function. The response is
  stored in an `evaluatedConstraints` state variable, which triggers a
  schema regeneration to update and disable dependent fields. The
  `evaluatedConstraints` are cleared on any subsequent form change to
  allow for re-evaluation.
* **Prop Synchronization:** The component keeps a local copy of the
  `element` and `coverageTerms` props in state. A `useEffect` hook
  checks for differences between the incoming props and the local state.
  If a change is detected (e.g., after a parent component saves data),
  the form’s data is re-initialized to reflect the new state.

Validation [#validation]

Validation is performed client-side using [Ajv ](https://ajv.js.org/).

* The validation schema is dynamically constructed by the
  `dataModelToJSONSchema` utility. This function considers the
  `elementModel`, `dataTypes`, `timezone`, and, importantly, the
  current `quote` object.
* When constraint evaluation is active, the schema is augmented with the
  `dependencyMap` and the latest `evaluatedConstraints` response,
  which allows `Ajv` to enforce that dependent fields are read-only
  and have the correct calculated values.
* The visibility of fields (controlled by `hideAllFields` and
  `hideCoverageTerms`) is also reflected in the final schema
  structure.
* The `translateError` utility is used to convert validation errors
  into user-friendly messages.

Labels and Translations [#labels-and-translations]

The text for UI labels and validation messages can be customized.

**UI Labels**

Labels for sections and fields can be overridden by passing a `titles`
object prop.

| Key             | Description                             | Default Value      |
| --------------- | --------------------------------------- | ------------------ |
| `coverageTerms` | Title for the “Coverage Terms” section. | `'Coverage Terms'` |
| `truthyLabel`   | Text for a “true” boolean value.        | `'Yes'`            |
| `falsyLabel`    | Text for a “false” boolean value.       | `'No'`             |
