Reset Inputs' Button in Shiny App

Reset inputs' button in shiny app

There isn't such a function in shiny, however, here's a way to accomplish this without having to essentially define your inputs twice. The trick is to use uiOutput and wrap the inputs you want to reset in a div whose id changes to something new each time the reset button is pressed.

library(shiny)

runApp(list(

ui = pageWithSidebar(

headerPanel("'Reset inputs' button example"),

sidebarPanel(
uiOutput('resetable_input'),
tags$hr(),
actionButton("reset_input", "Reset inputs")
),

mainPanel(
h4("Summary"),
verbatimTextOutput("summary")
)

),

server = function(input, output, session) {

output$summary <- renderText({
return(paste(input$mytext, input$mynumber))
})

output$resetable_input <- renderUI({
times <- input$reset_input
div(id=letters[(times %% length(letters)) + 1],
numericInput("mynumber", "Enter a number", 20),
textInput("mytext", "Enter a text", "test"))
})

}
))

Reset action button output in shiny

In my answer below I will demonstrate how to achieve what you're asking for. In my answer I use the shinyjs package, both for resetting input values and for hiding/showing the results. I cannot run your code because there are extra packages and functions that you are using that I don't know about, and the code itself is not a minimal isolated example, so instead I'll write my own small app that does something similar and achieves what you want. Here is the code:

library(shiny)

ui <- fluidPage(
shinyjs::useShinyjs(),
numericInput("num", "Enter a number", 7),
actionButton("submit", "Square that number!"),
actionButton("reset", "Reset"),
shinyjs::hidden(
div(
id = "results",
h3("The square is"),
textOutput("square")
)
)
)

server <- function(input, output, session) {
output$square <- renderText({
input$submit
isolate(input$num * input$num)
})

observeEvent(input$reset, {
shinyjs::reset("num")
shinyjs::hide("results")
})

observeEvent(input$submit, {
shinyjs::show("results")
})
}

shinyApp(ui = ui, server = server)

To address your two questions specifically and how they are solved above:

  1. To reset inputs to their original value, I use the shinyjs::reset() function. This is a much better approach than updating the inputs to a particular value, because the reset() function will guarantee to reset it to whatever value it was originally, whereas your approach means that if you change the initial value in the UI, you must remember to change it in the server as well.

  2. To hide the results after pressing reset, I wrapped all the results UI inside a div(id = "results", ...). Then whenever the submit button is pressed, I use shinyjs to show it, and when reset is pressed I use shinyjs to hide it. I also wrapped the UI in a shinyjs::hidden(...) because you want the results to start off as not showing.

Both of the above require a call to shinyjs::useShinyjs() in the UI.

You should be able to build off this example and implement these techniques in your more complex app.

Also note that my sample app above does a few other things differently than yours. For example, you should not use output$X <- eventReactive(...). You should use the render functions (such as renderText()) when assigning into outputs.

How do I make a Shiny reset button that resets input values then updates data?

actionButton() function has an internal value that increments by 1 each time it is pressed. For resetting the app, i can think of using session$reload() if there are no other tabs you need to conserve. If only a portion of the ui needs to reset, then you can call renderUI inside observeEvent.

Finally, for the update button we can use the input values but isolate them so the only thing that triggers an update is clicking the button and not changing in this case the slider.

library(shiny)

tab1_ui <- tagList(
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30),
actionButton('reset', 'RESET'),
actionButton("update","UPDATE"),
),
mainPanel(
plotOutput("distPlot")
) )
)

ui <- navbarPage(
title = "Old Faithful Geyser Data",
tabPanel('Tab 1',
uiOutput('tab_1_ui')),
tabPanel('Tab 2',
selectInput('iris_nms', 'Select Column', names(iris)))
)

