Reputation: 871
I have a button that when you click on it, it displays a table and when you click on a line, it displays the line number in a verbatimTextOutput
I have a reactive variable o() that saves all the lines that have been selected and when no line is selected it displays "nothing".
When I launch the application it displays several times "nothing" I don't understand why.
How could I redo the code to avoid these multiple appearances when launching the application?
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("updateTable", "Show data table")
)
server <- function(input, output) {
dt <- reactiveVal()
o <- reactiveVal()
val <- reactive(
tail(
as.character(dt()[input$table_rows_selected, 2]),
n=1)
)
val2 <- reactiveVal()
observeEvent(input$updateTable, {
# the datatable
dt(data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10)))
output$table <- DT::renderDataTable({
DT::datatable(dt(), selection = list(target = 'row'))
})
if(is.null(val())){ val2("nothing")}
})
observeEvent(val(), {
if(length(input$table_rows_selected) > 0){
val2(val())
o(c(o(), "\n", "You chose :", val2()))
} else{
val2("nothing")
o(c(o(), "\n", "You chose :", val2()))
}
output$output <- renderText({ o() })
})
}
shinyApp(ui = ui, server = server)
solution 1
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("showTable", "Show data table")
)
server <- function(input, output) {
val <- reactiveVal()
o <- reactiveVal()
dt <- reactiveVal()
observe({
val(as.character(dt()[input$table_rows_selected, 2]))
})
observeEvent(input$showTable, {
dt(data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10)))
output$table <- DT::renderDataTable({
DT::datatable(dt(), selection = list(target = 'row'))
})
o(c(o(), "\n", "Display of the table"))
})
output$output <- renderText({
if(input$showTable)
{
if(!identical(val(), character(0))){
o(c( isolate(o()), "\n", "You chose: ", isolate(val())))
} else{
o(c( isolate(o()), "\n", "You chose: ", "nothing"))
}
o()
}
})
}
shinyApp(ui = ui, server = server)
Solution 2
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("showTable", "Show data table")
)
server <- function(input, output) {
o <- reactiveVal()
dt <- reactiveVal()
observeEvent(input$showTable, {
dt(data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10)))
output$table <- DT::renderDataTable({
DT::datatable(dt(), selection = list(target = 'row'))
})
o(c(o(), "\n", "Display of the table"))
})
val <- reactive({
if(!is.null(input$table_rows_selected)){
tail(
as.character(dt()[input$table_rows_selected, 2]),
n = 1
)
} else{ "nothing" }
})
observeEvent(val(), {
if(input$showTable)
{
o(c(o(), "\n", "You chose: ", val()))
}
})
output$output <- renderText({ o() })
}
shinyApp(ui = ui, server = server)
Upvotes: 0
Views: 142
Reputation: 2044
It's due to your reactive values updating when the table is shown. The easiest solution is just remove adding "\n", "You chose :", val2()
to your list and just have it as a default option for o()
.
See below for the code:
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("updateTable", "Show data table")
)
server <- function(input, output) {
dt <- reactiveVal()
o <- reactiveVal()
val <- reactive(
tail(
as.character(dt()[input$table_rows_selected, 2]),
n=1)
)
val2 <- reactiveVal()
observeEvent(input$updateTable, {
# the datatable
dt(data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10)))
output$table <- DT::renderDataTable({
DT::datatable(dt(), selection = list(target = 'row'))
})
if(is.null(val())){ val2("nothing")}
})
observeEvent(val(), {
if(length(input$table_rows_selected) > 0){
val2(val())
o(c(o(), "\n", "You chose :", val2()))
} else{
val2("nothing")
o(c("\n", "You chose :", val2()))
}
output$output <- renderText({ o() })
})
}
shinyApp(ui = ui, server = server)
UPDATED
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("updateTable", "Show data table")
)
server <- function(input, output) {
#Data table
dt <- data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10))
output$table <- DT::renderDataTable({
DT::datatable(dt, selection = list(target = 'row'))
})
shinyjs::hide("table")
#Button
observeEvent(input$updateTable, {
shinyjs::show("table")
shinyjs::show("output")
})
#Value Box
o <- reactiveVal()
val <- reactive({
tail(
as.character(dt[input$table_rows_selected, 2]),
n = 1
)
})
observeEvent(val(), {
if(length(input$table_rows_selected) > 0){
o(c(o(), "\n", "You chose :", val()))
} else{
req(o())
o(c(o(), "\n", "You chose : nothing"))
}
})
output$output <- renderText({ o() })
shinyjs::hide("output")
}
shinyApp(ui = ui, server = server)
Upvotes: 1
Reputation: 11140
Your approach is too complex. Here's a simplified way -
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("updateTable", "Show data table")
)
server <- function(input, output) {
val <- reactiveVal()
dt <- eventReactive(input$updateTable, {
# the datatable
data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10))
})
output$table <- DT::renderDataTable({
DT::datatable(dt(), selection = list(target = 'row'))
})
observe({
val(c(isolate(val()), as.character(dt()[input$table_rows_selected, 2])))
})
output$output <- renderText({ paste0("\n You chose :", unique(val())) })
}
shinyApp(ui = ui, server = server)
Upvotes: 1