Reputation: 1280
I'm trying to be able to edit a table through a text input followed by an action button. In addition, I'd like the data to stay changed, so that if I reload the app or enter in new data into the text input, the previous input doesn't revert to the previous value.
I feel like there is likely a simple way to do this, and I see things like this, where we can delete rows: Are table displayed on shiny,read only? But that wouldn't help for when you reload the app. In addition, I don't seem quite able to apply it to just changing a specific cell.
Below I have some simplified code, using mtcars. I added two columns, one giving a Car number, and one for if the car is good. So essentially, I would like to be able to enter 1, then row Car_number 1 will have Good_car column changed to True. Then, when I enter 2, I'd like for both the previous 1 and now 2 to also be True. And finally, next time I reload the app I want them to still be True.
The second data table is just showing that I know the dplyr mutate replace can change specific things in a data table, because when I enter the car number using that it will change Good_car to T for that number, until the input changes then it will revert back.
library(shiny)
library(dplyr)
library(DT)
mtbetter<-mtcars%>%
mutate(Car_number = c(1:32),
Good_car = F)
ui <- fluidPage(
textInput(inputId = "text", label = "Filter Car Number"),
actionButton("action", "Go!"),
dataTableOutput(outputId = "table"),
dataTableOutput(outputId = "table2")
)
server = function(input, output, session){
mtfinal = reactiveVal(mtbetter)
output$table<-renderDataTable({
mtfinal()
})
observeEvent(input$action, {mtfinal()%>%
mutate(Good_car = replace(Good_car, Car_number == input$text, T))})
output$table2<-renderDataTable({
mtbetter2<-mtbetter%>%
mutate(Good_car = replace(Good_car, Car_number == input$text, T))
mtbetter2
})
}
shinyApp(ui, server)
I also suspect that Replacedata will do it, but admittedly the documentation still can go over my head sometimes: https://rdrr.io/cran/DT/man/replaceData.html
Upvotes: 2
Views: 2265
Reputation: 25435
You are really close, all you need to do is modify your observeEvent
:
observeEvent(input$action, {mtfinal(mtfinal()%>%
mutate(Good_car = replace(Good_car, Car_number == input$text, T)))})
Why your solution does not do what you want it to do: You call the value of mtfinal()
and filter from there. However, you do not write the resulting table back to mtfinal()
. So the next time you want to update it, you start again with the initial value for mtfinal()
. Since you can set a new value for a reactiveVal
called y
to x
by doing y(x)
, all we need to do is wrap the entire statement in mtfinal(...)
. Hope this helps!
Upvotes: 1