Custom Forms
Forms can be programatically made as children
of <Formally>
.
This is an alternative to the formBuilderId
prop (which loads forms from GetFormally.com).
Use of children
prop
import { Formally, Root, Page, Content, Text, Fieldset } from 'formally';
export const MyForm = () => (
<Formally>
<Root>
<Page id="page1">
<Content id="content1" />
<Text id="text1" />
<Fieldset id="fieldset1">
<Text id="test2" />
</Fieldset>
</Page>
<Page id="page2">
<Content id="content2" />
</Page>
</Root>
</Formally>
);
Rules
- There must be one
<Root>
component inside<Formally>
- The only children of
<Root>
must be<Page>
s. - Every component must have a unique
id
prop (except<Root>
).
The children
define all the content and fields in the form.
Although children
can vary at runtime it's preferable:
- Encoding dynamic behaviour in
<Conditional>
rule, or; - Using
<Formally>
props (eg,onValidation
);
Localisation / Translations
Locales are languages with optional localised variations, such as "New Zealand English", "Australian English", and plain "English".
Formally components can contain multiple locales, represented as an object where the keys are locale ids.
{
en: 'Welcome to the form',
'en-NZ': 'Welcome / Kia ora',
'en-AU': 'Gidday',
mi: 'Kia ora',
}
A page title might use this as,
<Page id="myPage1" titleHtml={{
'en': 'Welcome to the form',
'en-NZ': 'Welcome / Kia ora',
'en-AU': 'Gidday',
'mi': 'Kia ora',
}}>
These locale ids are the same as the
lang
attribute value in HTML
which comes from RFC 5646: Tags for Identifying Languages (aka BCP 47).
After these strings are added the locale must be enabled with the locales
prop of
<Root>
e.g. locales={['en', 'en-NZ', 'en-AU', 'mi']
. The order of this list controls
the list of languages in the locale picker UI.
If a user has their browser configured with a locale language preference that will be used. If a user's browser doesn't express a preference then the first locale id will be used.
Removing a locale id from locales
is a quick way of disabling a locale.
Ids
Every Formally component needs an id
which is unique within the form.
A run-time exception will be thrown if the component doesn't have an id.
Localisation: HTML or Plaintext
Formally uses a structured naming convention to indicate whether the localised string is
HTML or plaintext. If the prop name ends in Html
it's HTML, otherwise it's plaintext.
There are also TypeScript definitions that indicate whether a prop is LocalisedHtml
or LocalisedPlaintext
.
The reason for HTML is so that translations can use the full range of accessibility
features such as <abbr>
. For example,
<Text
hintHtml={{
en: 'See <abbr title="Mozilla Developer Network">MDN</abbr> for more',
}}
/>
Important: When providing HTML strings it is the responsibility of the developer to ensure these strings are safely sanitised to prevent malicious use such as XSS exploits. Formally does not sanitise HTML given to it.
Further, because arbitrary HTML is allowed it is up to the developer to test their
configuration. HTML is a powerful feature that is easy to misuse. For example, an
HTML string of 'my label <a href="https://example.com/">a link</a>'
when used as
<label>
content would have multiple clickable areas (clicking the <label>
or
clicking the link), which is unlikely to be intended. When in doubt, prefer to sanitise
HTML as plaintext.