I have two DTedit tables which are functionally related
I do not want users to get the Insert/New button in DT#2 when no row is selected in DT#1
I have Table1_Results$rows_selected
to test if selection exists (length>0)
I also identified the id of the 'New button' in DT#2 as being Table2_add
But do not succeed to make the length of Table1_Results$rows_selected
trigger the shinyjs show() or hide() action for DT#2
Could anyone please share some reactivity command to do this!
the following code is not working but illustrates my aim
observe(Table1_Results$rows_selected,{
if (length(Table1_Results$rows_selected)) {
shinyjs::show('Table2_add')
} else {
shinyjs::hide('Table2_add')
}
})
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.)
This manual test using a button works
observeEvent(input$showhide, {
toggle('Table2_add')
})
So it is really the reactive testing of the Table1_Results$rows_selected
which is lacking
Thanks in advance
In the code below:
Note: I use DTedit because it allows other features not shown here
AIMs:
1) when no drink is selected, hide the New button for containers
2) manage <table>$rows_selected so that it reflects the current status
library("shiny")
library("shinyjs")
library("DT")
library("DTedit")
server <- function(input, output) {
Drink_Results <- dtedit(
input, output,
name = 'Drink',
thedata = data.frame(
ID = c(1:3),
drink = c('Tea', 'Coffea', 'Water'),
stringsAsFactors = FALSE
)
)
# create proxy to clear row selection (found 'Drinkdt' by looking in the source)
Drink_proxy <- DT::dataTableProxy('Drinkdt')
Container_Results <- dtedit(
input, output,
name = 'Container',
thedata = data.frame(
ID = c(1:3),
Container = c('Cup', 'Glass', 'Pint'),
stringsAsFactors = FALSE
)
)
# create proxy to clear row selection
Container_proxy <- DT::dataTableProxy('Container')
# manually toggle visibility for New button
observeEvent(input$showhide, {
shinyjs::toggle('Container_add')
})
# clear Drink row selection
observeEvent(input$clearrows, {
Drink_proxy %>% selectRows(NULL)
})
# when no drink is selected, hide the New button for containers
observeEvent(Drink_Results$rows_selected, {
if ( length(Drink_Results$rows_selected) ) {
shinyjs::show('Container_add')
} else {
shinyjs::hide('Container_add')
}
})
# attempt to react on clearing the row-selection
choice <- reactive({
paste0(Drink_Results$rows_selected, " - ", Container_Results$rows_selected)
})
# output current combination
output$choice <- renderText({ as.character(choice()) })
}
ui <- tagList(useShinyjs(),
fluidPage(
shinyFeedback::useShinyFeedback(),
h3('What will you drink?'),
uiOutput('Drink'),
# manually clear row selections
actionButton(inputId="clearrows", label="clear selected drink", icon=icon('trash')),
hr(),
h3("What container do you prefer?"),
uiOutput('Container'),
hr(),
# manually hide the New button
actionButton(inputId="showhide", label="toggle New buttons", icon=icon('refresh')),
hr(),
# show current user choices
textOutput('choice'),
)
)
shinyApp(ui = ui, server = server)
The reactive for selected row is input$Drinkdt_rows_selected
in your case, based on the source code. If you use that, your code works fine. Try this
server <- function(input, output) {
## could not install DTedit. So, made a copy of the function
source("C:\\RStuff\\GWS\\dtedit.R", local=TRUE)
Drink_Results <- dtedit(
input, output,
name = 'Drink',
thedata = data.frame(
ID = c(1:3),
drink = c('Tea', 'Coffea', 'Water'),
stringsAsFactors = FALSE
)
)
name <- "Drink"
# create proxy to clear row selection (found Drinkdt by looking in the source)
Drink_proxy <- DT::dataTableProxy('Drinkdt')
Container_Results <- dtedit(
input, output,
name = 'Container',
thedata = data.frame(
ID = c(1:3),
Container = c('Cup', 'Glass', 'Pint'),
stringsAsFactors = FALSE
)
)
# create proxy to clear row selection
Container_proxy <- DT::dataTableProxy('Container')
# clear Drink row selection
observeEvent(input$clearrows, {
Drink_proxy %>% selectRows(NULL)
shinyjs::hide('Container_add')
})
sel <- reactive({!is.null(input[[paste0(name, 'dt_rows_selected')]])})
observe({
print(sel())
print(input$Drinkdt_rows_selected)
})
# when no drink is selected, hide the New button for containers
observe({
#observeEvent(input[[paste0(name, 'dt_rows_selected')]], {
if ( length(input[[paste0(name, 'dt_rows_selected')]])>0 ) {
shinyjs::show('Container_add')
}else {
shinyjs::hide('Container_add')
}
})
observeEvent(Drink_Results$thedata, {
message(Drink_Results$thedata)
})
observeEvent(input[[paste0(name, 'dt_rows_selected')]], ignoreNULL = FALSE, {
# 'no' (NULL) row will be 'selected' after each edit of the data
message(paste("Selected row:", input[[paste0(name, 'dt_rows_selected')]]))
})
# attempt to react on clearing the row-selection
choice <- reactive({
if (is.null(input[[paste0(name, 'dt_rows_selected')]])) {
paste0("Drink not selected")
}else {
paste0(input[[paste0(name, 'dt_rows_selected')]], " - ", input$Containerdt_rows_selected)
}
})
observeEvent(input$showhide, {
toggle('Container_add')
})
# output current combination
output$choice <- renderText({ choice() })
}
ui <- fluidPage(
shinyFeedback::useShinyFeedback(),
useShinyjs(),
h3('What will you drink?'),
uiOutput('Drink'),
# manually clear row selections
actionButton(inputId="clearrows", label="clear selected drink", icon=icon('trash')),
hr(),
h3("What container do you prefer?"),
uiOutput('Container'),
hr(),
# manually hide the New button
actionButton(inputId="showhide", label="toggle New buttons", icon=icon('refresh')),
hr(),
# show current user choices
textOutput('choice'),
)
shinyApp(ui = ui, server = server)