Fixing top section in shiny - r

Is there a way to fix the top section of the dashboard here. Right now, the widgets (selectinput) are fixed, but when the user scroll down, it gets covered by the datatable. Can we not make sure this does not get covered and only datatable moves down?
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:fixed; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)

You can use the CSS z-index property to control the stack order the HTML elements:
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:fixed; width:inherit; z-index: 1; background-color: white;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)
Another approach is using position: sticky;.

Changing the style line to position:absolute makes it so that the selection boxes scroll up and out of the page when you scroll down, if that's what you were looking for.
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:absolute; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
dataTableOutput("uioutput", height = "2000px")
))
server <- function(input, output, session) {
output$uioutput <- renderDataTable({
datatable(iris)
})
}
shinyApp(ui, server)
If you're trying to make the table stay in place and scroll down through the table, use DTOutput() and renderDataTable() instead of dataTableOutput() and renderDataTable(). Then, get rid of datatable() inside renderDT() and just use 'iris'. Finally, you can add the Scroller extension and an options list with scrollY and scroller. Others may be able to explain the difference between DT and DataTable (this page might help as well: https://rstudio.github.io/DT/shiny.html), but I believe DTOutput and renderDT are more flexible. Note: you can add horizontal scrollbars as well with scrollX if you use a table with more fields in the future.
Updated code is below.
Hope either of these helps!
library(shiny)
library(DT)
ui <- shinyUI(fluidPage(
titlePanel(fluidRow(
div(column(12, align="center",
selectInput("rmd1", "RMDw", choices = c(1,2)),
selectInput("rmd2", "RMD2", choices = c(1,2))
), style = "position:absolute; width:inherit;")
)),
br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),br(),
DTOutput("uioutput", height = "600px")
))
server <- function(input, output, session) {
output$uioutput <- renderDT({
iris
},
extensions = c('Scroller'),
fillContainer = T,
options = list(deferRender = T,
scrollY = 400,
scroller = T)
)
}
shinyApp(ui, server)

Related

How to avoid collapsing with shinyWidgets dropdown and a datatable

I want to display a spreadsheet with some information in shinyWidgets dropdown, sometimes spanning multiple pages.
If you click on the next page, the dropdown closes again.
How can I avoid this?
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
br(),br(),br(),
p("How to go to the next page, without collapsing?"),
uiOutput("irisdrop", inline = TRUE)
)
server <- function(input, output, session) {
output$irisdrop <- renderUI({
dropdown(circle = FALSE, inputId = "iris",
label = "iris", status = "primary",
datatable(iris, rownames = NULL,
height = "100%",
selection = "none"
)
)
})
}
shinyApp(ui, server)
You can do something like this -
library(shiny)
library(shinyWidgets)
library(DT)
ui <- fluidPage(
dropdownButton(
inputId = "iris",
label = "iris",
icon = icon("sliders"),
status = "primary",
circle = FALSE,
DT::dataTableOutput("iris_tb")
)
)
server <- function(input, output, session) {
output$iris_tb <- DT::renderDataTable({
datatable(iris, rownames = NULL,
height = "100%",
selection = "none"
)
})
}
shinyApp(ui, server)
Note: You can even use dropdown() instead of dropdownButton() from shinyWidgets package.
dropdown() is similar to dropdownButton() but it don't use Bootstrap, so you can put pickerInput in it. Moreover you can add animations on the appearance / disappearance of the dropdown with animate.css.
For more detail, you can look at the page 30 of the following document -
https://cran.r-project.org/web/packages/shinyWidgets/shinyWidgets.pdf

Left align checkboxgroups to a single column in a shiny sidebar

