• Stars
    star
    162
  • Rank 232,284 (Top 5 %)
  • Language
    R
  • License
    Other
  • Created over 9 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

📝 Easily create questionnaire-type forms with Shiny

shinyforms - Easily create questionnaire-type forms with Shiny

Donate

Note: The work on this package has paused, and it's currently looking for funding. Please contact me if your company would like to sponsor/fund this project. I receive a lot of emails about this package, but I cannot continue work on it without proper funding.

Click here to sponsor my work on shiny packages, and email me afterwards if you'd like me to continue working on shinyforms.

What does shinyforms do?

The idea of shinyforms is to let you create questions/polls/surveys as Shiny apps very easily. Kind of like mimicking a Google Form.

But, why?

Good question. You should read my blog post where I discuss how to mimick Google Forms with Shiny, and why I originally needed to do it. I've created a few Shiny apps that request user input and save it somewhere, and I wanted to make it super streamlined for anyone else to do so in the future. You can see an live example of a Shiny form here.

How do I use this?

First, install this package from GitHub

# install.packages("devtools")
devtools::install_github("daattali/shinyforms")

Then create your list of questions. Each question is a list with an id, type, title, and mandatory (mandatory is FALSE by default)

library(shiny)
library(shinyforms)

questions <- list(
  list(id = "name", type = "text", title = "Name", mandatory = TRUE),
  list(id = "age", type = "numeric", title = "Age"),
  list(id = "favourite_pkg", type = "text", title = "Favourite R package"),
  list(id = "terms", type = "checkbox", title = "I agree to the terms")
)

Then create your form information, which has an id, the list of questions, and the storage type (where responses get saved).

formInfo <- list(
  id = "basicinfo",
  questions = questions,
  storage = list(
    # Right now, only flat file storage is supported
    type = STORAGE_TYPES$FLATFILE,
    # The path where responses are stored
    path = "responses"
  )
)

That's all the information we need. Now we can add the form to a Shiny app by simply calling formUI() and formServer() from our Shiny apps' UI and server:

ui <- fluidPage(
  formUI(formInfo)
)

server <- function(input, output, session) {
  formServer(formInfo)
}

shinyApp(ui = ui, server = server)

Of course you could put more stuff in the app, but this is the beauty of it, the form is a "module" that you can just plug into any Shiny app anywhere you want. Every time you submit a response, it will be saved as a file in the responses directory. This example is the most basic usage.

Current features

  • Responses are saved to local files
  • Support for mandatory vs optional fields (all questions with mandatory = TRUE have to be filled out before the submit button can be clicked)
  • Can create a form with only one line in the UI and one line in the server
  • Can include multiple different forms in the same app
  • Clean and user-friendly way to catch and report errors
  • Questions and form data are in the format of R lists
  • Supported question types: text, numeric, checkbox
  • Ability to submit multiple responses for the same form (use multiple = FALSE in the form info list to disallow multiple submissions)
  • Admin mode support: if you add ?admin=1 to the URL, you will see buttons for viewing all submitted responses below each form. If you want to see all responses, you'll have to enter a password to verify you're an admin (since anybody can just modify the URL). The password is provided by the password in the form info list.
  • Support for more complex input validation that gives nice error messages when a field does not meet certain conditions (use the validations option in the form info)
  • Can have an optional "Reset" button that resets the fields in the form (use the reset = TRUE parameter in the form info)
  • Questions can have hint text, which is text just below the question title that gives a longer description (use the hint parameter of a question)

Future features

