I have a form with two different actions. The first one is to upload a file and the second is for an example. When I click one of these my app does something, but the server saves the information of a click and no change until I click on the other button.
For example, if I click the upload button without choose a file, it does nothing, but if I choose a file, the server uploads the file and start to process it without clicking on the upload button because the server has saved the past click. I want to know if is possible to reset the value for each click.
Index.html
<form class="span12 menu-med-upload">
<div class="row-fluid">
<h3>Upload File .fasta</h3>
<div class="custom-input-file btn btn-inverse">
<input type="file" size="1" name="fileFasta" id="fileFasta" class="input-file" />
Select File
</div>
<img src="/static/img/check.png" class = "custom-input-check">
<div class="span12"></div>
<textarea class = "span12" rows = "10" style="resize: none;" id="textAreaFasta">
</textarea>
</div>
<button id="uploadFasta" type="button" class="btn btn-inverse action-button" >Upload File</button>
<button id="exampleFasta" type="button" class="btn btn-inverse action-button" >Example</button>
</form>
Server.R
shinyServer(function(input, output, session) {
# Create a reactiveValues object, to let us use settable reactive values
values <- reactiveValues()
# To start out, lastAction == NULL, meaning nothing clicked yet
values$lastAction <- NULL
# An observe block for each button, to record that the action happened
observe({
if (input$exampleFasta != 0) {
values$lastAction <- 'example'
}
})
observe({
if (input$uploadFasta != 0) {
values$lastAction <- 'upload'
})
})
# Then you can use values$lastAction in reactive expressions, outputs, etc.
output$table <- renderText({
if (is.null(values$lastAction))
return(NULL)
if (identical(values$lastAction, 'upload'))
return(myRenderTable(matrixProtein(), "table", nameFile))
if (identical(values$lastAction, 'example'))
return(myRenderTable(matrixProteinExample(), "table", ""))
stop("Unexpected value for lastAction: ", values$lastAction)
})
})
Note: Joe Cheng made the code of server.R, and I copied to work in this example to shiny Change data input of buttons
This question was made more difficult to answer without a reproducible example. However, I've put together a self-contained example and fixed it so that it works. There were two problems with the code as it stood. The first, as identified by @xiaodai (but without adequate explanation) was that the file upload element wasn't isolated from the reactive context. This meant that any time the file element was changed, the output changed also. The second issue was that the code for each button was only being called once when clicking on it multiple times in a row, which meant that uploads didn't happen (after fixing the isolate issue) if you'd failed to click on the Example button first.
Now it works as I believe the OP wanted.
Here's the fixed index.html:
<html>
<head>
<script src="shared/jquery.js" type="text/javascript"></script>
<script src="shared/shiny.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="shared/shiny.css"/>
</head>
<body>
<form class="span12 menu-med-upload">
<div class="row-fluid">
<h3>Upload File .fasta</h3>
<div class="custom-input-file btn btn-inverse">
<input type="file" size="1" name="fileFasta" id="fileFasta" class="input-file" />
Select File
</div>
</div>
<button id="uploadFasta" type="button" class="btn btn-inverse action-button" >Upload File</button>
<button id="exampleFasta" type="button" class="btn btn-inverse action-button" >Example</button>
</form>
<div id="table" class="shiny-html-output"></div>
</body>
</html>
And here's the fixed server.R:
library("xtable")
library("Biostrings")
myRenderTable <- function(data, dataType, nameFile) {
print(xtable(data), type = "html", print.results = FALSE)
}
matrixProtein <- function(fastaFile) {
fasta <- readDNAStringSet(fastaFile)
alphabetFrequency(translate(fasta))
}
matrixProteinExample <- function() {
matrixProtein(system.file("extdata", "someORF.fa", package="Biostrings"))
}
shinyServer(function(input, output, session) {
# Create a reactiveValues object, to let us use settable reactive values
values <- reactiveValues()
# To start out, lastAction == NULL, meaning nothing clicked yet
values$lastAction <- NULL
# An observe block for each button, to record that the action happened
# Note setting the lastAction to NULL and then to a string ensures the output
# is generated each time the button is clicked which is necessary for the upload button
observeEvent(input$exampleFasta, {
values$lastAction <- "example"
})
observeEvent(input$uploadFasta, {
values$lastAction <- NULL
values$lastAction <- "upload"
})
nameFile <- "Random"
# Then you can use values$lastAction in reactive expressions, outputs, etc.
output$table <- renderText({
if (is.null(values$lastAction))
return(NULL)
if (identical(values$lastAction, 'upload')) {
if (!is.null(isolate(input$fileFasta))) {
return(myRenderTable(isolate(matrixProtein(input$fileFasta$datapath)), "table", nameFile))
} else {
stop("No file provided")
}
} else if (identical(values$lastAction, 'example'))
return(myRenderTable(matrixProteinExample(), "table", ""))
stop("Unexpected value for lastAction: ", values$lastAction)
})
})
Note that this depends on the Bioconductor package Biostrings and the CRAN package xtable. I've no idea what the original functions did, but this code takes a FASTA formatted file, reads in the sequences, translates to a protein sequence and then gives a table of alphabet frequency.
Also note I've no idea what the other parameters to myRenderTable meant, so I've ignored them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With