can an actionbutton be reseted to 0 inside server.R?
let's say i have actionButton("b1","button1"). what could be the code for reseting the action button to 0?
No, not at this time. Can you talk a little about why you want this? Thanks...
i was trying to bypass the issue with the radiobuttons(and the updateradiobuttons).so here is the logic. We have 2 buttons lets say b1 and b2. when a button is pushed then it is increased by 1 in server.R we render some text for this action.after it, the button must reseted to 0 so that if the state of a button is 1 it must trigger some text rendering and etc. but i think you gave me the answer. but it would be a nice addition for some ui control enhancement.what's your opinion?
Don't think of the value of the input$actionButtonId as being meaningful, _except_ for the special case of 0, which means "the button hasn't been pressed yet". In all other cases, you should just rely on the fact that input$actionButtonId changes and invalidates your reactive expression or observer. If you find yourself checking the actual value of input$actionButtonId (other than testing for 0) then it's a good sign you probably need to look again at using isolate
:
# Take an action when button is clicked
observe({
if (input$actionButtonId == 0)
return()
isolate({
# Your logic here
})
})
# Render text when button is clicked
output$text <- renderText({
if (input$actionButtonId == 0)
return("")
isolate({
# Your logic here
})
})
Actually I think the reset is useful. I have an app that contains multiple projects. E.g. each project could be a different data set I am analysing, so when I switch projects I would want to reset all buttons as if they have never been pressed.
I have the exact same problem where resetting the actionbuttons would help alot. An user is able to switch locations / working directories where he can analyse & create plots for different data sets. For all these different data sets the same plot buttons are being used. As soon as you would change the working directory now all scripts get called because buttons have been pressed already.
I'm facing this issue too. I have two buttons add and clear to build a query. when i select something and say add, that term should be added to query and if click on clear button, it should clear the query. i'm checking for add_button>0 now but that won't really solve my purpose because when i select something else after clicking add button it'll automatically be added to the query. i tried resetting the actionbutton value but really could not.
i did an odd workaround instead, using a var which i reset to 0 as soon as the button is pressed. I'm using input$h5fileName so the user can load another file.
observe ({
input$h5fileName
counter_createTime_Plot <<- 0
})
when call the function i want to run i increment this ensuring its run every time i actually press the actionButton.
observe({
# increment the counter so i know it has been pressed
if (counter_createTime_Plot == 0)
counter_createTime_Plot <<- counter_createTime_Plot + 1
#returning when the ui.R is opened the first time
if (input$createTime_Plot == 0)
return()
# run the function because the button is clicked once after loading a new file
else if (counter_createTime_Plot == 1) {
})
I use the counter value 1 to do a check if the file is correct, using a next if statement with if (counter_createTime_Plot > 1) to use the same actionButton for doing something else. It's not a pretty solution but for now it works the way i want it to. Being able to reset would still be much better.
I still don't think you need this. If your add logic is surrounded by isolate you shouldn't have this problem. If I'm wrong, let me know.
in sarvagna's case most likely yes, since i suspect his input field is in the same observer as both actionButtons (maybe share the code?). In my case however i have a button which has to check the data input when it is clicked the first time, when clicking it for the second time it should not check the datainput but create a plot instead. A third click would do nothing since the data is validated and the plot has been made.
The user is also able to switch files however and as soon as he/she does the plot button became useless. In this situation it would be perfect if i could just reset the actionbutton instead when a a different file is loaded. Now i have to keep track how many times it is clicked with an external counter variable.
Here is my code, i tried to use the logic you mentioned. this works well first time i click either add or clear button. but after that the buttons are useless.
observe({
if (input$add_button == 0)
return()
isolate({
selected_term_ids<-c(input$thti,input$select_child_terms)
if((!is.null(selected_term_ids)) & length(selected_term_ids)>0){
onto <- input$search_option
selected_terms <- get_onto_terms_by_ids(paste0(selected_term_ids,collapse=","))
}
if(!is.null(DisplayString$names)){
DisplayString$names<-unique(append(DisplayString$names,selected_terms$term))
QueryString$names<-unique(append(QueryString$names,selected_term_ids))
}
else{
DisplayString$names<-selected_terms$term
QueryString$names<-selected_term_ids
}
output$dynamic_value <- renderText({
paste0(DisplayString$names, collapse=",")
})
})
if(input$clear_button == 0)
return()
isolate({
DisplayString$names<- NULL
QueryString$names <- NULL
output$dynamic_value <- renderText({DisplayString$names})
})
})
Try using two observers, one for each button. Also, what are DisplayString and QueryString? Just normal lists or reactiveValues objects?
they are reactiveValues objects. I'll be using the displaystring in verbatimtextoutput and querystring in db query function further down the code
In that case output$dynamic_value only needs to be assigned once, outside of any observer.
Well i did something like this and it seems to be working for now.
#Build query
DisplayString <- reactiveValues()
QueryString <- reactiveValues()
observe({
if (input$add_button > 0){
isolate({
selected_term_ids<-c(input$thti,input$select_child_terms)
if((!is.null(selected_term_ids)) & length(selected_term_ids)>0){
onto <- input$search_option
selected_terms <- get_onto_terms_by_ids(paste0(selected_term_ids,collapse=","))
}
if(!is.null(DisplayString$names)){
DisplayString$names<-unique(append(DisplayString$names,selected_terms$term))
QueryString$names<-unique(append(QueryString$names,selected_term_ids))
}
else{
DisplayString$names<-selected_terms$term
QueryString$names<-selected_term_ids
}
})
}
#Clear selection
if(input$clear_button >= input$add_button){
isolate({
DisplayString$names<- NULL
QueryString$names <- NULL
})
}
})
#Show selected terms
output$dynamic_value <- renderText({
paste0(DisplayString$names, collapse=",")
})
I really wish one could reset an actionButton to 0.
@sharko666 Let me know if you have a simple example of why you need that. I'm totally open to being convinced but haven't seen any scenarios so far that weren't better handled using the idioms we've already established.
Joe, Did you send this to me by mistake? I'm not sharko666.
On Mon, Oct 13, 2014 at 11:29 AM, Joe Cheng [email protected]
wrote:
@sharko666 https://github.com/sharko666 Let me know if you have a
simple example of why you need that. I'm totally open to being convinced
but haven't seen any scenarios so far that weren't better handled using the
idioms we've already established.—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-58934438.
Marc-david Cohen | Chief Science Officer | +1.415.205.6295 |
www.aktana.com
_The power of many, the focus of one_
@Marccohen You probably got a copy of the message because you're watching the shiny repository on github.
Hi Joe,
I'm working on a application which takes an URL into a text field and loads data sets from an URL. That works fine as long as the user copy and pastes the URL into the text field. If there is a mistake in the URL or it is typed in, shiny constantly tries to load data from an unfinished URL. That's why I thought I add a submit button to it. That improved things that now the URL also can be typed in as nothing happens as long as the button is pressed. The new problem arises when another URL after the first one is typed in. The counter is already higher than 0 so the button is marked as pressed. So this works only for the first time. This problem would have been easily solved if there would be a way to reset the counter in the logic part when the dataset is loaded or an appropriate error (if the URL is still wrong) is caught.
Now, I found a solution but it might not be the solution as shiny is supposed to work. I have a global variable set in the reactiveValues function called actionCounter. Every time the button is pressed the buttoncounter is increased and is higher than the actionCounter. Inside the logic the action counter is set to the buttoncounter. Now I only test whether the actionCounter is lower than the buttonCounter. See code below.
vars = reactiveValues(actionCounter=0)
url = input$URL_input
if(!is.null(input$submit_URL)){
if(input$submit_URL>vars$actionCounter&url!=""){
vars$actionCounter=input$submit_URL
# try load the data
}
}
So there is a relative easy solution but if there were the possibility to reset the button counter it would have been simpler and easier to understand.
Regards
Christoph
From: Marc Cohen [[email protected]]
Sent: Tuesday, October 14, 2014 7:37
To: rstudio/shiny
Cc: Christoph Knapp
Subject: Re: [shiny] reset value of actionButton? (#167)
Joe, Did you send this to me by mistake? I'm not sharko666.
On Mon, Oct 13, 2014 at 11:29 AM, Joe Cheng [email protected]
wrote:
@sharko666 https://github.com/sharko666 Let me know if you have a
simple example of why you need that. I'm totally open to being convinced
but haven't seen any scenarios so far that weren't better handled using the
idioms we've already established.—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-58934438.
Marc-david Cohen | Chief Science Officer | +1.415.205.6295 |
www.aktana.com
_The power of many, the focus of one_
—
Reply to this email directly or view it on GitHubhttps://github.com/rstudio/shiny/issues/167#issuecomment-58935448.
Thanks for the feedback. This is the idiomatic way to handle such a situation:
url <- reactive({
if (input$submit_URL == 0) {
return(NULL)
}
isolate(input$URL_input)
})
Then everywhere you want to access the URL, use url()
.
It is a longstanding grievance against Shiny that we don't have wrapper functions for this idiom.
@sharko666 I just merged a very longstanding pull request into master. With this change you can now do this instead:
url <- reactive({
eventFilter(input$submit_URL, input$URL_input)
})
This basically means "the value of url
is nothing (NULL) at first, but every time input$submit_URL
is clicked, set it to the then-current value of input$URL_input
".
There is a complementary observeEvent
function as well:
observeEvent(input$submit_URL, function() {
# Do something involving input$URL_input
})
The "do something" part of the code will be executed when and only when the button is clicked.
@jcheng5 I just used the new version of Shiny - 10.2.9 for the new observeEvent function. It works great on my desktop version of R studio, but I am trying to run this using a portable R and Chrome install from a flash drive. This worked fine with shiny 10.2.1 because I was able to find a zip that worked for shiny 10.2.1. I have tried going though github, but am not sure how I can find (or create) a 10.2.9 zip that will work for a portable (32 bit) install of R. If you could point be in the right direction that would be much appreciated. Thanks :)
@dakshvarma Is there a reason that devtools::install_github` wouldn't work with your portable R?
@jcheng5 Got it working finally! devtools::install_github installs it by creating a local folder. The trick is to zip up the local folder, install a package from the zip in the portable install (with the zip in the same folder as portable R). Thanks for your help!
i have the following case:
2 actionsbuttons (Generate and Reset) that should be used under ONE renderPlot.
How to handle this situation? Appreciate your help
output$Result <- renderPlot({
if(input$GEN_button == 0){
# mylogic
}
else if(input$RES_button == 0){
# mylogic
}
else {
# mylogic
}
})
What does Reset do, clear it? What should the initial state of the plot
be--should it be generated when the app first starts up, or should it be
blank?
On Tue, Nov 18, 2014 at 8:37 AM, Hratch [email protected] wrote:
i have the following case:
2 actionsbuttons (Generate and Reset) that should be used under ONE
renderPlot.
How to handle this situation? Appreciate your helpoutput$Result <- renderPlot({
if(input$GEN_button == 0){
# mylogic
}
else if if(input$RES_button == 0){
# mylogic
}
else {
# mylogic
}
})—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63500459.
Reset sets back the value of the matrix to be plotted to an initial value.
The initial state (Initial run) should show plot the matrix that is created within the logic.
If Generate Button is clicked then a new matrix will be generated and plotted.
That means the matrix can be calculated outside the renderPlot too right?
In that case, it sounds like both Generate at Reset should affect not the
plot directly, but a matrix value.
initialMatrixValue <- ...
shinyServer(function(input, output, session) {
values <- reactiveValues(matrix = initialMatrixValue)
observe({
if (input$GEN_button == 0)
return()
values$matrix <- ... # Generate the matrix here
})
observe({
if (input$RES_button == 0)
return()
values$matrix <- initialMatrixValue
})
output$Result <- renderPlot({
plot(values$matrix) # or whatever
})
})
Thank you for your fast feedback/solution, you're great.
I am trying to do something similar and have multiple issues:
ui.R:
textInput("word", "Phrase", value=""),
textInput("predictedword", "Next Word:", value=""),
actionButton("accept", "Accept")
server.R
shinyServer(
function(input, output, session) {
observe ({
if (input$accept > 0) {
predicted <- paste(input$word, input$predictedword)
updateTextInput(session, "word", value = predicted)
}
else {
return()
}
})
observe({
nextword <- toString(predict(input$word,all.gram,4))
updateTextInput(session, "predictedword", value = nextword)
})
})
The infinite loop can be fixed by adding the function in bold:
if (input$accept > 0) {
This is almost always the pattern you want to follow when using
actionButton. In fact we have some features coming up in Shiny that will
wrap this pattern up for you so it's more natural to follow.
See http://shiny.rstudio.com/articles/isolation.html for more details.
On Thu, Nov 20, 2014 at 11:27 AM, Shanthi [email protected] wrote:
I am trying to do something similar and have multiple issues:
- I accept a phrase, I process the phrase and predict a word, I add the
predicted word back into the input. But this causes an infinite loop. Is
there a way to fix this?- Then I created a textbox for the predicted word and then added a button
"Accept". If user presses Accept, the word gets appended to the existing
phrase. However, I cannot get this to work.ui.R:
textInput("word", "Phrase", value=""),
textInput("predictedword", "Next Word:", value=""),
actionButton("accept", "Accept")server.R
shinyServer(
function(input, output, session) {
observe ({
if (input$accept > 0) {
predicted <- paste(input$word, input$nextword)
updateTextInput(session, "word", value = predicted)
}
else {
return()
}
})observe({
nextword <- toString(predict(input$word,all.gram,4))
updateTextInput(session, "predictedword", value = nextword)
})})
—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63864397.
Cool, that worked very well. Thanks for your quick response.
Is it possible to put the cursor at the end of the text in the above scenario? Basically, when the user clicks "Accept", I add the text to the input text but I want to place the cursor at the end.
This has to be done with JS. Try including this in your UI.
tags$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var input = $('#word');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
"))
Right after calling updateTextInput(session, "word", ...), you should add:
session$sendCustomMessage("cursorEnd", NULL)
On Thu, Nov 20, 2014 at 12:55 PM, Shanthi [email protected] wrote:
Is it possible to put the cursor at the end of the text in the above
scenario? Basically, when the user clicks "Accept", I add the text to the
input text but I want to place the cursor at the end.—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63878009.
Joe - this does not do anything. My ui.R and server.R are below:
library(shiny)
library(stringi)
library(data.table)
shinyUI(fluidPage(
titlePanel("TextPredictor"),
fluidRow(
column(6, wellPanel(
textInput("word", "Phrase", value=""),
tags$style(type='text/css', "#word { width: 300px; }"),
tags$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var input = $('#word');
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
actionButton("clear", "Clear"),
textInput("predictedword", "Next Word:", value=""),
actionButton("accept", "Accept")
))
)))
server.R
shinyServer(
function(input, output, session) {
observe ({
if (input$accept > 0) {
isolate({
phrase <- clean(input$word)
predicted <- paste(phrase, input$predictedword)
updateTextInput(session, "word", value = predicted)
session$sendCustomMessage("cursorEnd", NULL)
})
}
})
observe ({
if (input$clear > 0) {
isolate({
updateTextInput(session, "word", value = "")
})
}
})
observe({
phrase <- clean(input$word)
nextword <- toString(predict(phrase,all.gram,4))
updateTextInput(session, "predictedword", value = nextword)
})
})
Sorry, two mistakes:
Shiny.addCustomMessageHandler('cursorEnd', function() {
should be
Shiny.addCustomMessageHandler('cursorEnd', function(_message_) {
and
session$sendCustomMessage("cursorEnd", NULL)
should be
session$sendCustomMessage("cursorEnd", TRUE)
On Thu, Nov 20, 2014 at 2:50 PM, Shanthi [email protected] wrote:
Joe - this does not do anything. My ui.R and server.R are below:
library(shiny)
library(stringi)
library(data.table)shinyUI(fluidPage(
titlePanel("TextPredictor"),
fluidRow(
column(6, wellPanel(textInput("word", "Phrase", value=""),
tags$style(type='text/css', "#word { width: 300px; }"),
tags$script(HTML("
Shiny.addCustomMessageHandler('cursorEnd', function() {
var input = $('#word');
alert(input)
input[0].selectionStart = input[0].selectionEnd = input.val().length;
});
")) ,
actionButton("clear", "Clear"),
textInput("predictedword", "Next Word:", value=""),
actionButton("accept", "Accept")
))
)))server.R
shinyServer(
function(input, output, session) {
observe ({
if (input$accept > 0) {
isolate({
phrase <- clean(input$word)
predicted <- paste(phrase, input$predictedword)
updateTextInput(session, "word", value = predicted)
session$sendCustomMessage("cursorEnd", NULL)
})
}
})observe ({
if (input$clear > 0) {
isolate({
updateTextInput(session, "word", value = "")
})
}
})observe({
phrase <- clean(input$word)
nextword <- toString(predict(phrase,all.gram,4))
updateTextInput(session, "predictedword", value = nextword)
})})
—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-63894797.
Pretty neat solution, thanks once again. I did not even know these methods exist in Shiny.
I have a new problem. I am able to append the text and set the cursor, however, the cursor is not visible. I always see the first part of the text and the text does not scroll to the right.
I converted text into text area, and see the same issue. How can I bring in focus to the end of the text area? Thanks
I feel as though a simple case has been overlooked (and forgive me if I somehow missed this example in the above thread). It is very common to have a set of checkboxes with one button to check all, and another to uncheck all. For example, the desired code from server.R below. While I can conceive of a few ways to get around this, it doesn't mean that you should not be able to reset to 0. The reason the code below does not work is that after selecting and deselecting once, both input action button values are greater than 0. I am not deriving anything meaningful from the increment counter other than "the special value of 0" as stated above. Thoughts on this example?
observe({
if (input$uncheckAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = NULL)
}
if (input$checkAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = c(1,2,3))
}
})
These just need to be two separate observers.
observe({
if (input$uncheckAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = NULL)
}
})
observe({
if (input$checkAll > 0 ) {
updateCheckboxGroupInput(session = session, inputId = "test", choices = c(1,2,3), selected = c(1,2,3))
}
})
Actually with recent versions of Shiny it's nicer to use observeEvent, and also you don't need to provide the choices if they're not changing:
observeEvent(input$uncheckAll, {
updateCheckboxGroupInput(session, "test", selected = NULL)
})
observeEvent(input$checkAll, {
updateCheckboxGroupInput(session, "test", selected = c(1,2,3))
})
Thanks much, this actually makes sense and I stand corrected. I still don't quite understand the resistance to not being able to reset to zero - it doesn't seem to inherently promote any bad coding practices, and just because something can be done one way doesn't mean there may not be a better or more intuitive way. Anyhow, you have come up with elegant solutions for most of the problems here, so for now this will definitely suffice. Also, thank you for the advice about observeEvent(). I wasn't even aware of this new construct (I'm relatively new to shiny, and few of the examples in the gallery seem to use some of the newer functionality I am coming across).
I still don't quite understand the resistance to not being able to reset to zero - it doesn't seem to inherently promote any bad coding practices
It absolutely, positively does promote bad coding practices. Just look at all of the code examples in this thread (through no fault of the users, of course--we just haven't done a good enough job with education). The action button being clicked should be thought of as a discrete event, not a value. The special 0
value is just a workaround to prevent the code from thinking that the button is clicked at startup. It's _the fact that a number has changed_ that is the relevant signal here, not _the value that the number happens to be_.
Shiny's reactivity system wasn't designed for imperative programming--and pushing a button is, by nature, imperative. It was a stroke of pure luck that I came up with the observe/isolate idiom that allows actionButtons to work so nicely. It is a very narrow pattern that has very broad applications; if you stay within the pattern you can accomplish almost anything safely. If you stray outside the pattern your program is suddenly very difficult to reason about AND probably also doesn't accomplish what you originally wanted it to.
I think part of the reason is that the observe/isolate examples don't LOOK like anything particularly special relative to other reactive code. I'm hoping that observeEvent will help make the intent clearer, and make it less tempting to abuse.
I still disagree with this premise. There is a difference between promoting bad coding practices and people using code in the wrong way. Almost any code construct can be used inappropriately. I think the root of this disagreement may be the implementation of the counter for the actionButton, which I might argue is not intuitive based on many older examples I've found using observe. I will readily grant that that the interface for observeEvent is much cleaner and will naturally obfuscate the value associated with the actionButton. In any case, I do very much thank you for your help. If you want to continue the conversation about promotion of bad coding practices, feel free to email me as I don't want this thread to get too far off topic. Of course, if it relates to the examples and use cases, definitely post here. Thanks again.
quick side note. In my uncheckAll example, I used selected = NULL within updateCheckboxGroupInput. According to the documentation for this method, any arguments with a NULL value will be ignored. Hence, for those looking at this example, you must use selected = c('') or some such equivalent.
Hi, i think there is currently one problem with the approach: if you deleting and adding the button with the same ID again, the input$ID
might still exist and therefore is not null anymore, therefore the function gets executed immediately when added, I worked around that issue by extending the observeEvent function the following way (in a nutshell: I get the old value first and then compare with the new event):
observeEvent2 <- function (eventExpr, handlerExpr, event.env = parent.frame(),
event.quoted = FALSE, handler.env = parent.frame(), handler.quoted = FALSE,
label = NULL, suspended = FALSE, priority = 0, domain = getDefaultReactiveDomain(),
autoDestroy = TRUE, ignoreNULL = TRUE)
{
eventFunc <- exprToFunction(eventExpr, event.env, event.quoted)
if (is.null(label))
label <- sprintf("observeEvent(%s)", paste(deparse(body(eventFunc)),
collapse = "\n"))
handlerFunc <- exprToFunction(handlerExpr, handler.env,
handler.quoted)
oldValue <- isolate(eventFunc())
invisible(observe({
e <- eventFunc()
if (ignoreNULL && (isNullEvent(e) || (!is.null(oldValue) && e == oldValue))) {
return()
}
isolate(handlerFunc())
}, label = label, suspended = suspended, priority = priority,
domain = domain, autoDestroy = TRUE))
}
It's still not perfect but works much better.
I, too, find myself wanting to reset an action button. I don't find the following functionality in the thread so far, so I'll try it out for Joe...
It has to do with using a conditional panel that looks at an action button value for its condition (this is in ui.R, _not_ server.R).
In a sidePanel I have something like:
sidePanel(
...
actionButton(doit,"Configure this variable")
...
)
then in a main panel I have something like
mainPanel(
...
# for action button not pushed:
conditionalPanel(condition="input.doit == 0 & input.tabs==...",
...),
...
# for action button pushed:
conditionalPanel(condition="input.doit > 0 & input.tabs==...",
...),
Now, at some point (maybe triggered by another action button, I would like to reset input.doit and re-display the first conditional panel, have the user re-specify inputs there, etc. Seems like it would be quite natural to have something like updateActionButton()
over in server.R to get me back to my first conditional panel.
I would be very happy to hear the 'right and proper' way to do this, given that updateActionButton()
does not exist.
To get a 0 / 1 actionbutton without resetting:
attr(input, "readonly") <- FALSE
input$ActionButtonMemory <- 0
observe({
if(length(input$ActionButton)>0){
if((input$ActionButton-input$ActionButtonMemory)>0){
input$ActionButtonMemory<- input$ActionButton # Equalize
# DO YOUR THING HERE
}}
})
I stumbled upon this issue, while looking for a way to write a single handler that can respond to a large number of individual (dynamically changing) action buttons. Here's an example of what I was trying to do:
save_settings <- function()
{
xs <- seq(1,100,by=1)
result<-lapply(xs,function(x){
observeEvent(input[[paste0(x,"_save")]], {
if(!(input[[paste0(x,"_save")]]==0)){
# Save something for this value of x.
#input[[paste0(x,"_save")]] <- 0 # Could be a nice place to be able to reset to 0.
}
}
}
message(paste0(x,"_save: ",input[[paste0(x,"_save")]]))
})
input[[paste0(x,"_save")]]
})
return(result)
}
})
I could see the 'reset' to zero being useful in this case, but perhaps there's a better way of doing this.
Has anyone done something similar?
@mikebirdgeneau That's absolutely not necessary in this case. This is all you need to do:
save_settings <- function() {
xs <- seq(1,100,by=1)
lapply(xs,function(x){
observeEvent(input[[paste0(x,"_save")]], {
# Save something for this value of x.
})
})
}
@jcheng5 thanks - I'll give that a go! Appreciate the quick response. Cheers.
I can see one argument for resetting an actionButton that I haven't seen mentioned here (apologies if it has been mentioned, and I missed it). I'd like to be able to copy the URL from the browser in which my shiny app is running, send it to somebody else, and have them be able to load the same page with all of the inputs automatically populated from the URL. I do not, however, want the actions executed by an actionButton to run automatically. (One example of this might be a page used to visualize data, with an actionButton that will trigger the writing of that data to a particular file. I want to be able to send a visualization of that data to somebody by sending them the URL to my page, but they may not want to write it to file upon page load).
By default shiny can save/load all of its input variables to/from the URL, which is great most of the time, but can cause issues when it loads actionButtons with values > 0. In those cases, as in the example above, it will think that the user has clicked the actionButton when in reality he/she has not yet done so.
This is a case in which the value of the actionButton does not matter, but the fact that it is not zero is important. Thanks for your help!
By default shiny can save/load all of its input variables to/from the URL
That's not a built-in feature of Shiny; is there a specific package you're using to give you that functionality?
You're right - this is part of a separate package (that is not yet publicly available). Thank you for the quick response.
@nhpackard does shinyjs
help you accomplish what you need? Here's a minimal example of toggle
:
library(shiny);library(shinyjs)
shinyApp(
ui = fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("showPanel","Show Panel!")
),
mainPanel(
useShinyjs(),
absolutePanel(id = "panel", class = "panel panel-default",
style = "z-index:100; display: none;",
div(style="margin:10px;",
h3("Hello World")
)
)
)
)
),
server = function(input, output) {
observeEvent(input$showPanel,{
toggle("panel")
})
}
)
It's not using conditionalPanel
but I think it's cleaner to keep the logic on the server-side. Upon a button press you could have it updateX
for each of the inputs, and run the analysis, etc.
Hi Joe,
I stuck around the similar problem related to the resetting of action button. My problem is
On UI : I have 1 drag down which contains 2 values "Suntrust Bank" and "Huntington Bank". And below which i have 3 action buttons for 3 task : process data, download processed data and upload processed data.
When i select Suntrust first time, below three action buttons are not executed unless i pressed them. However, whenever i select Huntington, below 3 buttons executed automatically (buttons were not pressed) .
Could you please help me out how to resolve this ? Ideally i would like to have : when i change SunTrust to Huntington or and again Huntington to SunTrust, the below 3 buttons (process, download and upload) should not work unless and until i press them.
Thanks in advance !!
Like this:
observeEvent(input$process, {
# processing code here
})
observeEvent(input$download, {
# download code here
})
observeEvent(input$upload, {
# upload code here
})
On Tue, Jan 26, 2016 at 10:18 AM abhijeetgosavi [email protected]
wrote:
Hi Joe,
I stuck around the similar problem related to the resetting of action
button. My problem isOn UI : I have 1 drag down which contains 2 values "Suntrust Bank" and
"Huntington Bank". And below which i have 3 action buttons for 3 task :
process data, download processed data and upload processed data.When i select Suntrust first time, below three action buttons are not
executed unless i pressed them. However, whenever i select Huntington,
below 3 buttons executed automatically (buttons were not pressed) .Could you please help me out how to resolve this ? Ideally i would like to
have : when i change SunTrust to Huntington or and again Huntington to
SunTrust, the below 3 buttons (process, download and upload) should not
work unless and until i press them.Thanks in advance !!
—
Reply to this email directly or view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-175154688.
Yes, exactly. Let me paste my server.r code here
Server.r
library(data.table)
library(shiny)
library(stats)
shinyServer(function(input, output, session) {
datasetInput <- reactive({
switch(input$Select,
"SunHE" = heloc.comp.rate,
"HunHE" = heloc.comp.rate1
)
})
observeEvent(input$goButton, {
output$MyData <- renderDataTable({
datasetInput()
})
})
observeEvent(input$Click, {
output$fill <- renderUI({
write.csv(datasetInput(), file.loc,row.names=FALSE)
})
})
observeEvent(input$Submit, {
output$fill <- renderUI({
write.csv(datasetInput(), Up.file.loc,row.names=FALSE)
})
})
})
ui.r
shinyUI(fluidPage(
titlePanel("Generate Competitor rate GI file"),
sidebarLayout(
sidebarPanel(
selectInput("Select","Select Customer:",
list(SunHE = "SunHE", HunHE = "HunHE")
) ,
actionButton("goButton", "Generate GI File") ,
actionButton("Click", "Download GI File") ,
actionButton("Submit", "Upload GI File"),
uiOutput("fill") ,
uiOutput("Upload")
)
,
mainPanel(
h3(textOutput("caption")),
dataTableOutput("MyData")
)
)
))
When i'm changing bank from Suntrust to Huntington from Drag n Down, below 3 actions buttons are executing automatically.
Can we take the discussion over to shiny-discuss? Thanks.
I have created new discussion - Resetting action buttons. Kindly have a look and let me know if you have any inputs.
Thanks.
was this ever resolved or did they just keep insisting that nobody needed it? I need it! :)
I was wondering if there was a resolution to this as well. I need the actionButton reset because I have a conditionalPanel that depends on whether the button is clicked, but it has to be reset whenever the user switches options in my dropdown menu.
I think you can use this code to determine if it's odd or even
x %% 2 == 0
does that work?
On Thu, Mar 8, 2018 at 9:06 AM, Liquan Yang notifications@github.com
wrote:
I was wondering if there was a resolution to this as well. I need the
actionButton reset because I have a conditionalPanel that depends on
whether the button is clicked, but it has to be reset whenever the user
switches options in my dropdown menu.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/rstudio/shiny/issues/167#issuecomment-371495934, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AK1uahF09NieR3_qn660YI8QVNfYtuz0ks5tcTrIgaJpZM4At9WK
.
In general what you need is reactiveValue
that is tied to the button. Every the the button is clicked it adds one to the value, and that value is used to trigger observers etc. Then, when the user does the stuff that resets things, just reset the reactiveValue
to 0, the value tied to the button can stay as it is.
I ended up using shinyjs to create a hidden checkboxInput that would be toggled by several observers. Then, in my UI, I set up a conditionalPanel to check for the T/F value from the checkboxInput, and display the button if TRUE.
https://groups.google.com/forum/#!topic/shiny-discuss/9gJR5aCBNfE
I am experiencing a similar problem when using multiple embedded observeEvents, where a reset of the actionButton value would be useful.
observeEvent(input$button1, {
#a modal with button2 pops up, but should not trigger button2 until clicked
actionButton("button2", "Button 2")
observeEvent(input$button2, {
#modal number 2 pops up
#some action
removeModal()
})
})
This structure works perfectly in the first instance. However, when triggering button1 for the second time, it skips straight to observeEvent button2, without input$button2 having been provided.
A bit more investigating with browser() showed that input$button2 retains its value despite closing the modal and triggering input$button1 again, UNLESS a modalButton is used to dismiss the modal instead of removeModal().
A hard reset of the button in this case would be useful in conjunction with removeModal(), to prevent the app user from having to click a "Dismiss"-style modalButton every time.
Previously I have used updateRadioButtons to reset inputs for a selection menu, but this doesn't work the same with actionButtons.
I haven't found a suitable solution above, but I very much hope to be corrected by someone!
Thanks a lot.
that's an obviously useful feature - is there any piece of reasoning why this is not fixed???
I am experiencing a similar problem when using multiple embedded observeEvents, where a reset of the actionButton value would be useful.
For example:
observeEvent(input$button1, { #a modal with button2 pops up, but should not trigger button2 until clicked actionButton("button2", "Button 2") observeEvent(input$button2, { #modal number 2 pops up #some action removeModal() }) })
This structure works perfectly in the first instance. However, when triggering button1 for the second time, it skips straight to observeEvent button2, without input$button2 having been provided.
A bit more investigating with browser() showed that input$button2 retains its value despite closing the modal and triggering input$button1 again, UNLESS a modalButton is used to dismiss the modal instead of removeModal().
A hard reset of the button in this case would be useful in conjunction with removeModal(), to prevent the app user from having to click a "Dismiss"-style modalButton every time.
Previously I have used updateRadioButtons to reset inputs for a selection menu, but this doesn't work the same with actionButtons.
I haven't found a suitable solution above, but I very much hope to be corrected by someone!
Thanks a lot.
I'm having the same issue which is really annoying when having two modals back-to-back where the first one shows missing data for a selection. Could not find suitable workaround either
I'm having the same issue which is really annoying when having two modals back-to-back where the first one shows missing data for a selection. Could not find suitable workaround either
Ok. For future reference to people having the same problem as me. The easy solution for me was to include shinyjs::onclick()
instead of observeEvent. Then it works every time. A short snippet of my code:
`
observeEvent(input$change, {
showModal(modalDialog(title = "some_title",
renderTable({#my data}),
easyClose = FALSE,
footer = tagList(actionButton("ok", "Ok"), shinyjs::useShinyjs())))
shinyjs::onclick("ok", {
removeModal()
# My other modal is in a module. Should work outside as well
callModule(pop_up, "dato", dato_tabell = reactive({pop_up_data()}))
})
}
)
`
Sorry for terrible formatting. Hope this helps somebody
@TjebsC For future reference, you can work around this by giving observeEvent(input$button2, ...)
an additional argument ignoreInit=TRUE
. What this tells observeEvent
is, "no matter what the current value of input$button2
is, don't execute this observer until the NEXT time input$button2
is updated". Not very intuitive, but I think it should work.
Oh, ha, this exact scenario is laid out in ?observeEvent
(though I don't blame you for not coming across it):
For example, if you're setting up an
observeEvent
for a dynamically created button, thenignoreInit = TRUE
will guarantee that the action (inhandlerExpr
) will only be triggered when the button is actually clicked, instead of also being triggered when it is created/initialized.
ok, I am a same problem.
#SAVE
observeEvent(input$Guardar,{
req(input$Guardar)
input$Guardar
isolate({
archivo <- paste0("D:/",
input$Fundo, "-", input$Parcela, " ",
input$Lote, " ", input$Lado,".pdf")
pdf(archivo, width = 18, height = 11 )
Graph
dev.off()
shinyalert(title = "Descarga Correcta", type = "success")
})
I have this code inside an observeEvent to save every time I make changes to a map, the problem is that as soon as a parameter change is saved, I mean when I click on the save button, and it doesn't stop working; I would like it to only save when I click.
I need help, please.
Most helpful comment
was this ever resolved or did they just keep insisting that nobody needed it? I need it! :)