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` |