Shiny: Render Outputs when hidden - r

I am trying to render a few outputs in a shiny application that are contained within a shinyjs::hidden section upon the application running rather than once the section is visible.
EDIT: I had the app set up incorrectly in the original example so have changed it.
I want to be able to run the reactive statement before running the final observe to change the UI from the Alpha text to the Beta text and plot. Ideally this would mean in the console would see "Done plotting" before "Observe run".
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
div(id = "before-content", h3("Aux Text Alpha")),
shinyjs::hidden(
div(
id = "after-content",
h1("Aux Text Beta"),
plotOutput("text")
)
)
)
server <- function( session,input, output) {
in_plot <- reactive({
Sys.sleep(3)
print("Done plotting")
plot(iris)
})
output$text <- renderPlot({
in_plot()
})
observe({
print("Observe run")
hide("before-content")
show("after-content")
})
}
shinyApp(ui, server)
An alternative would be to have a layer over what is classed as the hidden section but am not too sure on how that is accomplished.

You can hide it in the reactive, like so:
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("button", "Click me"),
plotOutput("text")
)
server <- function( session,input, output) {
in_plot <- reactive({
hide("text")
Sys.sleep(3)
print("Done plotting")
plot(iris)
})
output$text <- renderPlot({
in_plot()
})
observeEvent(input$button, {
show("text")
})
}
shinyApp(ui, server)

Related

Change the title by pressing a shiny button Shiny R

library(shiny)
ui <- fluidPage(
h1("Free",align = "center"),
actionButton("go", "Go")
)
server <- function(input, output) {
observeEvent(input$go,{
#change the h1 title for
code("Busy",align="center")
}
}
shinyApp(ui, server)
How to change the title when pressing a button? the idea is to change the word free to busy when the button is pressed.
Would make the h1 header using uiOutput in the ui. Then, you can dynamically change this text to whatever you want in server. Perhaps for your example, you can have a reactiveVal that contains the text you want in the header, which can be modified in your case when the actionButton is pressed.
library(shiny)
ui <- fluidPage(
uiOutput("text_header"),
actionButton("go", "Go")
)
server <- function(input, output) {
rv <- reactiveVal("Free")
observeEvent(input$go, {
rv("Busy")
})
output$text_header <- renderUI({
h1(rv(), align = "center")
})
}
shinyApp(ui, server)

Show box only when tableoutput is ready in shiny app

I want to generate a boxPlus around my DT-Output. Now when I start my APP, the frame of the box is already there. How do I manage that the box is only displayed when the tableoutput is finished? As input I use a text input.
In my UI I use for the Input:
textInput("name", "Insert Number:")
the final box I create with:
uiOutput("box")
On Serverside I do:
output$name <- renderText(input$name)
New_input <- reactive({
list(input$name)
})
and the box I create like this:
output$box <- renderUI({
boxPlus(
div(style = 'overflow-x: scroll;'), dataTableOutput("table")
)
})
I tried it with: Similar Problem but I can not resolve the problem. Without the box everything works fine.
Never use reactive expressions inside a renderText function.
You have to wrap tagList around your two elements to return a SINGLE element (a list in your case).
Here is a reproduceable example.
library(shiny)
library(shinydashboardPlus)
library(dplyr)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Hide box"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
textInput("name", "Insert Number to filter cyl:")
),
mainPanel(
uiOutput("box")
)
)
)
server <- function(input, output) {
resultdf <- reactive({
mtcars %>%
filter(cyl > input$name)
})
output$box <- renderUI({
output$table <- renderDataTable({
resultdf()
})
if(input$name == "") {
return(NULL)
} else {
return(
tagList(
boxPlus(
div(style = 'overflow-x: scroll;'), dataTableOutput("table")
)
)
)
}
})
}
# Run the application
shinyApp(ui = ui, server = server)

observeEvent Shiny function used in a module does not work

