Inputs Layout and Forms

2024-05-27

Since {shinyMobile} 2.0.0, the layout of inputs has been improved. It is recommended that multiple inputs are wrapped inside a f7List() to benefit from styling options such as inset, strong, dividers,and outline. Also introduced since 2.0.0 are the functions f7Form() and updateF7Form() to gather inputs in the same form and update them in batch or only selected ones.

Inputs Layout

In your app you can have many different inputs. Most of the time these inputs are nicely displayed together so the users can make her/his selections. With the many styling options that Framework7 provides, it can be quite a hassle if you would have to style them all individually. Luckily, you don’t have to! You can wrap them inside a f7List() to benefit from the styling options, styling them all at once (see below with the iOS skin):

library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    options = list(dark = FALSE, theme = "ios"),
    title = "Inputs Layout",
    f7SingleLayout(
      navbar = f7Navbar(
        title = "Inputs Layout",
        hairline = FALSE
      ),
      f7List(
        inset = TRUE,
        dividers = TRUE,
        strong = TRUE,
        outline = FALSE,
        f7Text(
          inputId = "text",
          label = "Text input",
          value = "Some text",
          placeholder = "Your text here"
        ),
        f7TextArea(
          inputId = "textarea",
          label = "Text area input",
          value = "Some text",
          placeholder = "Your text here"
        ),
        f7Select(
          inputId = "select",
          label = "Make a choice",
          choices = 1:3,
          selected = 1
        ),
        f7AutoComplete(
          inputId = "myautocomplete",
          placeholder = "Some text here!",
          openIn = "dropdown",
          label = "Type a fruit name",
          choices = c(
            "Apple", "Apricot", "Avocado", "Banana", "Melon",
            "Orange", "Peach", "Pear", "Pineapple"
          )
        ),
        f7Toggle(
          inputId = "toggle",
          label = "Toggle me"
        ),
        f7Picker(
          inputId = "picker",
          placeholder = "Some text here!",
          label = "Picker Input",
          choices = c("a", "b", "c"),
          options = list(sheetPush = TRUE)
        ),
        f7DatePicker(
          inputId = "date",
          label = "Pick a date",
          value = Sys.Date()
        ),
        f7ColorPicker(
          inputId = "mycolorpicker",
          placeholder = "Some text here!",
          label = "Select a color"
        )
      )
    )
  ),
  server = function(input, output) {
  }
)

By default inputs list is displayed with stacked labels. Stacked labels always appear on top of the input.


The following inputs are supported:


This doesn’t mean you can’t use other inputs, but they may look a bit off. In this case you can take them out of f7List() and style them manually with the available options in the input. For example, f7CheckboxGroup() and f7Radio() are not supported in f7List() but can be styled to look similar:

library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    options = list(dark = FALSE, theme = "ios"),
    title = "Inputs Layout",
    f7SingleLayout(
      navbar = f7Navbar(
        title = "Inputs Layout",
        hairline = FALSE
      ),
      f7List(
        inset = TRUE,
        dividers = TRUE,
        strong = TRUE,
        outline = FALSE,
        f7Text(
          inputId = "text",
          label = "Text input",
          value = "Some text",
          placeholder = "Your text here"
        ),
        f7TextArea(
          inputId = "textarea",
          label = "Text area input",
          value = "Some text",
          placeholder = "Your text here"
        ),
        f7Select(
          inputId = "select",
          label = "Make a choice",
          choices = 1:3,
          selected = 1
        ),
        f7AutoComplete(
          inputId = "myautocomplete",
          placeholder = "Some text here!",
          openIn = "dropdown",
          label = "Type a fruit name",
          choices = c(
            "Apple", "Apricot", "Avocado", "Banana", "Melon",
            "Orange", "Peach", "Pear", "Pineapple"
          )
        ),
        f7Stepper(
          inputId = "stepper",
          label = "My stepper",
          min = 0,
          color = "default",
          max = 10,
          value = 4
        ),
        f7Toggle(
          inputId = "toggle",
          label = "Toggle me"
        ),
        f7Picker(
          inputId = "picker",
          placeholder = "Some text here!",
          label = "Picker Input",
          choices = c("a", "b", "c"),
          options = list(sheetPush = TRUE)
        ),
        f7DatePicker(
          inputId = "date",
          label = "Pick a date",
          value = Sys.Date()
        ),
        f7ColorPicker(
          inputId = "mycolorpicker",
          placeholder = "Some text here!",
          label = "Select a color"
        )
      ),
      f7CheckboxGroup(
        inputId = "checkbox",
        label = "Checkbox group",
        choices = c("a", "b", "c"),
        selected = "a",
        style = list(
          inset = TRUE,
          dividers = TRUE,
          strong = TRUE,
          outline = FALSE
        )
      ),
      f7Radio(
        inputId = "radio",
        label = "Radio group",
        choices = c("a", "b", "c"),
        selected = "a",
        style = list(
          inset = TRUE,
          dividers = TRUE,
          strong = TRUE,
          outline = FALSE
        )
      )
    )
  ),
  server = function(input, output) {
  }
)

Forms

Since {shinyMobile} 2.0.0, the functions f7Form() and updateF7Form() have been introduced to gather inputs in the same form and update them in batch or only selected ones. The form returns a list with all the inputs inside it, and you can access them by their inputId.


In the below example this means you can gather all the values by simply calling input$myform and update them all at once by calling updateF7Form():

library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    f7SingleLayout(
      navbar = f7Navbar(title = "Inputs form"),
      f7Block(f7Button("update", "Click me")),
      f7BlockTitle("A list of inputs in a form"),
      f7List(
        inset = TRUE,
        dividers = FALSE,
        strong = TRUE,
        outline = FALSE,
        f7Form(
          id = "myform",
          f7Text(
            inputId = "text",
            label = "Text input",
            value = "Some text",
            placeholder = "Your text here",
            style = list(
              description = "A cool text input",
              outline = TRUE,
              media = f7Icon("house"),
              clearable = TRUE,
              floating = TRUE
            )
          ),
          f7TextArea(
            inputId = "textarea",
            label = "Text Area",
            value = "Lorem ipsum dolor sit amet, consectetur
              adipiscing elit, sed do eiusmod tempor incididunt ut
              labore et dolore magna aliqua",
            placeholder = "Your text here",
            resize = TRUE,
            style = list(
              description = "A cool text input",
              outline = TRUE,
              media = f7Icon("house"),
              clearable = TRUE,
              floating = TRUE
            )
          ),
          f7Password(
            inputId = "password",
            label = "Password:",
            placeholder = "Your password here",
            style = list(
              description = "A cool text input",
              outline = TRUE,
              media = f7Icon("house"),
              clearable = TRUE,
              floating = TRUE
            )
          ),
          f7Select(
            inputId = "select",
            label = "Select a number",
            choices = c(1, 2, 3),
            style = list(
              description = "A selection",
              outline = TRUE,
              media = f7Icon("house")
            )
          )
        )
      ),
      f7Block(verbatimTextOutput("form"))
    )
  ),
  server = function(input, output, session) {
    output$form <- renderPrint(input$myform)
    
    observeEvent(input$update, {
      updateF7Form(
        "myform",
        data = list(
          "text" = "New text",
          "textarea" = "New text area",
          "password" = "New password",
          "select" = 3
        )
      )
    })
  }
)

Since the f7Form() is wrapped inside a f7List(), it will look like a regular list of inputs. The difference is in the way the inputs are gathered and how they can be updated.


Currently, the following inputs supported for the form are:


Having other types of inputs in your form might not looks as good, or it might not return the expected results.