Creating Action Buttons from User Input Selection
In this article, we’ll explore how to create interactive action buttons based on user input selection in a Shiny application. We’ll delve into the world of reactive values, conditionals, and custom UI elements.
Background
Shiny is an R framework for building web applications that incorporate Shiny’s graphical user interface (GUI) components, such as text inputs, dropdown menus, and buttons. The shinyWidgets
package provides additional GUI components, including action buttons. These buttons can be customized to respond to different user inputs.
Our goal in this article is to create an interactive application where users can input their name, select countries, cities, or popular items, and receive corresponding ratings.
Step 1: Setting Up the Application
First, we’ll set up a new Shiny application using the shiny
package. We’ll also import necessary libraries for data manipulation and visualization.
library(shiny)
library(shinyWidgets)
library(emojifont)
library(shinyBS)
Step 2: Creating UI Components
Next, we’ll create UI components that will collect user input:
textInput("name", "Enter your name:")
: a text input field for users to enter their name.actionButton("selectCountry", "Select Country")
: an action button to select a country.
ui <- fluidPage(
useShinyjs(),
titlePanel("Info"),
fluidRow(
column(width = 4,
panel(
style = "overflow-y:scroll; max-height: 300px; position:relative; align: centre",
textInput("name", label = "",
placeholder = "Type Message"),
actionButton("selectCountry", "Select Country"), heading = "Smart-Advisor", status = "primary")
))))
Step 3: Creating Server-Side Logic
Now, we’ll write server-side logic to handle user input and create action buttons accordingly.
server <- function(input, output, session) {
# Declaring and Initializing Global Variables
lvl <- reactiveVal()
lvl(i)
countries <- matrix(c("India", "US", "UK", "Canada"), byrow = TRUE, nrow = 1)
emj <- reactiveValues(em = 1)
clearInput <- function() {
updateTextInput(session, "name", value = "")
}
invalidInput <- function() {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin",
p("Kindly provide a valid input")))
clearInput()
}
cities <- reactive({
dat %>% filter(Country == "India") %>% distinct(Cities)
})
popularItems <- reactive({
dat %>% filter(Country == "India", Cities == "New Delhi") %>% distinct(`Popular for-Item`)
})
# Main Function
replyMessage <- function(lvl, msg) {
switch(lvl,
# Check for Level 1
if (grepl("^[a-zA-Z][a-zA-Z ]+[a-zA-Z]$", msg, perl = TRUE)) {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin",
img(), wellPanel(
p("Hi,", tags$b(msg), ".", tags$br(),
"My name is Zeta!"), tags$br()),
p(actionButton("mood1", "India", icon = icon("grin"),
style = "pill", color = "warning", size = "xs"),
actionButton("mood2", "US", icon = icon("frown-open"),
style = "pill", size = "xs", color = "success"),
actionButton("mood3", "UK", icon = icon("meh"), style = "pill",
size = "xs", color = "primary"),
actionButton("mood4", "Canada", icon = icon("meh"),
style = "pill", size = "xs", color = "primary"))),
clearInput(),
shinyjs::disable("name"),
shinyjs::hide("selectCountry")
},
# Level 3
if (msg == "India") {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin",
img(), wellPanel(
p("What Personal challenges are you facing?", emoji("raising_hand")))), tags$br(),
p(actionButton("P1", paste(cities()[1, 1]), icon = icon("user-friends"),
color = "warning", style = "pill", size = "xs"), tags$br(), tags$br(),
actionButton("P2", paste(popularItems()[1, 1]), icon = icon("dollar-sign"),
color = "success", style = "pill", size = "xs"), tags$br(), tags$br(),
actionButton("P3", paste(cities()[1, 1]), icon = icon("first-aid"),
color = "primary", style = "pill", size = "xs"))),
clearInput(),
shinyjs::disable("name"),
shinyjs::hide("selectCountry")
},
if (paste(cities()[1, 1]) == TRUE) {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin",
img(), wellPanel(
p("What Personal challenges are you facing?", emoji("raising_hand")))), tags$br(),
p(actionButton("P1", paste(popularItems()[1, 1]), icon = icon("user-friends"),
color = "warning", style = "pill", size = "xs"), tags$br(), tags$br(),
actionButton("P2", paste(popularItems()[1, 1]), icon = icon("dollar-sign"),
color = "success", style = "pill", size = "xs"), tags$br(), tags$br(),
actionButton("P3", paste(popularItems()[1, 1]), icon = icon("first-aid"),
color = "primary", style = "pill", size = "xs")))
clearInput(),
shinyjs::disable("name"),
shinyjs::hide("selectCountry")
}
} )
# Function to Check Blank in Message Box
getMessage <- function(lvl) {
observeEvent(input$selectedCountry, {
if (input$selectedCountry == "") {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin",
img()), p("Kindly provide a valid input.")))
clearInput()
} else {
replyMessage(lvl(), input$selectedCountry)
}
})
lapply(sprintf("mood%s", 1:4),
function(x) {
observeEvent(input[[x]], {
emj$em <- as.numeric(sub("mood", "", x))
insertUI(selector = "#name", where = "beforeBegin",
p(paste(replyMessage(lvl(), emojis[, emj$em]))))
})
shinyjs::disable("mood1")
shinyjs::disable("mood2")
shinyjs::disable("mood3")
shinyjs::disable("mood4")
})
}
# Main Function
startConversation <- function() {
clearInput()
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin", tags$img(src = "chat-robot.gif", class = "img-responsive")),
wellPanel(p("Hey! Could I get your name?")))
getMessage(lvl)
}
startConversation()
}
Step 4: Integrating Reactive Values
We’ll define reactive values to store the user’s input and update them accordingly.
# Defining Server Controls
server <- function(input, output, session) {
# ...
# Define a reactive value for the selected country
selectedCountry <- reactiveValues(em = 1)
# Update the selected country when the "Select Country" button is clicked
observeEvent(input$selectCountry, {
updateTextInput(session, "selectedCountry", value = "")
})
# Use the selected country in the reply message function
replyMessage <- function(lvl, msg) {
switch(lvl,
# ...
if (input$selectedCountry == "") {
insertUI(selector = "#name", where = "beforeBegin",
ui = div(class = "chat-bubbles", div(class = "bubble admin", img()), p("Kindly provide a valid input.")))
clearInput()
} else {
replyMessage(lvl(), input$selectedCountry)
}
})
}
Step 5: Creating Custom UI Components
We can create custom UI components using the shinyWidgets
package. For example, we can create a custom button that displays an emoji.
# Create a custom button with an emoji
ui <- fluidPage(
useShinyjs(),
titlePanel("Info"),
fluidRow(
column(width = 4,
panel(
style = "overflow-y:scroll; max-height: 300px; position:relative; align: centre",
textInput("name", label = "",
placeholder = "Type Message"),
actionButton("selectCountry", "Select Country"), heading = "Smart-Advisor", status = "primary")
))
)
# Create a custom button with an emoji
ui <- fluidPage(
useShinyjs(),
titlePanel("Info"),
fluidRow(
column(width = 4,
panel(
style = "overflow-y:scroll; max-height: 300px; position:relative; align: centre",
textInput("name", label = "",
placeholder = "Type Message"),
actionButton("selectCountry", "Select Country"), heading = "Smart-Advisor", status = "primary")
))
# Display a custom button with an emoji
div(class = "button-container", shiny::actionButton("customButton", "", icon = shiny::icon("smile")))
)
Conclusion
In this article, we’ve explored how to create interactive action buttons based on user input selection in a Shiny application. We’ve used reactive values and custom UI components to make the application more engaging and user-friendly.
Example Use Cases
- Chatbot Application: Create a chatbot that responds to user inputs with relevant answers or actions.
- Survey Application: Develop an interactive survey application where users can select options and receive feedback based on their responses.
- Game Development: Build games that require user input, such as button presses or key presses, to progress through levels or challenges.
Tips and Variations
- Use conditionals: Use
if
statements or conditional expressions to make your application more dynamic and responsive to user inputs. - Create custom UI components: Use the
shinyWidgets
package to create custom UI components that fit your application’s design and functionality. - Incorporate reactive values: Use reactive values to store and update data in real-time, allowing for a more interactive and dynamic user experience.
By following these steps and incorporating tips and variations, you can create engaging and interactive applications using Shiny that respond to user inputs and provide a unique experience for your users.
Last modified on 2024-08-11