I have a df dataframe. I would like to display each row. I would like to add on each line a button Show_Hide which will display other ui element below line l (between lines l and l+1).
How can I do this ? I was thinking of created a conditionalPanel but how can I test if the button is clicked?
I created a lapply loop to listen to all Show_Hide buttons but i get an error
mod_test_ui <- function(id){ ns <- NS(id) tagList(
uiOutput(ns("table")))}
mod_test_server <- function(id){ moduleServer( id, function(input, output, session){ ns <- session$ns
df <- reactiveVal(data.frame(index = 1:5, nom = c("Alice", "Bob", "Charlie", "David", "Eve"), val1 = c(10, 20, 30, 40, 50), val2 = c(5, 4, 3, 2, 1)))
df2 <- data.frame(matrix(rnorm(20 * 10), nrow = 20))
output$table <- renderUI({
lapply(1:nrow(df()), function(i) {
id_sh <- paste0("sh", df()$index[i])
condition_sh <- sprintf("input.%s %% 2 === 0", id_sh)
id_del <- paste0("del", df()$index[i])
id_table <- paste0("t", df()$index[i])
id_name <- paste0("name", df()$index[i])
fluidRow(
column(2, p(df()$index[i])),
column(2, textInput(ns(id_name), label = NULL, value = df()$nom[i])),
column(2, p(df()$val1[i])),
column(2, p(df()$val2[i])),
column(2, actionButton(ns(id_sh), label = "Show_Hide")),
column(2, actionButton(ns(id_del), label = "Delete")),
column(
12,
dataTableOutput(ns(id_table)),
),
)})})
#Observe button "Show_Hide"
lapply(1:nrow(df()), function(i) {
observeEvent(input[[paste0("sh", df()$index[i])]], {
cat("Button Show_Hide pressed : ", paste0("sh", df()$index[i]), "\n")
id_table <- paste("t", i)
output[[id_table]] <- renderTable(head(df2))
})})
})}
When I run the application golem::run_dev() I get an error:
Warning: 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 consumer.
mod_test_ui <- function(id){
ns <- NS(id)
tagList(
uiOutput(ns("table"))
)
}
mod_test_server <- function(id){
moduleServer( id, function(input, output, session){
ns <- session$ns
df <- reactiveVal(data.frame(
index = 1:5,
nom = c("Alice", "Bob", "Charlie", "David", "Eve"),
val1 = c(10, 20, 30, 40, 50),
val2 = c(5, 4, 3, 2, 1)
))
df2 <- data.frame(matrix(rnorm(20 * 10), nrow = 20))
output$table <- renderUI({
if(nrow(df()!= 0)){
lapply(1:nrow(df()), function(i) {
id_sh <- paste0("sh", df()$index[i])
condition_sh <- sprintf("input.%s %% 2 === 0", id_sh)
id_del <- paste0("del", df()$index[i])
id_table <- paste0("t", df()$index[i])
id_name <- paste0("name", df()$index[i])
fluidRow(
column(2, p(df()$index[i])),
column(2, textInput(ns(id_name), label = NULL, value = df()$nom[i])),
column(2, p(df()$val1[i])),
column(2, p(df()$val2[i])),
column(2, actionButton(ns(id_sh), label = "Show_Hide")),
column(2, actionButton(ns(id_del), label = "Delete")),
column(
12,
uiOutput(ns(id_table)),
),
)
})
}
})
lapply(1:5, function(i) {
observeEvent(input[[paste0("del", i)]], {
df(subset(df(), index != i))
})
})
lapply(1:5, function(i) {
observeEvent(input[[paste0("sh", i)]], {
id_t <- paste0("t", i)
if(input[[paste0("sh", i)]]%%2 == 0){
output[[id_t]] <- renderTable(NULL)
} else {
output[[id_t]] <- renderTable(head(df2))
}
cat("Bouton cliqué:", id_t, "\n")
})
})
})
}
I think I misunderstood where you want to place the conditional panel but here is the idea.
An action button initially takes the value
0, and this value is incremented by1each time you click the button. So, if you want to detect the click in a conditional panel, you can check whether the value is odd or even, i.e. whether it equals 0 modulo 2:Thus: