updateTabsetPanel now, without delay - r

In the following minimal example, note that while the file.choose() line is commented out, the code works as expected: clicking the OK button on the Input tab switches to the Results tab.
However, uncomment the file.choose() line and the updateTabsetPanel() function no longer works. Is there some way to get the tab to change on the screen before the file.choose() begins?
ui <- fluidPage(fluidRow(
tabsetPanel(id="main",
tabPanel("Input", actionButton("okButton", "OK")),
tabPanel("Results", h3(textOutput("results")))
)))
server <-function(input, output, session) {
output$results = renderText("Results Tab")
observeEvent(input$okButton, {
updateTabsetPanel(session, "main", "Results")
# file.choose()
})
}
shinyApp(ui = ui, server = server)

You can do it in two steps: 1. Switch the tab; 2. Based on the tab switching event, open the file choose window.
ui <- fluidPage(fluidRow(
tabsetPanel(id="main",
tabPanel("Input", actionButton("okButton", "OK")),
tabPanel("Results", h3(textOutput("results")))
)))
server <-function(input, output, session) {
output$results = renderText("Results Tab")
observeEvent(input$okButton, {
updateTabsetPanel(session, "main", "Results")
})
observeEvent(input$main, {
if (input$main == "Results") {
file.choose()
}
})
}
shinyApp(ui = ui, server = server)

Related

Action button in Shiny app updates query in url with input from user

I have this app:
library(shiny)
ui <- fluidPage(
textInput("query_text","Type something:"),
actionButton(inputId='query_button',
label="Search",
icon = icon("th"),
onclick = paste("location.href='http://www.example.com?lookfor=",
input$query_text, "'", sep=""))
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
I'd like to update the url with the action button, so when the user types something (for example: paper), it updates the url like this:
http://www.example.com/?lookfor=paper
Any ideias how to do it? Maybe wrapping it on a observeEvent?
Based on your replies to my comment, what you're looking for is the updateQueryString function.
library(shiny)
ui <- fluidPage(
textInput("query_text", "Type something:"),
actionButton(inputId = 'query_button', label = "Search")
)
server <- function(input, output, session) {
observeEvent(input$query_button, {
updateQueryString(paste0("?lookfor=", input$query_text))
})
}
shinyApp(ui, server)

Error when I try to close the shiny's app window while the app is running

I have this shiny app and its logic is very clear.Whenever i press the Hit button it prints 1000 hi.The problem is that if I go and close the app window while it is printing it crashes.How can i solve it?
ui <- fluidPage(
titlePanel("Data"),
sidebarLayout(
sidebarPanel(
actionButton("h","hit")
),
mainPanel()
)
)
server <- function(input, output) {
observeEvent(input$h,{
for(i in 1:1000){
print("hi")
)
})
}
shinyApp(ui = ui, server = server)
Does it do the trick for you?
tryCatch({shinyApp(ui = ui, server = server)})

Shiny reactive check if file is choose

Good morning. I want to check if file is choose or not in fileInput so I had to create reactive function but this not working.
ui.R
fileInput("file_input","Choose your file in csv")
mainPanel("main panel",textOutput("choose"))
server.R
library(shiny)
isFileChoose<-function(){reactive({
if(is.null(input$file_input))
return (FALSE)
else
return (TRUE)
}) }
server <- function(input, output) {
if(isFileChoose()==FALSE)
{
output$choose<-renderText("Not selected file")
}
}
I do not think you can just use a reactive in a function like that, see here. You could do this:
library(shiny)
ui <- fluidPage(
fileInput("file_input","Choose your file in csv"),
textOutput("choose")
)
server <- function(input, output) {
output$choose <- reactive({
if(is.null(input$file_input))
{
"No input given yet."
}
else
{
"Now we can process the data!"
}
})
}
shinyApp(ui = ui, server = server)
Hope this helps!

How to capture shinyalert input field as variable

I'm trying to use the relatively new shinyAlert package to see if it offers better results than the sweetalert package but I'm unable to figure out how to get this:
Myvar <- shinyalert input text
from this minimal example.
library(shiny)
library(shinyjs)
library(shinyalert)
ui <- fluidPage(
shinyjs::useShinyjs(),
useShinyalert(),
actionButton("run", "Run", class = "btn-success")
)
server <- function(input, output, session) {
shinyEnv <- environment()
observeEvent(input$run, {
shinyalert('hello', type='input')
})
}
shinyApp(ui = ui, server = server)
My thanks for any help from you geniouses out there.
Here is how you do it:
library(shiny)
library(shinyalert)
ui <- fluidPage(
useShinyalert(),
actionButton("run", "Run", class = "btn-success")
)
server <- function(input, output, session) {
observeEvent(input$run, {
shinyalert('hello', type='input', callbackR = mycallback)
})
mycallback <- function(value) {
cat(value)
}
}
shinyApp(ui = ui, server = server)
It's done using callbacks. You can assign the value to a reactive variable if you'd like.
I had fully documented the package last month and was about to release it, and then my computer crashed before I had a chance to push to github, and lost all progress. I haven't had a chance to work on it again. So sorry that the documentation isn't great yet, the package is still un-released so use at your own risk for now :)
(Notice that you don't need shinyjs for this)
I have no experience with the package shinyalert, but you can achieve what you want with the widely used and well documented modal dialogs from shiny. Maybe you there is a reason for you to stick with shinyalert that I am unaware off, but if not, example code for achieving what you want with modal dialogs:
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("run", "Run", class = "btn-success"),
textOutput("output1")
)
server <- function(input, output, session) {
dataModal <- function(failed = FALSE) {
modalDialog(
textInput("input1", "Enter text:",
placeholder = 'Enter text here'
)
)
}
# Show modal when button is clicked.
observeEvent(input$run, {
showModal(dataModal())
})
output$output1 <- renderText({
input$input1
})
}
shinyApp(ui = ui, server = server)
Let me know if this helps!

