This seems like a very simple question, but I have searched and searched!
I am using selectize to select multiple items from a list in a selectInput dropdown menu. Below it I have a Submit button to perform some action on the list. As you add multiple entries, the selectInput box grows, and the button dynamically moves down the sidebar, but when you open the dropdown menu to see the list of options, the Submit button is hidden. I would like the button to dynamically jump down and stay visible when you open the dropdown, and conversely to jump back up when it closes.
I can't for the life of me...
I know how to change the default size of the dropdown with css
.selectize-dropdown-content { max-height: ... },
and I can add a spacer to keep the Submit button always visible, but that's wasted space once you're done selecting items.
sample code attached
library(shiny)
library(shinydashboard)
# long entries that will increase number of lines in the selectInput box
nonsenseWords <- c(replicate(25,paste0(sample(letters, 10, replace=TRUE),collapse="")))
ui <-
dashboardPage(
dashboardHeader(),
dashboardSidebar(
fluidRow(style = "margin: 1%",
selectInput("tall_list",
"Stop covering my buttons!",
nonsenseWords,
multiple = TRUE,
selected=nonsenseWords[c(1,5,7,11,20)]
)
# The line below puts static space between the dropdown and the submit button -- this is what I want to remove
# ,tags$div(style = "height: 16em;")
)
,fluidRow(style = "margin: 1%",
actionButton("submit", "Submit")
)
),
dashboardBody(
dataTableOutput("choice")
)
)
server <- function(input, output, session) {
output$choice <- renderDataTable({
req(input$submit)
return(data.frame("Chosen Words" = c(input$tall_list)))
})
}
shinyApp(ui, server)
Use this CSS:
dashboardBody(
tags$head(
tags$style(".selectize-dropdown {position: static}")
),
dataTableOutput("choice")
)
Related
I want to have scroll bar to scroll up and down, cross button to close the pop up window and default of 10 records should display instead of 25 now.
I don't know how to write code for this.
library(shiny)
library(shinydashboard)
library(shinyjs)
library(shinyBS)
data <- iris
ui <- tagList(
useShinyjs(),
dashboardPage(
dashboardHeader(title = "Telemedicine HP"),
dashboardSidebar(),
dashboardBody(
fluidRow(
div(id='clickdiv',
valueBox(60, subtitle = tags$p("Attended", style = "font-
size: 200%;"), icon = icon("trademark"), color = "purple", width = 4,
href
= NULL)
)
)
)
)
)
server <- function(input, output, session){
onclick('clickdiv', showModal(modalDialog(
title = "Your title",
renderDataTable(data)
)))
}
shinyApp(ui, server)
By clicking on valuebox a pop up window will appear showing some tabular data.
But that window should have a scroll bar, cross button in right top corner and records should be shown 10 by default instead of 25 showing now in top left corner of the pop up window.
Can anyone help me with this ?
If your server part is like this, it is limited to 10 shown per page:
server <- function(input, output, session){
onclick('clickdiv', showModal(modalDialog(
title = "Your title",
renderDataTable(data, options = list(
pageLength = 10,
scrollY = "400px"
))
)))
}
I'm not sure I understand the need for the other parts. With 10 records, you don't need to be able to scroll up and down, but even when I set this to a lot of records (say 100), the normal page scroll bar works fine. And there is a button to dismiss the table already (although I appreciate it is not the cross in the corner you are requesting).
You can change other parts of your DataTable using the options - you can see some examples here.
Hope this helps!
EDIT: I've added an option for a vertical scroll bar. You can change the number to suit you.
If that doesn't work then you might be using a setup (for eg Mac) where scrollbars are hidden by default until you start scrolling.
is there any way to show all of the contents in the mainPanel only when the user clicks the action button? ive been searching the internet for awhile for the answer but couldn't really find an answer. i know i can use hidden - it works on smaller elements inside the mainPanel, such as showing a picture on click but doesn't work on the whole mainPanel itself. any suggestions? finding a way to wrap the whole main panel inside a hidden instead of each element in the mainPanel wrapped in a hidden would be easier i think but i can't seem to find a way to make it work.
in dashboard body:
fluidRow(
column(12, actionButton("analyze", "Fetch Data!", width = "100px"))),
hidden(
mainPanel(
hidden( (htmlOutput("artistpic")), // this works fine & shows on button click
infoBoxOutput("approvalBox"))
)),
server:
pic <- eventReactive(input$analyze2, {
print(get_id_picture()[3])
url = toString(get_id_picture()[3])
print(url)
url
})
output$artistpic <- renderText({c('<img src="',pic(),'"width="17%" height="17%">')})
This is easy with shinyjs.
Just surround mainPanel() with a div() tag so that you can use it's id for toggling it's visability and start the app with the div tag hidden using hidden() like in the following example:
# ui.R
fluidPage(
useShinyjs(),
actionButton("toggle.main.button", "Toggle Main"),
div(id = "main",
mainPanel(
p("This paragraph is in main."),
p("This one too!")
)
) %>% shinyjs::hidden()
)
# server.R
library(shinyjs)
function(input, output, session) {
# Toggling visability of main on button click.
observeEvent(input$toggle.main.button, {
shinyjs::toggle("main")
})
}
I am using Shiny to build a web app. I am adding a button that will show/hide some element on the page. But after the element got hide, other page componemt does not resize themselves to fill the screen. For example, I try to hide the sidebar of a sidebarLayout, by using toggle function in shinyjs. Here's the code I have:
library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(sidebarLayout(
sidebarPanel(id="sidebar"),
mainPanel(wellPanel(actionButton("sideBarControl", label = "Show/Hide")))
)))
server <- function(input, output) {
observeEvent(input$sideBarControl, {
shinyjs::toggle(id = "sidebar")
# potentially some statements here to fix the layout? But what should they be?
})
}
shinyApp(ui = ui, server = server)
The sidebar hides/shows when clicking sidebarControl button correctly, but instead of resize mainPanel to fill the screen, it shifts mainPanel to the left, and left a space at the right. How to resolve this? See the pictures below:
Let me respond to the comment to my previous suggestion. Since this is quite different from the previous, I write a new answer instead of editing it.
In general, you can inspect what HTML code is generated from your UI description by running the command on console. For example,
sidebarPanel(id="sidebar", actionButton("b", "btn"))
##<div class="col-sm-4">
## <form class="well" id="sidebar">
## <button id="b" type="button" class="btn btn-default action-button">btn</button>
## </form>
##</div>
This tells us that sidebarPanel function generates a nested framework of
div with class col-sm-4; and
form with the supplied id
The reason why your example code did not shifts the main panel is clear now; Even if you hide sidebar, which is the form inside, there still is div that encloses it.
So we would like a way to hide the div. Unfortunately, I could not find a way to do so with sidebarPanel function. An alternative is to use column function.
column(width=3, id="col", actionButton("b", "btn"))
##<div class="col-sm-3" id="col">
## <button id="b" type="button" class="btn btn-default action-button">btn</button>
##</div>
You can see that the output of column is kind of similar to that of sidebarPanel. Importantly, column allows you to give an ID to the div element.
So, here is a toy example that shifts the main panel to the left (i.e. fully hide the sidebar).
library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
column(width=4, id="spcol", actionButton("dummy", "dummy")),
column(width=8, wellPanel(actionButton("sideBarControl",
label = "Show/Hide")))
)))
server <- function(input, output) {
observeEvent(input$sideBarControl, {
shinyjs::toggle(id = "spcol")
})
}
shinyApp(ui = ui, server = server)
Now, let's tackle on your second point, that is, letting the main panel to fill, instead of shifting.
mainPanel()
##<div class="col-sm-8"></div>
So it does not fill because its width is set as 8. We want to change it to 12, and we can use toggleClass function from shinyjs library for that. In short, toggleClass adds a class to an element if it does not have one, and removes the class if it already does.
I believe the code below behaves as we wish.
library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
column(width=4, id="spcol", actionButton("dummy", "dummy")),
column(width=8, id="main", wellPanel(actionButton("sideBarControl",
label = "Show/Hide")))
)))
server <- function(input, output) {
observeEvent(input$sideBarControl, {
shinyjs::toggle(id = "spcol")
shinyjs::toggleClass("main", "col-sm-8")
shinyjs::toggleClass("main", "col-sm-12")
})
}
shinyApp(ui = ui, server = server)
Also, here is another working example code, in which two versions of main panels with different widths are hidden and shown by turn.
library(shiny)
library(shinyjs)
ui <- fluidPage(useShinyjs(), br(), wellPanel(fluidRow(
column(width=4, id="spcol", actionButton("dummy", "dummy")),
column(width=8, id="main1", wellPanel(actionButton("sideBarControl",
label = "Show/Hide"))),
column(width=12, id="main2", wellPanel(actionButton("sideBarControl2",
label = "Show/Hide")))
)))
server <- function(input, output) {
shinyjs::toggle(id = "main2")
observeEvent(input$sideBarControl+input$sideBarControl2, {
shinyjs::toggle(id = "spcol")
shinyjs::toggle(id = "main1")
shinyjs::toggle(id = "main2")
})
}
shinyApp(ui = ui, server = server)
How about you try shinydashboard? It has the behavior you are looking for by default.
https://rstudio.github.io/shinydashboard/get_started.html
I have a button in my ui.R that I want to be shown only when "Summary" tab is selected, so I thought of this code
fluidRow(
column(4,
column(12,id="sub",
actionButton("submit", "SUBMIT", width = "100%"))),
column(8,
bsCollapse(id = "collapse7", open = "Results",
bsCollapsePanel("Results",
tabsetPanel(
tabPanel("Summary",
tags$script(HTML("document.getElementById('sub').style.visibility = 'visible';")))
tabPanel("Plot",
tags$script(HTML("document.getElementById('sub').style.visibility = 'hidden';"))))
))))
The problem is, the button is hidden even though in my first tab it should be visible and also when i go to Plots and back to Summary, the button stays hidden.
After looking at: How to use tabPanel as input in R Shiny?
I decided to play with observeEvent and the input$tabset option. The result is 100% working and it's really simple. Here's the code:
observeEvent(input$choices, {
choice = input$choices
if(choice == "Summary")
{
runjs(
"document.getElementById('submit').style.visibility = 'visible';"
)
}
else
{
runjs(
"document.getElementById('submit').style.visibility = 'hidden';"
)
}
})
Also, I found out why my previous code wasn't working, it was due to the fact that when the UI was initialized, the button element kept the last style modification (the hidden one) and it didn't change depending on the tab I have selected, since its not reactive.
How can tab's page reset to initial state when moving from one tab to another in R shiny?That is consider that there are two tabs A abs B.When A is clicked and some actions are performed in A such as button click and filling a form and all.Then when moving to tab B and again to tab A.Then tab A should be reset to its initial state.Can this action be performed automatically when moving from one tab to another without clicking button in R?
My code is
ui.R
shinyUI(
navbarMenu
(
"IDnavbarmenu",
tabPanel("A", fluidRow( column(2,
actionButton("button1", "button1")))),
tabPanel("B")
)
)
Server.R
shinyServer(function(input, output,session) {
observeEvent(
input$button1,
output$ui1 <- renderUI({isolate({
div( id="g",
fluidPage(shinyjs::useShinyjs(),
fluidRow(column(4,
textInput("name", label = "NAME:",
value ='')))))})}))
}