Advanced Web Form Creation

Though (RefLink[FormFunction, paclet:ref/FormFunction]) and (RefLink[FormObject, paclet:ref/FormObject]) provide a very terse interface for creating simple web forms, this tutorial will cover the methods and options necessary for the creation of more advanced web forms.

Appearance Rules

(RefLink[FormFunction, paclet:ref/FormFunction]) and (RefLink[FormObject, paclet:ref/FormObject]) take the option (RefLink[AppearanceRules, paclet:ref/AppearanceRules]), which can be used to specify various parts of the form, such as the title and the way the elements are displayed in each field.

Title and Description

You can use (RefLink[AppearanceRules, paclet:ref/AppearanceRules]) with "Title" and "Description" to add a title and a subtitle to your form.

CloudDeploy[FormFunction["city" -> "City", #city&,AppearanceRules-> <|"Title" -> "What's your city", "Description" -> "This form allows you to input your city"|>]]

SubmitLabel and NextLabel

You can use "SubmitLabel" to change the text displayed in the button at the bottom of the form.

CloudDeploy[FormFunction["city" -> "City", #city&,AppearanceRules-> <|"SubmitLabel" -> "Go!"|>]]

Similarly, "NextLabel" can be used to customize the text in all the fields except for the last in a multipage form.

Non-textual Values

Most of the fields in (RefLink[AppearanceRules, paclet:ref/AppearanceRules]) do not need to be strings.

CloudDeploy[FormFunction["animal" -> "Animal", #animal&,AppearanceRules-> <|"SubmitLabel" -> , "Title" -> Import["ExampleData/turtle.jpg"], "Description"-> Style["What is this animal?", Blue] |>]]

RequiredFieldIndicator

"RequiredFieldIndicator" applies a function to the labels of the required fields.

CloudDeploy[FormFunction[{"required" -> "Number", "optional" -> "Number" -> 0}, Identity,AppearanceRules-> <|"RequiredFieldIndicator" -> Function[Style[#,Red]] |>]]

ItemLayout

"ItemLayout" can be used to decide the way the elements are displayed in a grid. Empty rows and columns are automatically elided.

The default "Horizontal" corresponds to a 2×2 grid.

CloudDeploy[FormFunction[{"x" -> <|"Help" -> "type here"|>, "y" -> "Integer"}, Identity,AppearanceRules-> <|"ItemLayout" -> "Horizontal" |>]["x" -> "text"]]

"Inline" corresponds to all the elements laid out on the same row.

CloudDeploy[FormFunction[{"x" -> <|"Help" -> "type here"|>, "y" -> "Integer"}, Identity,AppearanceRules-> <|"ItemLayout" -> "Inline" |>]["x" -> "text"]]

"Vertical" corresponds to all the elements laid out on the same column.

CloudDeploy[FormFunction[{"x" -> <|"Help" -> "type here"|>, "y" -> "Integer"}, Identity,AppearanceRules-> <|"ItemLayout" -> "Vertical" |>]["x" -> "text"]]

Multipage Forms

Forms can span multiple pages; an additional list in the first argument specifies a multipage form.

CloudDeploy[FormFunction[{{"first" -> "Integer"},{"second" ->"Integer"}}, Identity]]

All pages except the first can be specified as pure functions; doing so will let you have new pages that depend on the old ones.

CloudDeploy[FormFunction[{{"label" -> "String"},{{"second",#label }->"Integer"}&}, Identity]]

You can use this technique to create new fields programmatically.

CloudDeploy[FormFunction[{{"number" -> "Integer"},Table["x" <> ToString[i] -> "String",{i, #number}]&}, Identity]]

Note that fields in different pages can have the same key. If this happens, the newest value will overwrite the old.

Dynamic Forms

Sometimes it is useful to define a form where one field depends on another and where both appear on the same page. This can be done by using the Wolfram Language templating language, with symbols such as (RefLink[TemplateSlot, paclet:ref/TemplateSlot]).

CloudDeploy[FormFunction[{"state" -> "USState", "county" -> TemplateSlot["state"][(EntityProperty["subdivisions", EntityProperty["AdministrativeDivision","Subdivisions"], "EntityProperty[\"AdministrativeDivision\", \"Subdivisions\"]"])]}, Identity]]

Fields that depend on other fields are automatically hidden until there is enough information to display them, while fields that have other fields depending on them automatically submit when filled in.

Autosubmitting

You can force a field to automatically submit the whole form when it is filled in by wrapping it with (RefLink[AutoSubmitting, paclet:ref/AutoSubmitting]).

CloudDeploy[FormFunction[{"x" -> AutoSubmitting["Integer"], "y" -> "Integer"}, Identity]]

Note that when selecting the second field after typing in the first, the whole form is submitted, resulting in a failure message below the second field.

RepeatingElement and CompoundElement

Sometimes it is useful to have a variable number of fields in a form. Use (RefLink[RepeatingElement, paclet:ref/RepeatingElement]) to repeat a field.

CloudDeploy[FormFunction["field" -> RepeatingElement["String", {2,{1, 5}}]]]

Using the second argument of (RefLink[RepeatingElement, paclet:ref/RepeatingElement]), you can make a subfield depend on its index.

CloudDeploy[FormFunction["number of occupants" -> RepeatingElement[<|"Interpreter" -> "Integer", "Label" :> "room " <> ToString[i]|>, {{i,2},{1, 5}}]]]

(RefLink[CompoundElement, paclet:ref/CompoundElement]) can be used with (RefLink[RepeatingElement, paclet:ref/RepeatingElement]) to create a table of fields.

CloudDeploy[FormFunction["names" -> RepeatingElement[CompoundElement[<|"first"-> "String", "last" -> "String"|>]]]]

The (RefLink[AppearanceRules, paclet:ref/AppearanceRules]) options "AddLabel" and "DeleteLabel" can be used to customize the labels of the buttons in a (RefLink[RepeatingElement, paclet:ref/RepeatingElement]).

CloudDeploy[FormFunction["field" -> RepeatingElement["String"],AppearanceRules -> <|"AddLabel"-> "Add", "DeleteLabel" -> "Delete"|>]]