My Shiny app has the following functionality. Alongside a table consisting of a reactiveValues
-nested reactive DT allocation_engine()
, the user inputs an amount that is automatically allocated across a DT
column ("Allocation") subject to some input constraints. This script works fine through the use of reactiveValues
.
I am also implementing the ability to manually enter cells in the Allocation column by allowing the DT to be editable. These entries are subject to one constraint. My script works in the sense that the constraint is active once, but not again! Firstly, let me elaborate;
The user's manual input DT$Allocation[i] <= DT$AIA[i]
must hold, where AIA simply is another column in the DT
rendered from reactiveValues
. Hence, if DT$AIA = c(10,20)
then the maximum manual entry into DT$Allocation[2]
is 20. If the user inputs 30, the actual implemented entry should thus be 20.
Bottom line: This restriction works, but only the first time that you cross the restriction! In the example above; If I enter DT$Allocation[2] = 30
one time, the resulting entry is 20 owing to the restriction. The next time I enter 30 in the same cell, the restriction does not work and the cell enters as 30, whilst the DT does not seem to update.
I have followed Yihui's editable DT guide in order to implement this logic: https://github.com/rstudio/DT/issues/28#issuecomment-236293247
Another SO question which relates to editing DT tables, for some background: R Shiny DT - edit values in table with reactive
My code follows below. Happy to provide more information if you feel that you can help me.
# Container for reactive values created here:
allocation_values = reactiveValues(rendered = NULL)
observe({
rendered = allocation_engine()
allocation_values$rendered = rendered
})
# The reactiveValue container is rendered as an editable DT
output$alloc_table = DT::renderDataTable(
allocation_values$rendered,
server=TRUE,
rownames = FALSE,
options=list(pageLength=10, search = list(smart = TRUE)),
selection = 'none',
editable = TRUE
)
alloc_table_proxy = DT::dataTableProxy('alloc_table')
observeEvent(input$alloc_table_cell_edit, {
#When the user carries out a manual entry:
info = input$alloc_table_cell_edit
str(info)
i = info$row
j = info$col
v = min(info$value, allocation_values$rendered$AIA[i])
# ^ Create a value [v] that is the minimum of the entry and the
# corresponding AIA of the same row as the entry
if (j == 9) { # If the input column is "Allocation"
# replace the selected row in Allocation with the
# variable [v] calculated above
allocation_values$rendered$Allocation[i] = DT::coerceValue(v,
allocation_values$rendered$Allocation[i])
# This step is actually unnecessary for my implementation,
# but included in Yihui's guide.
replaceData(alloc_table_proxy, allocation_values$rendered,
resetPaging=TRUE, rownames=FALSE)
}}
Thanks, J.