taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit 05a762edf2e5b26be763573476c5721c3200978f
parent b842a4cbd9f60545171c479ccf95fdf591edb8f8
Author: Sebastian <sebasjm@gmail.com>
Date:   Tue,  2 Jan 2024 18:18:43 -0300

first version of dynamic forms

Diffstat:
Adesign-documents/054-dynamic-form.rst | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdesign-documents/index.rst | 1+
2 files changed, 183 insertions(+), 0 deletions(-)

diff --git a/design-documents/054-dynamic-form.rst b/design-documents/054-dynamic-form.rst @@ -0,0 +1,182 @@ +DD 53: Dynamic Web Form +####################### + +Summary +======= + +This document defines an approach of a dynamic web form. + +Motivation +========== + +Currently when a web app need a form a new page needs to be coded +with HTML, css and js. +Exchange AML have multiple forms and different instance may have +different form depending on the jurisdiction. + +Requirements +============ + +A form consist of a layout and a set of fields. +Layout requirements: + +* **editable by system admin**: if new form is required system admin should +be able to create a new form. + +* **accesibility**: forms should satisfy accesibility level AA. + +* **responsive**: forms should work on all devices. + +* **metadata**: generated info by the form should contain enough information +to handle multiple version of the form. + +Fields requirements: + +* **validations**: each field may required custom validation + +* **custom data type**: a field may consist of a list, string, number or a complex +composite structure. + + +Proposed Solutions +================== + +Forms are initialized with the follow structure: + +``` +interface FormType<T extends object> { + value: Partial<T>; + initial?: Partial<T>; + readOnly?: boolean; + onUpdate?: (v: Partial<T>) => void; + computeFormState?: (v: Partial<T>) => FormState<T>; +} +``` + +`T`: is the type of the result object +`value`: is a reference to the current value of the result +`readOnly`: when true, fields won't allow input +`onUpdate`: notification of the result update +`computeFormState`: compute a new state of the form based on the current value + +Form state have the same shape of `T` but every field type is `FieldUIOptions`. + +Fields type can be: + * strings + * numbers + * boolean + * arrays + * object + +The field type `AmountJson` and `AbsoluteTime` are opaque since field is used as a whole. + +The form can be instanciated using + +``` +import { FormProvider } from "@gnu-taler/web-util/browser"; +``` + +Then the field component can access all the properties by the `useField(name)` hook, +which will return + +``` +interface InputFieldHandler<Type> { + value: Type; + onChange: (s: Type) => void; + state: FieldUIOptions; + isDirty: boolean; +} +``` + +`value`: the current value of the field +`onChange`: a function to call anytime the user want to change the value +`state`: the state of the field (hidden, error, etc..) +`isDirty`: if the user already tried to change the value + +A set of common form field exist in `@gnu-taler/web-util`: + + * InputAbsoluteTime + * InputAmount + * InputArray + * InputFile + * InputText + * InputToggle + +and should be used inside a `Form` context. + +``` +function MyFormComponent():VNode { + return <FormProvider ...> + <InputAmount name="amount" /> + <InputText name="subject" /> + <button type="submit"> Confirm </button> + </FormProvier> +} + +Example +------------------------- + +For example, for the form shape: + +``` +type theFormType = { + name: string, + age: number, + savings: AmountJson, + nextBirthday: AbsoluteTime, + pets: string[], + addres: { + street: string, + city: string, + } +} +``` + +one example instance of the form: + +``` +const theFormValue = { + name: "Sebastian", + age: 15, + pets: ["dog","cat"], + address: { + street: "long", + city: "big", + } +} +``` + +and one example valid state + +``` +function computeFormStateBasedOnFormValues(formValues): { + //returning fixed state as an example + //the return state will be commonly be computed from the values of the form + return { + age: { + hidden: true, + }, + pets: { + disabled: true, + elements: [{ + disabled: false, + }], + }, + address: { + street: { + required: true, + error: "the street name was not found", + }, + city: { + required: true, + }, + }, + } +} +``` + + + +Q / A +===== + diff --git a/design-documents/index.rst b/design-documents/index.rst @@ -65,4 +65,5 @@ Design documents that start with "XX" are considered deprecated. 051-fractional-digits.rst 052-libeufin-bank-2fa.rst 053-wallet-ui.rst + 054-dynamic-form.rst 999-template