I'm developing an app in which I use modules to display different tab's ui content. However it seems like the module does not communicate with the main (or parent) app. It displays the proper ui but is not able to execute the observeEvent function when an actionButton is clicked, it should update the current tab and display the second one.
In my code I have created a namespace function and wrapped the actionButton's id in ns(), however it still does not work. Does anyone knows what's wrong?
library(shiny)
moduleUI <- function(id){
ns <- NS(id)
sidebarPanel(
actionButton(ns("action1"), label = "click")
)
}
module <- function(input, output, session){
observeEvent(input$action1, {
updateTabItems(session, "tabsPanel", "two")
})
}
ui <- fluidPage(
navlistPanel(id = "tabsPanel",
tabPanel("one",moduleUI("first")),
tabPanel("two",moduleUI("second"))
))
server <- function(input, output, session){
callModule(module,"first")
callModule(module,"second")
}
shinyApp(ui = ui, server = server)
The observeEvent works, but since modules only see and know the variables given to them as input parameters, it does not know the tabsetPanel specified and thus cannot update it. This problem can be solved using a reactive Value, which is passed as parameter and which is changed inside the module. Once it's changed, it is known to the main app and can update the tabsetPanel:
library(shiny)
library(shinydashboard)
moduleUI <- function(id){
ns <- NS(id)
sidebarPanel(
actionButton(ns("action1"), label = "click")
)
}
module <- function(input, output, session, tabsPanel, openTab){
observeEvent(input$action1, {
if(tabsPanel() == "one"){ # input$tabsPanel == "one"
openTab("two")
}else{ # input$tabsPanel == "two"
openTab("one")
}
})
return(openTab)
}
ui <- fluidPage(
h2("Currently open Tab:"),
verbatimTextOutput("opentab"),
navlistPanel(id = "tabsPanel",
tabPanel("one", moduleUI("first")),
tabPanel("two", moduleUI("second"))
))
server <- function(input, output, session){
openTab <- reactiveVal()
observe({ openTab(input$tabsPanel) }) # always write the currently open tab into openTab()
# print the currently open tab
output$opentab <- renderPrint({
openTab()
})
openTab <- callModule(module,"first", reactive({ input$tabsPanel }), openTab)
openTab <- callModule(module,"second", reactive({ input$tabsPanel }), openTab)
observeEvent(openTab(), {
updateTabItems(session, "tabsPanel", openTab())
})
}
shinyApp(ui = ui, server = server)

Reset ratingInput in shiny app

I want to use a rating Input in conjunction with the shinyjs::reset()function. Everthing works fine except the reset functionality. Any hints?
Here is my minimal example:
library(shiny)
devtools::install_github("stefanwilhelm/ShinyRatingInput")
library(ShinyRatingInput)
library(shinyjs)
ui <- shinyUI(bootstrapPage(
useShinyjs(),
ratingInput("movieRating", label="Rate this movie...", dataStop=5),
htmlOutput("movieRatingout"),
actionButton("resetbtn", "reset")
))
#the corresponding server.R
server <- shinyServer(function(input, output, session) {
output$movieRatingout <- renderText({
paste("The movie was rated ",input$movieRating)
})
observeEvent(input$resetbtn, {
reset("movieRating")
})
})
shinyApp(ui, server)
You can create reset action manualy
1) Add js to reset icons ( set width of foreground ==0)
jsCode <-"shinyjs.reset_1 = function(params){$('.rating-symbol-foreground').css('width', params);}"
2) add this js to app using extendShinyjs
3) add session$sendInputMessage to reset input ( set value == NULL)
Working example
jsCode <-"shinyjs.reset_1 = function(params){$('.rating-symbol-foreground').css('width', params);}"
ui <- shinyUI(bootstrapPage(
useShinyjs(),
extendShinyjs(text = jsCode),
ratingInput("movieRating", label="Rate this movie...", dataStop=5),
htmlOutput("movieRatingout"),
actionButton("resetbtn", "reset")
))
#the corresponding server.R
server <- shinyServer(function(input, output, session) {
output$movieRatingout <- renderText({
paste("The movie was rated ",input$movieRating)
})
observeEvent(input$resetbtn, {
session$sendInputMessage("movieRating", list(value = NULL))
js$reset_1(0)
})
})

Shiny: add button label to sidebar & update buttons after click

I'm a bit rusty to Shiny reactivity, but I want to do two things when a button is clicked:
add that button label to the sidebar (and add more labels to sidebar after more clicks)
update the button labels (i.e. more random integers)
I'm nervous about changing the label before recording it, so I want to get the timing right. Here's a skeleton of what I'm working with:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textOutput("clicks")
),
mainPanel(
uiOutput("button1"),
uiOutput("button2")
))
)
###################
server <- function(input, output, session) {
output$clicks <- renderText({
paste()
})
## reactive values
inside <- reactive({
inside <- sample(1:100,2)
})
## buttons
output$button1 <- renderUI({
actionButton("course1", label = inside()[1], style='padding:50px')
})
output$button2 <- renderUI({
actionButton("course2", label = inside()[2], style='padding:50px')
})
}
shinyApp(ui = ui, server = server)
Right now the sidebar is blank because I'm not sure how to add it, or what to add to make the button labels update after a click (whether to do it inside a reactive value or an observeEvent). Any help is much appreciated!
Here's a way to do it with reactiveValues:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
textOutput("clicks")
),
mainPanel(
uiOutput("button1"),
uiOutput("button2")
))
)
###################
server <- function(input, output, session) {
# Show history
output$clicks <- renderText({
history[['clicked']]
})
## reactive values
# store history as reactive values
history <- reactiveValues(clicked = c())
# update history when a button is clicked
observeEvent(input$course1,{
history[['clicked']] <- c(history[['clicked']],inside()[1])
})
observeEvent(input$course2,{
history[['clicked']] <- c(history[['clicked']],inside()[2])
})
#update inside when history updates
inside <- reactive({
history[['clicked']]
inside <- sample(1:100,2)
})
## buttons
output$button1 <- renderUI({
actionButton("course1", label = inside()[1], style='padding:50px')
})
output$button2 <- renderUI({
actionButton("course2", label = inside()[2], style='padding:50px')
})
}
shinyApp(ui = ui, server = server)

Resources