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>
<Content />
<Text />
<Fieldset>
<Text />
</Fieldset>
</Page>
<Page>
<Content />
</Page>
</Root>
</Formally>
);
Note: the props of <Root>
, <Page>
, <Content>
, <Fieldset>
, and <Text>
have been ommited for brevity in this example as it's trying to show the overall
form structure.
Rules
- There must be one
<Root>
component inside<Formally>
- The only children of
<Root>
must be<Page>
s.
The children
define all the content and fields in the form.
Although children
can vary at runtime instead dynamic behaviour should be done by:
- Encoding dynamic behaviour such as conditional logic in the
data
, or; - Using props (eg,
onValidation
in<Formally onValidation={myCustomValidation}) />
);
Creating children
Use these components exported from formally
:
<Root>
<Page>
<Text>
<DateInput>
<Range>
<AutoSuggest>
<Radios>
<Checkboxes>
<Select>
<Upload>
<Conditional>
<Repeater>
<Fieldset>
<Content>
<AnswerSummary>
<PopOutContent>
<CustomField>
<OptionRoot>
<OptionGroup>
<Option>
Be sure to read the relevant documentation page to do with each component.
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 form title might use this as,
<Root 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.
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 e.g. a label
<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.
Ids
Every Formally component needs an id
which is unique within the form.
When using the Form Builder it's usually not necessary to think about component id
s (they're autogenerated),
however when using the SDK it becomes necessary.
When Formally components are under <Formally>
then an id is autogenerated and developers don't need to
provide this prop, however if Formally components are included from other components, ie in this situation:
export default () => (
<Formally>
<Range />
<MyWrapper />
</Formally>
);
const MyWrapper = () => <Text />;
The <Range />
wouldn't need an id
prop but the <Text>
would.
A run-time exception will be thrown if the component doesn't have an id.
Stable Ids
It's always possible to provide an id
prop, and this is referred to as a 'stable id'
because it's not randomly autogenerated.
Some features of Formally refer to other components by id
and a stable id should be used.
For example, a <Conditional>
(which conditionally displays components) might have a rule
referring to a <Text>
by id
.