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)
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)
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)
Related
In this shiny App (code below), tabPanel 'Scatter plot', note that the plot is correctly rendered only when the user expand the bsCollapsePanel 'Marker settings' for the first time. Before expanding the panel 'Marker settings' at first time, the message Error: argument is of length zero is shown. Can someone find out where the error is in the code?
library(shiny)
library(shinyBS)
library(tidyverse)
shinyApp(
ui = fluidPage(
tabsetPanel(
tabPanel("mtcars",
dataTableOutput("mtcarsDATA")),
tabPanel("Scatter plot",
sidebarPanel(
bsCollapse(id = "Side panel", open = "Variables",
bsCollapsePanel("Variables",
uiOutput("varx"),
uiOutput("vary"))
)
),
mainPanel(
bsCollapsePanel("Marker settings",
uiOutput("showMrk"),
uiOutput("shpMrk"),
uiOutput("forPorForma"),
uiOutput("forPorVar"),
uiOutput("mrkTrsp")),
plotOutput('SctPlot'))
)
)
),
server <- function(input, output) {
output$mtcarsDATA <- renderDataTable({
data <- mtcars
getModel <- reactive({
names(data) })
output$varx <- renderUI({
selectInput("varsel.x", HTML("Select var X<span style='color: red'>*</span>"),
choices = as.list(getModel()), multiple = F) })
getModelnum <- reactive({
filterNumeric <- data[sapply(data, is.numeric)]
names(filterNumeric) })
output$vary <- renderUI({
selectInput("varsel.y", HTML("Select var Y<span style='color: red'>*</span>(numerical only)"),
choices = as.list(getModelnum()), multiple = F) })
output$showMrk <- renderUI({
checkboxInput("show_Mrk", "Show marker", value=T) })
output$shpMrk <- renderUI({
conditionalPanel(condition = "input.show_Mrk == T",
radioButtons("shp_Mrk", "Format marker",
choices = c("by shape", "by variable"))) })
output$forPorForma <- renderUI({
conditionalPanel(condition = "input.shp_Mrk == 'by shape' & input.show_Mrk == T",
sliderInput("for_PorForma", 'Deslize para mudar o formato do marcador',
min = 1, max=25, value = 16)) })
output$mrkTrsp <- renderUI({
conditionalPanel(condition = "input.show_Mrk == T",
sliderInput("mrk_Trsp", 'Slide to change marker transparency',
min = 0, max=1, value = .5, step=.05)) })
getModelcat <- reactive({
filterCaracter <- data[sapply(data, is.character)]
names(filterCaracter) })
output$forPorVar <- renderUI({
conditionalPanel(condition = "input.show_Mrk == 1 & input.shp_Mrk == 'by variable'",
selectInput("forPorVar.sel", "Select var",
choices = as.list(getModelcat()), multiple = F)) })
output$SctPlot <- renderPlot({
if(input$show_Mrk == T){
if(input$shp_Mrk == "by shape") {
geomPoint <- geom_point(alpha=1-input$mrk_Trsp, shape=input$for_PorForma) } else {
geomPoint <- geom_point(alpha=1-input$mrk_Trsp, aes_string(shape=(input$forPorVar.sel))) }} else {
geomPoint <- geom_point(alpha=0) }
p <- data %>%
ggplot(aes_string(x=input$varsel.x, y=input$varsel.y)) +
geomPoint
p
})
data
})
}
)
I would like to make sure that when we click on the button button we send in the verbatimTextOutput, 1 then we pause for 2s and at the end we send 2.
But what I get is a pause for 2s then it sends 1 and 2.
How can I do that ?
library(shiny)
ui <- fluidPage(
verbatimTextOutput("output", placeholder = TRUE),
actionButton("b", "button")
)
server <- function(input, output, session) {
o <- reactiveVal("--- Hello ---")
output$output <- renderText(o())
observeEvent(input$b, {
o(c(o(), "\n", "- 1 "))
Sys.sleep(2)
o(c(o(), "\n", "- 2 "))
})
}
shinyApp(ui, server)
library(shiny)
library(magrittr)
ui <- fluidPage(
verbatimTextOutput("output", placeholder = TRUE),
actionButton("b", "button")
)
server <- function(input, output, session) {
v <- reactiveValues(msg = "--- Hello ---",start = 0)
output$output <- renderText({
v$msg
})
observeEvent(input$b,{
v$msg <- paste0(v$msg,"\n","- 1 ")
v$start <- v$start + 1
})
start <- reactive({
v$start
})
start_d <- start %>% debounce(50)
observeEvent(start_d(),{
req(start_d() > 0)
Sys.sleep(2)
v$msg <- paste0(v$msg,"\n","- 2 ")
})
}
shinyApp(ui, server)
It's possible to do with delay() from shinyjs
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
verbatimTextOutput("output", placeholder = TRUE),
actionButton("b", "button")
)
server <- function(input, output, session) {
o <- reactiveVal("--- Hello ---")
output$output <- renderText(o())
observeEvent(input$b, {
o(c(o(), "\n", "- 1 "))
delay(2000, o(c(o(), "\n", "- 2 ")))
})
}
shinyApp(ui, server)
I have a table where I get a value from the same column but from different rows and I would like to display in a verbatimTextOutput each value without overwriting each time.
I tried to do that but I get an error:
library(shiny)
library(DT)
ui <- fluidPage(
DT::dataTableOutput("table"),
verbatimTextOutput("output", placeholder = TRUE)
)
server <- function(input, output) {
val <- reactiveVal(as.character(dt[input$table_rows_selected, 2]))
o <- reactiveVal(NULL)
observeEvent(input$table_rows_selected, {
o(c(o(), "\n", "You chose :", val()))
output$output <- renderText({ o() })
})
dt <- data.frame("a" = paste("a", 1:10), "b" = paste("b", 1:10))
output$table <- DT::renderDataTable({
DT::datatable(dt, selection = list(target = 'row'))
})
}
shinyApp(ui = ui, server = server)
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
I would like to link an action to the arrow/cursor keys in my Shiny app.
The action is already linked to pressing previous and next buttons. So I would like to add the eventExpr "cursor right" and "cursor left" to it, respectively. This is to plot one plot after another. Here is a simplified example with mtcars dataset.
datasets <- list(mtcars, iris, PlantGrowth)
ui <- fluidPage(
mainPanel(
titlePanel("Simplified example"),
tableOutput("cars"),
actionButton("prevBtn", icon = icon("arrow-left"), ""),
actionButton("nextBtn", icon = icon("arrow-right"), ""),
verbatimTextOutput("rows")
)
)
server <- function(input, output) {
output$cars <- renderTable({
head(dat())
})
dat <- reactive({
if (is.null(rv$nr)) {
d <- mtcars
}
else{
d <- datasets[[rv$nr]]
}
})
rv <- reactiveValues(nr = 1)
set_nr <- function(direction) {
rv$nr <- rv$nr + direction
}
observeEvent(input$nextBtn, { # here I would like add the sec. eventExpr.
set_nr(1)
})
observeEvent(input$prevBtn, { # here I would like add the sec. eventExpr.
set_nr(-1)
})
ro <- reactive({
nrow(dat())
})
output$rows <- renderPrint({
print(paste(as.character(ro()), "rows"))
})
vals <- reactiveValues(needThisForLater = reactive(30 * ro()))
}
shinyApp(ui = ui, server = server)```
You can attach a keydown event handler to the document:
datasets <- list(mtcars, iris, PlantGrowth)
js <- paste(
"$(document).on('keydown', function(event){",
" var key = event.which;",
" if(key === 37){",
" Shiny.setInputValue('arrowLeft', true, {priority: 'event'});",
" } else if(key === 39){",
" Shiny.setInputValue('arrowRight', true, {priority: 'event'});",
" }",
"});"
)
ui <- fluidPage(
tags$head(tags$script(HTML(js))),
mainPanel(
titlePanel("Simplified example"),
tableOutput("cars"),
actionButton("prevBtn", icon = icon("arrow-left"), ""),
actionButton("nextBtn", icon = icon("arrow-right"), ""),
verbatimTextOutput("rows")
)
)
server <- function(input, output) {
output$cars <- renderTable({
head(dat())
})
dat <- reactive({
if (is.null(rv$nr)) {
d <- mtcars
}
else{
d <- datasets[[rv$nr]]
}
})
rv <- reactiveValues(nr = 1)
set_nr <- function(direction) {
rv$nr <- rv$nr + direction
}
observeEvent(list(input$nextBtn, input$arrowRight), {
set_nr(1)
})
observeEvent(list(input$prevBtn, input$arrowLeft), {
set_nr(-1)
})
ro <- reactive({
nrow(dat())
})
output$rows <- renderPrint({
print(paste(as.character(ro()), "rows"))
})
vals <- reactiveValues(needThisForLater = reactive(30 * ro()))
}
shinyApp(ui = ui, server = server)
I am trying to have Shiny connects to Teradata.
Below is the code I have but I always get "ERROR: [on_request_read] connection reset by peer" after I choose the indicator and click the action button. Appreciated any input for this. Thanks.
ui <- shinyUI(fluidPage(
titlePanel("Generic grapher"),
sidebarLayout(
sidebarPanel(
numericInput("wafer", label = h3("Select Indicator:"),
value = NULL),
actionButton("do", "An action button")
),
mainPanel(
verbatimTextOutput("value"),
verbatimTextOutput("que"),
verbatimTextOutput("wq_print"),
dataTableOutput(outputId="pos")
)
)
)
)
library(markdown)
library(RODBC)
library(DBI)
library(sqldf)
ch<-odbcConnect("xxx", uid=" ",pwd=" ")
wq = data.frame()
server <- shinyServer(function(input, output){
values <- reactiveValues()
values$df <- data.frame()
d <- eventReactive(input$do, { input$wafer })
output$value <- renderPrint({ d() })
a <- reactive({ paste("SELECT * FROM dwname.tablename WHERE indicator_x = ", d(), sep="") })
output$que <- renderPrint({ a() })
observe({
if (!is.null(d())) {
wq <- reactive({ sqlQuery( a() ) })
output$wq_print <- renderPrint({ print(str(wq())) })
values$df <- rbind(isolate(values$df), wq())
}
})
output$pos <- renderDataTable({ values$df })
})
shinyApp(ui, server)