please refer to the reproducible code below. Everything works fine up to one point. If you select a team, and choose a weight through pushing the action buttons, and then click the populate button, a table appears with the weights.
One thing though. If you select, say team = a, and input 10%, and switch to team = b. The input is still at 10%. I'd like it to revert back to 0 so you always start anew.
Anyway to do this?
library(shiny)
library(dplyr)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
df = data.frame(team = c("a", "b", "c", "d"),
weights = c(0, 0, 0, 0))
df
ui = dashboardPage(
header = dashboardHeader(title = "teams"),
sidebar = dashboardSidebar(),
body = dashboardBody(
prettyRadioButtons(
inputId = "radio1",
label = "Select Teams",
choices = df$team
),
br(),
div(style = "margin-top: 10px;width: 100px; display: inline-block", textOutput("text1a")),
div(
style = "width: 25px; display: inline-block; margin-left: 1px",
actionBttn(
inputId = "action1a",
size = "xs",
label = "-",
style = "material-flat",
color = "primary"
)
),
div(style = "width: 25px; display: inline-block; margin-left: 10px; text-align: center", textOutput("text1b")),
div(
style = "width: 25px; display: inline-block; margin-left: 25px",
actionBttn(
inputId = "action1b",
size = "xs",
label = " ",
style = "material-flat",
color = "primary"
)
),
br(),
br(),
actionBttn(
inputId = "populate",
size = "xs",
label = "Populate Weights",
style = "material-flat",
color = "danger"
),
br(),
br(),
div(style = "width: 800px; margin-left: 10px", tableOutput("table1"))
)) # End of Dashboard Body and Page
server = function(input, output, session) {
rv = reactiveValues(action1 = 0, df = df)
output$text1a = renderText(paste("Team", input$radio1, sep = " "))
rv$action1 = eventReactive(c(input$action1a, input$action1b),
{
min(max(-5 * input$action1a 5 * input$action1b,-50),50)
})
output$text1b = renderText({
if (rv$action1() >= 0) {
paste(" ", rv$action1(), sep = "")
}
else {
rv$action1()
}
})
rv$df = eventReactive(
input$populate,
df <<- rbind(
df %>% filter(team == input$radio1) %>% mutate(weights = rv$action1()),
df %>% filter(team != input$radio1)
) %>% arrange(team)
)
output$table1 = renderTable({
rv$df()
})
}
shinyApp(ui = ui,
server = server,
options = list(launch.browser = T))
CodePudding user response:
below is my interpretation of what you want. I put the info in the code too, but I'll give a brief idea here. Rather than use eventReactive
, I used reactiveValues
. This way I have a number that I can alter with different inputs. I then used observeEvent on each of the three inputs, radio1
, action1a
, and action1b
. If any button on radio1
is pressed, the reactiveValues
is set to 0. If action1a
is pressed, minus five from the reactiveValues
, and of course add 5 if action1b
is pressed.
library(dplyr)
library(shiny) #Added the library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
df = data.frame(team = c("a", "b", "c", "d"),
weights = c(0, 0, 0, 0))
df
ui = dashboardPage(
header = dashboardHeader(title = "teams"),
sidebar = dashboardSidebar(),
body = dashboardBody(
prettyRadioButtons(
inputId = "radio1",
label = "Select Teams",
choices = as.character(df$team)
),
br(),
div(style = "margin-top: 10px;width: 100px; display: inline-block", textOutput("text1a")),
div(
style = "width: 25px; display: inline-block; margin-left: 1px",
actionBttn(
inputId = "action1a",
size = "xs",
label = "-",
style = "material-flat",
color = "primary"
)
),
div(style = "width: 25px; display: inline-block; margin-left: 10px; text-align: center", textOutput("text1b")),
div(
style = "width: 25px; display: inline-block; margin-left: 25px",
actionBttn(
inputId = "action1b",
size = "xs",
label = " ",
style = "material-flat",
color = "primary"
)
),
br(),
br(),
actionBttn(
inputId = "populate",
size = "xs",
label = "Populate Weights",
style = "material-flat",
color = "danger"
),
br(),
br(),
div(style = "width: 800px; margin-left: 10px", tableOutput("table1"))
)) # End of Dashboard Body and Page
server = function(input, output, session) {
rv = reactiveValues(action1 = 0, df = df)
output$text1a = renderText(paste("Team", input$radio1, sep = " "))
DF<-reactiveValues("DF" = 0) #Using a reactiveValue instead of eventreactive
observeEvent(input$action1a,{ #Observe's action 1a. When pressed, take the current reactiveValue DF$DF, and -5
temp<-isolate(DF$DF)
DF$DF<-temp-5
})
observeEvent(input$action1b,{ #Observe's action 1b. When pressed, take the current reactiveValue DF$DF, and 5
temp<-isolate(DF$DF)
DF$DF<-temp 5
})
observeEvent(input$radio1,{ #Observe's radio1. If this button is changed, reset reactiveValue to 0.
DF$DF<-0
})
output$text1b = renderText({ #Rendertext only displays the reactiveValue
DF$DF
})
rv$df = eventReactive(
input$populate,
df <<- rbind(
df %>% filter(team == input$radio1) %>% mutate(weights = DF$DF), #Changed weights to be the reactiveValues
df %>% filter(team != input$radio1)
) %>% arrange(team)
)
output$table1 = renderTable({
rv$df()
})
}
shinyApp(ui = ui,
server = server,
options = list(launch.browser = T))
As I switched from eventReactive
, I can see this not being the ideal solution, but this is how I would accomplish what you are doing. An alternate idea is to use shinyjs
, which can reset certain inputs, though I'm not sure it would work with your original code as it may not reset an eventReactive
. Best of luck, I hope this helps!