server <- function(input, output,session) {

#show the ui at the start of the app.
output$tab_1_ui <- renderUI({
tab1_ui
})

# When reset button is pressed, reset the slider value and send a 'push update' signal
observeEvent(input$reset,{
output$tab_1_ui <- renderUI({
tab1_ui
})
})

# When update button is pressed, send a 'push update' signal
observe({
input$update
input$reset
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = isolate(input$bins[1]))
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})

})


}

shinyApp(ui = ui, server = server)

Reset inputs with reactive app in shiny

Here is the code that should work for You:

l <- NULL
l$name <- c('b','e','d','b','b','d','e','e','b','b')
l$age <- c(20,20,21,21,20,22,22,30,21,32)
l$gender <- c('Female', 'Female', 'Male', 'Female', 'Male','Male',
'Female','Male',"Female","Male")

l <- as.data.frame(l)
l$name <- as.character(l$name)
l$age <- as.numeric(l$age)
l$gender <- as.character(l$gender)


library(shiny)
library(shinyjs)
server <- shinyServer(function(input,output){

observeEvent(input$reset, {
shinyjs::reset("name")
shinyjs::reset("age")
shinyjs::reset("gender")

})

# DEfinition of all values of my variables
assign('All Names',unique(sort(l$name)))
assign("All Ages", unique(sort(l$age)))
assign('All Genders', unique(sort(l$gender)))


data1 <- reactive({
l[which(l$name %in% if(exists(input$name))
{get(input$name)}else{input$name}),]
})




data2 <- reactive(data1()[which(data1()$age %in% if(exists(input$age))
{get(input$age)}else{input$age}),])


data3 <- eventReactive(input$baba, {
data2()[which(data2()$gender %in% if(exists(input$gender))
{get(input$gender)}else{input$gender}),]
})

output$table3 <- renderTable({
data3()
})


output$Box1 = renderUI(
if((is.null(input$age)) & (is.null(input$gender))){
selectInput("name", "Choose Name", choices=c("All Names",unique(sort(l$name))), selected = "All Names")
} else{selectInput("name", "Choose Name", choices=c("All Names",
unique(l[l$gender %in% (if(exists(input$gender)){
get(input$gender)
}else{
input$gender}) &
l$age %in% (if(exists(input$age)){
get(input$age)
}else{input$age}), "name"])), selected = "All Names")
}
)



output$Box2 = renderUI(
if((is.null(input$name)) & (is.null(input$gender))){
selectInput("age", "Choose Age", choices=c("All Ages", unique(sort(l$age))), selected = "All Ages")
}else{selectInput("age", "Choose Age", choices=c("All Ages",unique(l[l$gender %in% (if(exists(input$gender)){get(input$gender)}else{input$gender}) & l$name %in% (if(exists(input$name)){get(input$name)}else{input$name}) , "age"])), selected = "All Ages")}
)


output$Box3 = renderUI(
if((is.null(input$name)) & (is.null(input$age))){
selectInput("gender", "Choose Gender", choices=c("All Genders", unique(sort(l$gender))), selected = "All Genders")
}else{
selectInput("gender", "Choose Gender", choices=c("All Genders", unique(l[l$name %in% (if(exists(input$name)){get(input$name)}else{input$name}) & l$age %in% (if(exists(input$age)){get(input$age)}else{input$age}), "gender"])), selected = "All Genders")
}
)



})

ui <-shinyUI(fluidPage(
useShinyjs(),
uiOutput("Box1"),
uiOutput("Box2"),
uiOutput("Box3"),
actionButton("baba", "GO !"),
actionButton("reset", "reset"),
tableOutput("table3")
))

shinyApp(ui,server)

There are two things that were creating a problem, and it is not the package shinyjs, rather Your code:

1. You did not have a selected value in the widgets, You had for example: selected = input$age but not fixed value to reset to (i have changed it to selected = "All ages", etc.)

2. You should use shinyjs::reset() function with the id of the widget, such as in Your case: name, age and gender and not as You have: Box1,Box2,Box3

Problem with reset button that I created in shiny code