New to R/Shiny, I'm attempting to create checkboxgroups in a Shiny sidebar where choices are in a single column and left aligned.
Additionally, is there any way to remove the break/space between the first and second checkboxinputs?
I've tried turning "inline" on and off, but it doesn't seem related. From what I can see in the forums, the answer might require HTML/CSS, but I'm not sure how to integrate that into a sidebar/checkbox group.
Here's how the code looks currently:
library(shiny)
library(shinydashboard)
sidebar <- dashboardSidebar(
checkboxGroupInput( inputId='ABC', label='ABC', choices= c('A','B','C'), inline=TRUE )
,checkboxInput('bar0','All/None', value=TRUE))
header <- header <- dashboardHeader(
title = "aligned column",titleWidth = 300)
body <- dashboardBody()
ui <- dashboardPage(title = 'aligned column', header, sidebar, body)
server <- function(input, output,session) {
## All/None buttons on selections ----
observeEvent( input$bar0, {
updateCheckboxGroupInput(
session, 'ABC', choices = c('A','B','C'), inline=TRUE,
selected = if (input$bar0) choices = c('A','B','C'))})
}
shinyApp(ui, server)
Thanks!
Hello Adam have you tried changing inline = FALSE in the server section? Like so:
server <- function(input, output,session) {
## All/None buttons on selections ----
observeEvent( input$bar0, {
updateCheckboxGroupInput(
session, 'ABC', choices = c('A','B','C'), inline=FALSE,
selected = if (input$bar0) choices = c('A','B','C'))})
}
This seems to have worked for me. If I am understanding your question, this is what you wanted to do right? Screenshot

Update DataTable dynamically with navbar

Context
I'm building an app whith Rshiny. I created a dynamic navbar. Now, i would like to insert a datatable at each navbar's item (tabPanel). But i don't want to create a table per item in navbar. So i would like to know if it's possible to create only 1 table which update itself with the navbar's selected item ??
Code to create dynamical navbar
runApp(list(
ui = fluidPage(
navbarPage(theme=shinytheme("paper"),title="test",
tabPanel(uiOutput('mytabs'))
)
),
server = function(input, output, session){
output$mytabs = renderUI({
nTabs = length(unique(iris$Species))
myTabs = lapply(unique(iris$Species)[1:nTabs], tabPanel)
do.call(tabsetPanel, myTabs)
})
}
))
Now i woulk like to display datatable(subset(iris,Species=="value of navbar")) at each navbar's item
Can someone explain me how to do ?
Using question here, you can define a function and call it as below. Note that csv button will only work in a browser.
library(shiny)
library(shinythemes)
runApp(list(
ui = fluidPage(
navbarPage(theme=shinytheme("paper"),title="test",
tabPanel(uiOutput('mytabs'))
)
),
server = function(input, output, session){
createTabs <- function(species_r){
tabPanel(title = paste("Data", species_r, sep=" "),
datatable(subset(iris,Species==species_r),rownames = FALSE,
extensions = 'Buttons', options = list(dom = 'Bfrtip', buttons = c('copy', 'csv',I('colvis'))))
)
}
output$mytabs = renderUI({
nTabs = length(unique(iris$Species))
myTabs = lapply(unique(iris$Species)[1:nTabs], createTabs)
do.call(tabsetPanel, myTabs)
})
}
))

Shiny splitLayout and selectInput issue

