Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clean "input" after removing element using removeUI

Tags:

r

shiny

How can I clean the "input" (the verbatimTextOutput("summary") in the example bellow) after removing some element. I tried some thing using shiny.unbindAll without succes. the dedicated removeUI doesnt do the job. Please have a look to this example :

library(shiny)

ui <- fluidPage(

    actionButton('insertBtn', 'Insert'), 
    actionButton('removeBtn', 'Remove'), 
    verbatimTextOutput("summary"),
    tags$div(id = 'placeholder') 

)

server <- function(input, output, session) {
  ## keep track of elements inserted and not yet removed
  inserted <- c()

  observeEvent(input$insertBtn, {
    btn <- input$insertBtn
    id <- paste0('txt', btn)
    insertUI(
      selector = '#placeholder',
      ## wrap element in a div with id for ease of removal
      ui = tags$div(
        actionButton(inputId = paste0("truc",id),label = paste0("truc",id)), 
        id = id
      )
    )
    inserted <<- c(id, inserted)
  })

  observeEvent(input$removeBtn, {
    removeUI(
      ## pass in appropriate div id
      selector = paste0('#', inserted[length(inserted)])
    )
    inserted <<- inserted[-length(inserted)]
  })


  output$summary <- renderPrint({
    invalidateLater(1000)
    lst <- reactiveValuesToList(input) 
    message("upd")
    lst[order(names(lst))]
  })
}

shinyApp(ui, server)

Any idea how to do this ?

like image 370
Vincent Guyader Avatar asked Jun 23 '18 14:06

Vincent Guyader


2 Answers

You can use shinyjs to modify inputs. Would something like this work?

library(shiny)
library(shinyjs)

ui <- fluidPage(

  actionButton('insertBtn', 'Insert'), 
  actionButton('removeBtn', 'Remove'), 
  verbatimTextOutput("summary"),
  tags$div(id = 'placeholder'), 
  useShinyjs()

)

server <- function(input, output, session) {
  ## keep track of elements inserted and not yet removed
  inserted <- c()

  observeEvent(input$insertBtn, {
    btn <- input$insertBtn
    id <- paste0('txt', btn)
    insertUI(
      selector = '#placeholder',
      ## wrap element in a div with id for ease of removal
      ui = tags$div(
        actionButton(inputId = paste0("truc",id),label = paste0("truc",id)), 
        id = id
      )
    )
    inserted <<- c(id, inserted)
  })

  observeEvent(input$removeBtn, {
    id <- inserted[length(inserted)]
    removeUI(
      ## pass in appropriate div id
      selector = paste0('#',id)
    )
    #use the javascript functio Shiny.onInputChange to set the values of 
    # the removed inputs to NULL, javascript uses lower case for null
    runjs(paste0("Shiny.onInputChange('",paste0("truc",id),"',null)"))
    inserted <<- inserted[-length(inserted)]
  })


  output$summary <- renderPrint({
    invalidateLater(1000)
    lst <- reactiveValuesToList(input) 
    message("upd")
    lst[order(names(lst))]
  })
}

shinyApp(ui, server)

Hope this helps!!

like image 121
Bertil Baron Avatar answered Nov 11 '22 12:11

Bertil Baron


If you absolutely want to remove inputs you have created, my solution won't help (you could still use Bertil Baron's solution though). However, if you just want to clean the inputs (without removing them), then this what I would suggest :

library(shiny)

ui <- fluidPage(

  actionButton('insertBtn', 'Insert'), 
  actionButton('removeBtn', 'Remove'), 
  verbatimTextOutput("summary"),
  tags$div(id = 'placeholder') 

)

server <- function(input, output, session) {
  ## keep track of elements inserted and not yet removed
  inserted <- reactiveVal(0)

  observeEvent(input$insertBtn, {
    inserted(inserted() + 1)
    id <- paste0('txt', inserted())
    insertUI(
      selector = '#placeholder',
      ## wrap element in a div with id for ease of removal
      ui = tags$div(
        actionButton(inputId = paste0("truc", id), label = paste0("truc", id)), 
        id = id
      )
    )
  })

  observeEvent(input$removeBtn, {
    removeUI(
      ## pass in appropriate div id
      selector = paste0('#txt', inserted())
    )
    inserted(inserted() - 1)
  })


  output$summary <- renderPrint({
    invalidateLater(1000)
    lst <- isolate(reactiveValuesToList(input) )
    message("upd")
    lst[order(names(lst))]
  })
}

shinyApp(ui, server)
like image 1
denrou Avatar answered Nov 11 '22 13:11

denrou