Getting file path from Shiny UI (Not just directory) using browse button without uploading the file

I need to deal with a huge file (>500mb) in R. So instead of loading such heavy file in R environment, I process the file in chunks of specific number of rows and finally get the aggregate values.
I need user to specify the file (using some kind of browse functionality) so that I can feed the file path to my algorithm
fileConnection <-file( "../output/name.txt", open="w")
Is there any way to get only file path from Shiny UI based on the address specified by user? I tried ShinyFiles package, but it gives only directory to choose, not file.
This functionality is available in the shinyFiles package. Have a look at this minimal example:
library(shiny)
library(shinyFiles)
ui <- fluidPage(
shinyFilesButton("Btn_GetFile", "Choose a file" ,
title = "Please select a file:", multiple = FALSE,
buttonType = "default", class = NULL),
textOutput("txt_file")
)
server <- function(input,output,session){
volumes = getVolumes()
observe({
shinyFileChoose(input, "Btn_GetFile", roots = volumes, session = session)
if(!is.null(input$Btn_GetFile)){
# browser()
file_selected<-parseFilePaths(volumes, input$Btn_GetFile)
output$txt_file <- renderText(as.character(file_selected$datapath))
}
})
}
shinyApp(ui = ui, server = server)
EDIT: This approach worked when running on RStudio desktop on Windows. But it fails on RStudio Server on Unix, as the file.choose dialog appears in the RStudio window instead of in the app.
Rather than uploading the file, we can instead just send a text string that is the file path to the app.
Consider the following minimal example:
library(shiny)
ui <- fluidPage(
actionButton("get", "Send file path"),
textOutput("txt")
)
server <- function(input,output,session){
val = reactiveVal()
observeEvent(input$get, {
val(file.choose())
})
output$txt <- renderText(val())
}
shinyApp(ui = ui, server = server)
The file.choose dialog returns the file path of a local file. This value is passed to the app where it is stored in a reactiveVal. The app can now display this text string.
Note that the file chosen is local to the browser, not the server. This means that in most cases your server will not be able to access the file.
Also, important to be clear to the user that they are providing a file path, not the file. Some users will not want to share the file path for privacy or security reasons.
Inspired by shinyFiles, I developed the following file-selection modal. This removes a package dependency, allows me to control the root folder users can access, and gives me control of the file-access source code. All of which will help when discussing the app with IT/security.
The file-access modal as a shiny module
## user interface
module_UI = function(id){
ns = NS(id)
tagList(
actionButton(ns("button_open"), "Select file")
)
}
## server
module_Server = function(id){
moduleServer(id, function(input, output, session){
ns = NS(id)
# path setup
root_path = "/set/this/path/so/users/will/only/have/access/to/subfolders"
current_path = reactiveVal()
current_path(root_path)
return_path = reactiveVal()
return_path(root_path)
# Selection modal
observeEvent(input$button_open, {
showModal(
modalDialog(
title = "Select a file",
p(strong("Current path: "), textOutput(ns("current_path"), inline = TRUE)),
fluidRow(
column(2, actionButton(ns("button_back"), "Back")),
column(4, selectInput(ns("dir"), label = NULL, choices = "Please select"))
),
footer = tagList(
modalButton("Cancel"),
actionButton(ns("ok"), "OK")
)
)
)
new_choices = c("Please select", dir(current_path()))
updateSelectInput(inputId = "dir", choices = new_choices)
})
# back button
observeEvent(input$button_back, {
if(current_path() != root_path){
current_path(dirname(current_path()))
new_choices = c("Please select", dir(current_path()))
updateSelectInput(inputId = "dir", choices = new_choices)
}
})
# OK button
observeEvent(input$ok, {
return_path(current_path())
removeModal()
})
# update directory
observeEvent(input$dir, {
if(input$dir != "Please select"){
current_path(file.path(current_path(), input$dir))
}
new_choices = c("Please select", dir(current_path()))
updateSelectInput(inputId = "dir", choices = new_choices)
})
# display directory
output$current_path = renderText({ current_path() })
return(reactive(return_path()))
})
}
A basic app for testing
testApp = function(...){
ui = fluidPage(
module_UI("id"),
textOutput("display")
)
server = function(input, output, session){
selected_path = module_Server("id")
output$display = renderText({ selected_path() })
}
shinyApp(ui, server, ...)
}
# run app
print(testApp())
Note that testing of the root_path is recommended, because some locations can be referred to in multiple ways. For example: dirname("~/Network-Shares/folder/subfolder") = "/home/ORG/username/Network-Shares/folder"

Resources