When I combine the splitLayout and selectInput in R Shiny, there is something wrong.
The dropdown list of choices cannot be displayed properly.
How can we address this issue.
Please check the reproducible code.
library(shiny)
server <- function(input, session, output) {
output$select_1 = renderUI({
selectInput("select_input","select", choices = LETTERS)
})
}
ui <- fluidPage(
splitLayout(
uiOutput("select_1")
)
)
shinyApp(ui = ui, server = server)
I have 8 selectInputs that I want to place evenly side by side in one row.
Using fluidrow is not OK because the column width can only be integers.
I wonder if there is any alternative way to do this.
Here is a potential fix. It appears that the parent div of the dropdown menu has an overflow: auto style, which blocks the dropdown menu. Changing to visible fixes it.
library(shiny)
server <- function(input, session, output) {
output$select_1 <- renderUI({
selectInput("select_input","select", choices = LETTERS)
})
}
ui <- fluidPage(
splitLayout(
uiOutput("select_1"),
tags$head(tags$style(HTML("
.shiny-split-layout > div {
overflow: visible;
}
")))
)
)
shinyApp(ui = ui, server = server)
I tried the solution of #Xiongbing Jin, but that didn't fully resolve the issue for me, but pushed my to this solution:
# in ui.R
splitLayout(
tags$head(tags$style(HTML(".shiny-split-layout > div {overflow: visible;}"))),
cellWidths = c("0%","50%", "50%"), # note the 0% here at position zero...
selectInput("A", label = "A LBL",),
selectInput("B", label = "B LBL")
)

Auto complete and selection of multiple values in text box shiny

Is it possible to select multi values using auto complete strings similar to google search and stack overflow tags selection in shiny text box.
dataset<-cbind("John Doe","Ash","Ajay sharma","Ken Chong","Will Smith","Neo"....etc)
I want to select multiple variables from the above dataset as a auto fill in my textbox and pass it to my server.R
ui.R
shinyUI(fluidPage(
titlePanel("test"),
sidebarLayout(
sidebarPanel(
helpText("text"),
textInput("txt","Enter the text",""),
#Pass the dataset here for auto complete
),
mainPanel(
tabsetPanel(type="tab",tabPanel("Summary"),textOutput("text2"))
)
)
))
server.R
# server.R
shinyServer(function(input, output) {
output$text2<- renderText({
paste("hello",input$txt)
})
}
)
EDITED
I have used select2input from shinysky for selecting mulitiple varialbes but now I have added submit button to get selected values together.
#ui.R
select2Input("txt","This is a multiple select2Input",choices=c("a","b","c"),selected=c("")),
actionButton("go","submit")
I want to bind selected option lets say user selected a and c then new variable is
#server.R
input$go #if pressed submit button
var<-cbind("a","c")
output$text<-renderText({ print ("var")})
but this is not working
Look into shinysky package and textInput.typeahead. You can further customize the style of the textinput yourself. Edit: I added example with select2Input from the shinysky package also for reference
rm(list = ls())
library(shinysky)
library(shiny)
my_autocomplete_list <- c("John Doe","Ash","Ajay sharma","Ken Chong","Will Smith","Neo")
ui <- shinyUI(
fluidPage(tags$style(type="text/css",".shiny-output-error { visibility: hidden; }",".shiny-output-error:before { visibility: hidden; }"),
tags$style(type="text/css","#search { top: 50% !important;left: 50% !important;margin-top: -100px !important;margin-left: -250px
!important; color: blue;font-size: 20px;font-style: italic;}"),
mainPanel(
# one way of doing it
textInput.typeahead(id="search",
placeholder="Type your name please",
local=data.frame(name=c(my_autocomplete_list)),
valueKey = "name",
tokens=c(1:length(my_autocomplete_list)),
template = HTML("<p class='repo-language'>{{info}}</p> <p class='repo-name'>{{name}}</p>")
),
br(),br(),
# using select2Input
select2Input("select2Input1","",choices=c(my_autocomplete_list),type = c("input", "select"))
)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)
Edit 2 as per request. Please wrap your objects in a reactive expressions as I did e.g. var <- reactive({...}) so you can re-use those later
rm(list = ls())
library(shinysky)
library(shiny)
my_autocomplete_list <- c("John Doe","Ash","Ajay sharma","Ken Chong","Will Smith","Neo")
ui <- shinyUI(
fluidPage(sidebarPanel(select2Input("txt","",choices=c("a","b","c"),selected=c("")), br(),actionButton("go","submit"), width =2),
mainPanel(textOutput('text'))
)
)
server <- function(input, output, session) {
var <- reactive({
if(input$go==0){return()}
isolate({
input$go
cbind("a","c")
})
})
output$text <- renderText({var()})
}
shinyApp(ui = ui, server = server)
A much easier approach imho is to use shiny::selectizeInput(). It allows you to autocomplete inputs with via the choices argument.
rm(list = ls())
library(shiny)
my_autocomplete_list <- c("John Doe","Ash","Ajay sharma",
"Ken Chong","Will Smith","Neo")
ui <- shinyUI(
selectizeInput(
inputId = 'search',
label = 'Search',
choices = my_autocomplete_list,
selected = NULL,
multiple = TRUE, # allow for multiple inputs
options = list(create = FALSE) # if TRUE, allows newly created inputs
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)

Resources