You can see all the features I want to support here (but it might take some time because I can't devote too much time to this package right now).

Another example

This example is similar to the previous one, but illustrates a few more features. It shows how to have two forms in one app, and how to use the admin viewing ability.

library(shiny)
library(shinyforms)

# Define the first form: basic information
basicInfoForm <- list(
  id = "basicinfo",
  questions = list(
    list(id = "name", type = "text", title = "Name", mandatory = TRUE,
         hint = "Your name exactly as it is shown on your passport"),
    list(id = "age", type = "numeric", title = "Age", mandatory = FALSE),
    list(id = "favourite_pkg", type = "text", title = "Favourite R package"),
    list(id = "terms", type = "checkbox", title = "I agree to the terms")
  ),
  storage = list(
    type = STORAGE_TYPES$FLATFILE,
    path = "responses"
  ),
  name = "Personal info",
  password = "shinyforms",
  reset = TRUE,
  validations = list(
    list(condition = "nchar(input$name) >= 3",
         message = "Name must be at least 3 characters"),
    list(condition = "input$terms == TRUE",
         message = "You must agree to the terms")
  )
)

# Define the second form: soccer
soccerFormInfo <- list(
  id = "soccerform",
  questions = list(
    list(id = "team", type = "text", title = "Favourite soccer team"),
    list(id = "player", type = "text", title = "Favourite player")
  ),
  storage = list(
    type = STORAGE_TYPES$FLATFILE,
    path = "soccer"
  ),
  multiple = FALSE
)

ui <- fluidPage(
  h1("shinyforms example"),
  tabsetPanel(
    tabPanel(
      "Basic info",
      formUI(basicInfoForm)
    ),
    tabPanel(
      "Soccer",
      formUI(soccerFormInfo)
    )
  )
)

server <- function(input, output, session) {
  formServer(basicInfoForm)
  formServer(soccerFormInfo)
}

shinyApp(ui = ui, server = server)

Notice how easy this is? After defining the forms with R lists, it's literally two function calls for each form to get it set up. A couple things to note: first, the soccer form uses the multiple = FALSE option, which means a user can only submit once (if you restart the Shiny app, the same user is able to submit the form again). Secondly, the first form uses the password option, which means that the admin table will be available IF you add ?admin=1 to the URL. To see the responses from the admin table, click on "Show responses" and type in the password "shinyforms". This app also uses several other features.

Using Google Sheets example

This example is similar to the first example, but illustrates how to use shinyforms with Google sheets as your storage type. In the example you can see that we need to first create a new Google sheet document and give it a header. From there on, we only need to pass the sheet's key to the storage list and shinyforms will do the rest.

library(shiny)
library(shinyforms)
library(googlesheets)

# Create a new google sheets file 
df <- data.frame(name = "", age = 0, favourite_pkg = "", terms = TRUE)
google_df <- gs_new("responses", input = df, trim = TRUE, verbose = FALSE)


questions <- list(
  list(id = "name", type = "text", title = "Name", mandatory = TRUE),
  list(id = "age", type = "numeric", title = "Age"),
  list(id = "favourite_pkg", type = "text", title = "Favourite R package"),
  list(id = "terms", type = "checkbox", title = "I agree to the terms")
)

formInfo <- list(
  id = "basicinfo",
  questions = questions,
  storage = list(
    # Right now, only flat file storage is supported
    type = STORAGE_TYPES$GOOGLE_SHEETS,
    # The path where responses are stored
    path = "responses",
    # Get the Google sheet key 
    key = google_df$sheet_key
    
  )
)

ui <- fluidPage(
  formUI(formInfo)
)

server <- function(input, output, session) {
  formServer(formInfo)
}

shinyApp(ui = ui, server = server)

Feedback

If you think you could have a use for shinyforms, please do let me know or file an issue. Don't be shy!

Notes

Please don't look at the code, it's hideous! This was done at runconf16 in just a few very short hours so it needs to be cleaned up quite a bit. Also, since so little time was spent building this package so far, it's very likely that the API will change. I'm completely open for input.

More Repositories

1

beautiful-jekyll

✨ Build a beautiful and simple website in literally minutes. Demo at https://beautifuljekyll.com
HTML
5,297
star
2

advanced-shiny

🤹 Shiny tips & tricks for improving your apps and solving common problems
R
1,196
star
3

addinslist

📜 Discover and install useful RStudio addins
R
840
star
4

shinyjs

💡 Easily improve the user experience of your Shiny apps in seconds
R
730
star
5

timevis

📅 Create interactive timeline visualizations in R
R
654
star
6

shinycssloaders

⌛ Add loading animations to a Shiny output while it's recalculating
CSS
400
star
7

ggExtra

📊 Add marginal histograms to ggplot2, and more ggplot2 enhancements
R
379
star
8

shiny-server

My personal Shiny server
R
252
star
9

shinyalert

🗯️ Easily create pretty popup messages (modals) in Shiny
R
241
star
10

oldschool-github-extension

Revert GitHub's UI back to its classic look (before the June 23, 2020 update that has a flat, rounded and more whitespaced design).
CSS
227
star
11

colourpicker

🎨 A colour picker tool for Shiny and for selecting colours in plots (in R)
JavaScript
214
star
12

shinyscreenshot

📷 Capture screenshots of entire pages or parts of pages in Shiny apps
R
69
star
13

shinydisconnect

🔌 Show a nice message when a Shiny app disconnects or errors
R
65
star
14

ddpcr

🔬 Analysis and visualization of Droplet Digital PCR data in R and on the web
R
60
star
15

daattali.github.io

Dean Attali's website - R/Shiny Consultant
HTML
58
star
16

shinybrowser

🌐 Find out information about a user's web browser in Shiny apps
R
40
star
17

lightsout

🔦 Lights Out game implemented in R
R
39
star
18

rsalad

A mix of useful R functions that are good for you
R
26
star
19

UBC-STAT545

My first 12 months with R, mostly through a UBC course and my own experiments
HTML
23
star
20

timevisBasic

Helper package to learn advanced 'htmlwidgets' tips
R
22
star
21

gslides-betternotes-extension

The slide previews in the Speaker Notes window of Google Slides are tiny and unreadable. This extension automatically resizes the slides when the window is resized, and allows the user to drag the sidebar to select a size.
JavaScript
21
star
22

statsTerrorismProject

Final project for STAT545A - Terrorist activity data analysis
HTML
20
star
23

github-diff-navigator-extension

Chrome/Firefox extension that allows you to easily navigate through the changes in a file that has been edited on GitHub.
JavaScript
19
star
24

shinytip

💬 Simple flexible tooltips for Shiny apps
R
18
star
25

shinyfilebrowser

📁 Simple file browser and list selector for Shiny apps
R
17
star
26

shinymixpanel

🔍 Track user interactions with Mixpanel in Shiny apps or R scripts
R
13
star
27

rasperry-pi-gaming-console-setup

How to set up raspberry pi as a portable oldies gaming console
13
star
28

cranalerts

Get email alerts when a CRAN package gets updated
R
11
star
29

shiny-mini-workshop

Shiny Mini Workshop
R
9
star
30

single-page-amazon-return-labels-extension

Print Amazon return labels as a single page
JavaScript
9
star
31

settlers-catan-turn-analyzer

Settlers of Catan Turn Analyzer - a simple app to teach myself ReactJS
JavaScript
8
star
32

shinycodeviewer

📝 View and edit a series of code chunks with syntax highlighting in Shiny
R
7
star
33

undomanager

🔄 Generic undo/redo manager for R
R
7
star
34

shiny-colour-gradient-input

Colour gradient input for R-Shiny
R
6
star
35

cashflow-calculation-extension

Cashflow Calculator extension for Zillow, Trulia, and Redfin (works in Chrome/Firefox/Edge)
JavaScript
6
star
36

smileyfy-my-facebook-extension

Chrome extension that adds infinite happiness to your Facebook browsing, plus a little bonus rickrolling :)
JavaScript
5
star
37

shinyHelpers

R
5
star
38

shiny-workshop-odsc2019

Shiny Workshop at ODSC 2019 (visualizing NBA 2018/19 player stats)
R
5
star
39

modularize-addin

RStudio addin to help modularize Shiny app code
R
4
star
40

useR2017

Analysis of useR2017 attendance information
R
3
star
41

bingo

Generate Bingo cards with R.
R
3
star
42

Rlist

Easy way to navigate and explore list structures in R (abandoned project)
R
2
star
43

dash2

R
2
star
44

shiny-training-rstudioconf-2018

R
2
star
45

presentations

A place for me to keep my presentations/papers/etc organized
2
star
46

pftv-ad-bypass-extension

Project Free TV shows an interstitial ad page before allowing users to continue to the video - this extension bypasses that page
JavaScript
2
star
47

attalitech

AttaliTech Ltd
CSS
1
star
48

shinywc

R
1
star
49

shiny-conf-nyr-2022

R
1
star
50

stat540-2014-attali-dean

Lab work for UBC STAT540
R
1
star
51

htmldependencybug

JavaScript
1
star
52

genes-track-demo

HTML
1
star