The following should do it. It requires a bit more checking...

  my <- reactiveValues(plot=NULL)
output$graph <- renderPlot({
if (!is.null(input$date2) & !is.null(input$code)) {
my$plot <- f1(data(),as.character(input$date2),as.character(input$code))
}else {
my$plot <- NULL
}
my$plot
})

observeEvent(input$reset, {
df1 <- data()
my$plot <- NULL
updateDateInput(session, 'date2', value = NA)
updateSelectInput(session, 'code', h4("Category"),choices= unique(df1$Category), selected=character(0))
})

Adjust reset button position and display in shiny

Try

                       conditionalPanel(
condition = "output.mycode",
actionButton("reset", "Reset")
),

Full code

function.test<-function(){

df1 <- structure(
list(date1= c("2021-06-28","2021-06-28","2021-06-28"),
date2 = c("2021-07-01","2021-07-02","2021-07-04"),
Category = c("ABC","ABC","ABC"),
Week= c("Wednesday","Wednesday","Wednesday"),
DR1 = c(4,1,0),
DR01 = c(4,1,0), DR02= c(4,2,0),DR03= c(9,5,0),
DR04 = c(5,4,0),DR05 = c(5,4,0),DR06 = c(5,4,0),DR07 = c(5,4,0),DR08 = c(5,4,0)),
class = "data.frame", row.names = c(NA, -3L))



return(df1)
}

library(shiny)
library(shinythemes)
library(dplyr)


ui <- fluidPage(

ui <- shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
br(),

fluidRow(
column(3,
wellPanel(uiOutput("date"),
uiOutput("mycode")
),
conditionalPanel(condition = "output.mycode", actionButton("reset", "Reset") )
),

column(9,
wellPanel(
plotOutput("graph",width = "100%", height = "600")
))
)
))


server <- function(input, output,session) {

data <- reactive(function.test())

output$date <- renderUI({
req(data())
all_dates <- seq(as.Date('2021-01-01'), as.Date('2021-01-15'), by = "day")
disabled <- as.Date(setdiff(all_dates, as.Date(data()$date2)), origin = "1970-01-01")
dateInput(input = "date2",
label = h4("Data"),
min = min(data()$date2),
max = max(data()$date2),
value = NA, # min(data()$date2),
format = "dd-mm-yyyy",
datesdisabled = disabled)

})

output$mycode <- renderUI({
req(input$date2)
df1 <- data()
df2 <- df1[as.Date(df1$date2) %in% input$date2,]
selectInput("code", label = h4("Category"),choices=unique(df2$Category))
})

output$graph <- renderPlot({
req(input$date2,input$code)
f1(data(),as.character(input$date2),as.character(input$code))
})

my <- reactiveValues(plot=NULL)
output$graph <- renderPlot({
if (!is.null(input$date2) & !is.null(input$code)) {
my$plot <- plot(cars) ### f1(data(),as.character(input$date2),as.character(input$code))
}else {
my$plot <- NULL
}
my$plot
})

observeEvent(input$reset, {
df1 <- data()
my$plot <- NULL
updateDateInput(session, 'date2', value = NA)
})

}

shinyApp(ui = ui, server = server)

output

How I should create a clear button for eliminating rows in R shiny?

The problem here is a slight oversight in how the selected rows are obtained for deletion. Instead of getting selected rows from the DT table, one has to get them straight from the ui element which is DT2

Also, you can work directly on the DT table created in server, instead of storing a new reactive value

Here's the revised (relevant) server code :

  #xxxxxxxx this   not needed 
#values <- reactiveValues(df_data = new_frame)

observeEvent(input$clear,{

if (!length(input$DT2_rows_selected)==0) {
#work directly on store variable
store$value<- store$value[-as.numeric(input$DT2_rows_selected),]
}


})

I've tested this and it works. Can post the whole app code if needed.



Related Topics



Leave a reply



Submit