Skip to main content

Submission

In Formitiva, following operations are performed to make a sucess submission

  • Field validation when fieldValidationMode is onSubmission
  • Form validation
  • Form submit handler process
  • Errors reports

Handle Field Validation​

When fieldValidationMode is onSubmission, all field validation will be performed

  • Field type built-in validation
    Inlcude the registered correspodent type validation for custom component
  • Filed Custom validation

Field Validation Reference​


Handle Form Validation​

Form validation performs cross-fields check and time consuming checks, include asynchronous checks.

Handle submission​

Formitiva supports two common approaches:

  1. Pass an onSubmit function directly to Formitiva (simplest).
  2. Use the submission registration system so each definition can reference a handler by name.

Handler signature​

export type FormSubmissionHandler = (
definition: FormitivaDefinition,
instanceName: string | null,
valuesMap: Record<string, FieldValueType | unknown>,
t: TranslationFunction,
) => string[] | undefined | Promise<string[] | undefined>;
  • Parameters
    • definition : definition data
    • instanceName : the name of instance which is in editing
    • valuesMap : the property name to value map
    • t : translation function for localized error messages
  const alertSubmission: FormSubmissionHandler = (
definition, instanceName, valuesMap, t
): string[] | undefined => {
const instance = {
name: instanceName || "Unnamed Instance",
version: (definition as any)?.version || "",
definition: (definition as any)?.name || "",
values: valuesMap as Record<string, FieldValueType | unknown>,
};
const instanceStr = JSON.stringify(instance, null, 2);
alert(instanceStr);
return undefined;
};

Option A — submit via onSubmit​

Registration​

export function registerSubmissionHandler(
submitterName: string,
fn: FormSubmissionHandler) : void
  • Parameters
    • submitterName : submission registered handler name
    • fn : submission handler

Examples​

React​
import * as React from 'react';
import { Formitiva } from '@formitiva/react';

export function App() {
return (
<Formitiva
definitionData={definition}
onSubmit={alertSubmission} // See alertSubmission defined above
/>
);
}
Vue​
<script setup lang="ts">
import { Formitiva } from '@formitiva/vue';
</script>

<template>
<Formitiva :definition-data="definition" :on-submit="alertSubmission" />
</template>
Angular​
import { Component } from '@angular/core';
import { FormitivaComponent } from '@formitiva/angular';

@Component({
selector: 'app-root',
standalone: true,
imports: [FormitivaComponent],
template: `<fv-formitiva [definitionData]="definition" [onSubmit]="alertSubmission"></fv-formitiva>`,
})
export class AppComponent {
definition = definition;
alertSubmission = alertSubmission; // See alertSubmission defined above
}
Vanilla JS​
import { Formitiva } from '@formitiva/vanilla';

const form = new Formitiva({
definitionData: definition,
onSubmit: alertSubmission, // See alertSubmission defined above
});
await form.mount(document.getElementById('app')!);

Option B — register a submission handler​

This option is very useful when you have multiple forms and each form has different submission process. The submission handlers can be registered and reference in form defintion without passing specific submission by onSubmit.

Reference a handler in your definition using submitHandlerName.​

const definition = {
name: 'contactForm',
version: '1.0.0',
displayName: 'Contact Form',
submitHandlerName: 'exampleSubmitHandler',
properties: [
{ name: 'name', type: 'text', displayName: 'Name', required: true },
{ name: 'email', type: 'email', displayName: 'Email', required: true },
{ name: 'message', type: 'multiline', displayName: 'Message', minHeight: '80px' },
],
};

Register a handler with the same name.​

export function registerSubmissionHandler(
submitterName: string,
fn: FormSubmissionHandler) : void
  • Parameters
    • submitterName : submission registered handler name
    • fn : submission handler

Examples​

React​
import { useEffect } from 'react';
import { Formitiva, registerSubmissionHandler } from '@formitiva/react';

export function App() {
useEffect(() => {
registerSubmissionHandler('exampleSubmitHandler', alertSubmission); // see alertSubmission defined above
}, []);

// Formitiva will get submission handler by submitHandlerName and invoke it automatically
return <Formitiva definitionData={definition} />;
}
Vue​
<script setup lang="ts">
import { Formitiva, registerSubmissionHandler } from '@formitiva/vue';

// Register once at module load (outside setup, or in onMounted)
registerSubmissionHandler('exampleSubmitHandler', alertSubmission); // see alertSubmission defined above
</script>

<template>
<Formitiva :definition-data="definition" />
</template>
Angular​
import { Component } from '@angular/core';
import { FormitivaComponent, registerSubmissionHandler } from '@formitiva/angular';

// Register once at module load
registerSubmissionHandler('exampleSubmitHandler', alertSubmission); // see alertSubmission defined above

@Component({
selector: 'app-root',
standalone: true,
imports: [FormitivaComponent],
template: `<fv-formitiva [definitionData]="definition"></fv-formitiva>`,
})
export class AppComponent {
definition = definition;
}
Vanilla JS​
import { Formitiva, registerSubmissionHandler } from '@formitiva/vanilla';

// Register once at module load
registerSubmissionHandler('exampleSubmitHandler', alertSubmission); // see alertSubmission defined above

const form = new Formitiva({ definitionData: definition });
await form.mount(document.getElementById('app')!);

### Priority of Option A and Option B
`onSubmit` callback has higher priority than registration submission handler. When `onSubmit` is specified, registrated submission handler will be skipped.

## Value Types (valuesMap)

The table below shows common definition field types and the runtime value type you'll receive in the `valuesMap` inside submission handlers.

| name / definition type | definition type string(s) | submission type | example |
|---|---:|---|---|
| Text / Multiline / Email / URL | `text`, `multiline`, `email`, `url` | string | `name: "Alice"` |
| Integer | `int` | number (integer) | `count: 5` |
| Float / Number | `float`, `number` | number (float) | `price: 12.5` |
| Checkbox / Switch | `boolean` | boolean | `subscribe: true` |
| Dropdown / Radio | `dropdown`, `enum` | string (selected value) | `country: "US"` |
| Multi-select | `select-selection` (multi) | string[] | `tags: ["react","forms"]` |
| Integer array | `int-array` | number[] | `scores: [10,20]` |
| Float array | `float-array` | number[] | `ratios: [0.1,0.2]` |
| Unit / Tuple | `unit`, (custom) | [number, string] | `dimension: [100, "px"]` |
| Date / Time | `date`, `time` | string (ISO date/time) or Date (component-dependent) | `birthday: "2023-05-01"` |
| File | `file` | File (browser File object) | `avatar: File` |
| Files (multiple) | `file` with `multiple: true` | File[] | `attachments: File[]` |
| Button / Description | Image | `button`, `description`, `image` | undefined | `button: undefined` |