I have a Shiny app that allows user to edit record notes by clicking a button in the table. It works for first click, but immediately after you close the the edit dialogue (OK or cancel) the same button becomes innert. If you click a second button the first then becomes active again. Any idea how to fix this?
require(shiny)
require(DT)
require(tidyverse)
states_dat = tibble(id = state.abb, name = state.name, pop = state.x77[,1], note = NA_character_)
#------------------------------------------------
# Return the UI for a modal dialog with state update options
editModal = function(conv_id) {
ns = NS('state-update')
curr_mon_id <<- conv_id
conv = dplyr::filter(my_dt$df, id == conv_id$id)
modalDialog(
h3(paste0('Edit note ', conv_id)),
textInput(ns("edit_note"), "Note", value = conv$note, width='600px'),
footer = tagList(
modalButton("Cancel"),
actionButton(ns("ok"), "OK")
)
)
}
#------------------------------------------------
# Main screen server
dt_server = function(input, output, session) {
ns = session$ns
myValue = reactiveValues(check = '')
shinyInput = function(FUN, len, id, ns, ...) {
inputs = character(len)
for (i in seq_len(len)) inputs[i] = as.character(FUN(paste0(id, i), ...))
inputs
}
my_dt <<- reactiveValues(df = {
dat = states_dat
dat$` ` = shinyInput(actionButton, nrow(dat), 'button_', label = "Edit note",
onclick = glue::glue('Shiny.onInputChange("{ns("select_button")}", this.id)'))
dat
})
observeEvent(input$select_button, {
selectedRow = as.numeric(strsplit(input$select_button, "_")[[1]][2])
myValue$check <<- my_dt$df[selectedRow,1]
showModal(editModal(myValue$check))
})
output$states_table = DT::renderDT(filter = "top", {
return(my_dt$df)
}, escape = FALSE)
}
#------------------------------------------------
# Record Update server
mud_server = function(input, output, session) {
ns = session$ns
# When OK button is pressed, check if details have changed and if so update postgres db
observeEvent(input$ok, {
id = curr_mon_id$id[1]
if(!identical(input$edit_note, states_dat$note[states_dat$id == id])){
my_dt$df$note[my_dt$df$id == id] = input$edit_note
}
removeModal()
})
}
#------------------------------------------------
# Data table UI
dt_ui = function(id){
ns = NS(id)
tagList(
titlePanel( h3('State populations'), windowTitle = 'States-Pop'), hr(),
mainPanel(width=12, DT::DTOutput(ns("states_table"))
)
)
}
#------------------------------------------------
ui = fluidPage( dt_ui(id = "states-manager"))
server = function(input, output, session) {
callModule(module = dt_server , id = "states-manager")
callModule(module = mud_server , id = "state-update")
}
shinyApp(ui = ui, server = server)
Any other brief comments on how to improve this app would be very welcome. This is my first experience of Shiny modules so it be far from an optimal configuration. For instance note edits wipe any current table filters in place..