rshiny

How to listen to checkbox event that has been insert into ui using `insertUI` in Shiny-R


I am trying to build a simple To do list app using Shiny, the application is very simple, there's a textInput where I put things I want to do, and submit it, and it creates a checkbox. What I want to achieve is, if I check the box, there will be a text on the right side that says: "you have done XXX", the XXX is the information of the checkbox.

So far, I have managed to figure out how to insert a checkbox back into the UI however, I have problems in: writing the party of the code that once the checkbox is checked, generate a text which says " you have done XXX"

The two main difficulties is : 1. listen to the inserted UI (each checkbox needs a special id, but I can't write logic in the server components that has indeterministic checkbox id. Also, I can figure out a way to extract the content of the checkbox from the server side, the input$checkbox only gives me true or false value.

This is the code I am working on so far, I am wondering if this functionality is achievable using Shiny-R?


ui <- fluidPage(
  theme = bs_theme(version = 4, bootswatch = "sketchy"),
  titlePanel("A simple todo App"),

  sidebarLayout(
    sidebarPanel(
      
      # Date configuration
      dateInput("date", label = "Date Configuration"),
      
      # Things to do 
      h3("Daily Todo", id="start", style = "color:grey", align = "center"),
      checkboxInput("checkbox","Submit One Job Application"),
      textInput("todo", label = "Other things to do"),
      actionButton("todoBnt", label = "Submit"),
      br(),
      br(),
      textInput("learnt", label = "Key things learnt"),
      actionButton("learntBnt", label = "Submit")),
    
    mainPanel(
      
      h1(textOutput("timing"), align = "center"),
      h1("What have I done",align = "center"),
      verbatimTextOutput("value"),
      h1("What have I learnt", align = "center"),
      h2(textOutput("selected_var"),align = "center"),
      p(textOutput("summary"),align="center"))
  )
)

server <- function(input, output) {
  
  inserted <- c()

  observeEvent(input$todoBnt, {
    
    insertUI(
      selector = "#start",
      where = "afterEnd",
      ui = checkboxInput("chekcbox",input$todo)
    )
  })

  output$timing <- renderText({ 
    paste0("Today is ", as.character(input$date))
  })
  
  output$value <- renderText({ input$checkbox }) ##this gives "TRUE" value, I don't think it's right. 
  
  output$summary <- renderText({
    paste0("I have learnt to ", input$learnt, "!")
  })
  
}

shinyApp(ui = ui, server = server)

I have tried to search answer online, but I think the checkbox in Shiny-R is mainly used to filter graphs etc... So I am not sure if the function I want is actually achievable using the langague. Please help!


Solution

  • Instead of inserting each checkbox separately one option would be to switch to a checkboxGroupInput which you could update in your observeEvent. Doing so makes it easy to get a list of things you have done. However, doing so requires to track the things to do for which I use a reactiveVal choices which gets updated each time a new item is added to the to-do list:

    library(shiny)
    library(bslib)
    
    ui <- fluidPage(
      theme = bs_theme(version = 4, bootswatch = "sketchy"),
      titlePanel("A simple todo App"),
      
      sidebarLayout(
        sidebarPanel(
          
          # Date configuration
          dateInput("date", label = "Date Configuration"),
          
          # Things to do 
          h3("Daily Todo", id="start", style = "color:grey", align = "center"),
          checkboxGroupInput("checkbox", label = "", choices = "Submit One Job Application"),
          textInput("todo", label = "Other things to do"),
          actionButton("todoBnt", label = "Submit"),
          br(),
          br(),
          textInput("learnt", label = "Key things learnt"),
          actionButton("learntBnt", label = "Submit")),
        
        mainPanel(
          
          h1(textOutput("timing"), align = "center"),
          h1("What have I done",align = "center"),
          verbatimTextOutput("value"),
          h1("What have I learnt", align = "center"),
          h2(textOutput("selected_var"),align = "center"),
          p(textOutput("summary"),align="center"))
      )
    )
    
    server <- function(input, output) {
      
      choices <- reactiveVal("Submit One Job Application")
      inserted <- c()
      
      observeEvent(input$todoBnt, {
        selected <- input$checkbox
        choices(c(choices(), input$todo)) 
        updateCheckboxGroupInput(inputId = "checkbox", choices = choices(), selected = selected)
        updateTextInput(inputId = "todo", value = "")
      })
      
      output$timing <- renderText({ 
        paste0("Today is ", as.character(input$date))
      })
      
      output$value <- renderText({ 
        paste(input$checkbox, collapse = "\n")
      })
      
      output$summary <- renderText({
        paste0("I have learnt to ", input$learnt, "!")
      })
      
    }
    
    shinyApp(ui = ui, server = server)
    

    enter image description here