Input validation is a key part of shiny applications. If a user is able to add open text input, then it is likely someone will end up entering something that will crash the application. For example incorrectly writing an e-mail address or adding an extra . in a number.
Normally, an application will handle validating the inputs on the server side in R, but it can be cumbersome writing conditions for every possibility and writing an informative message for each potential issue.
Fomantic UI have included a form validation component within their framework which easily does the required checks within the UI, meaning little/no work required on your end.
To add form validation to a Fomantic UI application:
Create a shiny.semantic::form
, adding a set of inputs and giving the form
element a unique ID
Within form
, include an extra argument, form_validation
, using the same ID as the form
it is in
Add a series of field_validation
, each containing a set of field_rule
, making sure the IDs match the inputs
Any server-side functionality relying on the inputs in the form, replace reactive(...)
with eventReactive(input$<form_id>_submit, ...)
(and same with observe
and observeEvent
), as the submit button will only run if the form validation is successful
In-depth documentation is available for each form validation function.
Using the form validation example, we can see the following in the UI:
shiny.semantic::form(
id = "form",
h4(class = "ui dividing header", "User Information"),
shiny.semantic::fields(
class = "two",
shiny.semantic::field(
tags$label("Firstname"),
shiny.semantic::text_input("firstname", value = "", type = "text")
),
shiny.semantic::field(
tags$label("Surname"),
shiny.semantic::text_input("surname", value = "", type = "text")
)
),
fomantic.plus::form_validation(
id = "form",
fomantic.plus::field_validation(
"firstname",
fomantic.plus::field_rule("empty")
),
fomantic.plus::field_validation(
"surname",
fomantic.plus::field_rule("empty"),
fomantic.plus::field_rule("doesntContain", value = "test")
)
)
)
The form itself looks like any standard form in {shiny.semantic}
, with an exception that we have included an ID to the form. This is important for the validation to know which form to validate.
The validation above is looking for the following:
If all conditions pass, then the button will enable events to be run server-side, otherwise an error message will appear in the UI (as above) telling the user all of the mistakes that have been made. Including a label for each input is important, as this is how the validation messages will return useful messages to the user.
If you would rather have the message next to the wrong input rather than a message box use inline = TRUE
.
There are two types of rule, ones that require a value, and ones that don’t require a value.
The following rules do not require a value:
"empty"
- Checks that a certain input is not empty"checked"
- Checks that a checkbox input has been checked"email", "url", "creditCard"
- Checks that an input is in a specific format"number", "decimal", "integer"
- Checks that a number is any numeric value. NB even though these are numeric values, they must still be text_input
s
"x..y"
where x
is the minimum value and y
is the maximum valueThe following rules do require a value:
"regExp"
- Matches input against a regular expression"contains", "doesntContain", "containsExactly", "doesntContainExactly"
- Matches input against a fixed string"is", "not", "isExactly", "notExactly"
- Matches input exactly against a fixed string
"Exactly"
is included, the term is case sensitive, otherwise it is case insensitive"minLength", "exactLength", "maxLength"
- Checks the number of characters used in an input"match", "different"
- Matches the input against another input the form"minCount", "exactCount", "maxCount"
- Checks the number of selections made in a multiple select inputFor a list of all available rules, check the details section in ?fomantic.plus::field_rule
or the Fomantic UI Website
The validation messages from Fomantic are pretty clear, but if you want to write a more specific message then that is possible using the prompt
argument in field_rule
.
For example if you require a password with a non-word character you might use:
field_rule(
"regExp",
prompt = "Password must contain at least one special character",
value = "\\W"
)
There are also some special phrases that can be used for more dynamic prompts:
{name}
- The current text of a field’s label, or if no label available its placeholder text{identifier}
- The identifier used to match the field{value}
- The current field value{ruleValue}
- The value passed to a rule, for example field_rule("minLength", value = 100)
would set this value to 100field_rule(
"is",
prompt = "You entered {value}, we were looking for {ruleValue}",
value = "right"
)