I have three input controls and want to align one at the left side and two at the right side of the page in a shiny application. Furthermore, the two selectInput controls have to be side by side which I solved using the code fome this answer.
Using column's and align = "right" I'm able to get what I want. The problem is that the text as well as the select arrow is also right-aligned, which is looking awful (see picture and highlighted area below).
Is there another way to achieve the expected alignment?
library(tidyverse) # loaded for the words data.frame
library(shiny)
ui <- fluidPage(
navbarPage(
set.seed(1233),
fluidRow(
column(8,radioButtons("plot", "", choices = list("Cluster"="1","Correlation"="2"), inline=T)),
column(4, align = "right",
div(style="display: inline-block;vertical-align:top; width: 120px;",
selectInput("Something","Something", choices = sample(words, 5))),
div(style="display: inline-block;vertical-align:top; width: 120px;",
selectInput("Else","else", choices = sample(words, 6))))
)
)
)
server <- function(input, output) {}
shinyApp(ui, server)
I can't give you advice for best practice of alignment, but in this case, you can add
text-align:left !important;
to your style args
Related
I'm trying to adjust the positioning of conditionally-rendered objects in R shiny. When running the below skeleton code and clicking the "Delete" action button, I'd like to nudge the conditionally-rendered text ("Select series to delete >>") a bit to the right, and move the little selectInput() box that also conditionally appears on the far right a bit to the left, closer to "Select series to delete >>". I've fiddled with column widths, etc., and I've exhausted all the formatting options which I know of which are limited. Any suggestions for fine-tuning the positioning of these items? My guess is this would entail some CSS which I know almost nothing about.
Skeleton code:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {show(output_name)})
observeEvent(input$addSeries, {hide(output_name)})
}
ui <- fluidPage(br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5((hidden((textOutput("delFlag")))))),
column(3,hidden(uiOutput("delSeries2")))
)
)
server <- function(input, output, session) {
output$delFlag <- renderText("Select series to delete >>")
output$delSeries2 <-
renderUI(
selectInput("delSeries3",
label = NULL,
choices = c(""),
selected = "",
width = '110px')
)
toggleView(input,"delSeries2")
toggleView(input,"delFlag")
}
shinyApp(ui,server)
You can add some styles to the 2 columns like so:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {hide(output_name)})
observeEvent(input$addSeries, {show(output_name)})
}
# (0)
css <- HTML("
.row .nudge-right {
padding-right:0;
}
.row .nudge-left {
padding-left:0;
}
")
ui <- fluidPage(
tags$head(tags$style(css)), # (1)
br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5(hidden(textOutput("delFlag"))),
class = c("nudge-right", "text-right")), # (2)
column(3,hidden(uiOutput("delSeries2")), class = "nudge-left") # (2)
)
)
Explanation
The white space you see is partly due to the width of the column and partly due to the so called padding (an additional white space around the element). To bridge this gap you can:
Right align the text. Here you can rely on the already pre-defined (by the underlying bootstrap framework) class text-right.
Further decrease the gap by removing the right padding from the text column and the left padding from the input column. In order to so, you define new classes (I called them .nudge-right and .nudge-left respectively) where you deliberately set the padding to your liking (here I removed it completely, you may want to provide a small offset though - e.g. 5px).
Then all which is left is to
Create some css with the class definitions (#0)
Load the css (#1)
Assign the classes to the columns (#2)
I am interested in removing or hiding the side arrows that appear when you use numericInput() with shiny. I will attach an image of the arrows that I am referring to so everyone can understand which part I would like to remove/hide. After reading the documentation, it does not appear that there is an option to remove these arrows. So I am wondering if there is a way to use CSS to remove these arrows. I did see one other post that asked a similar question. However, I am only interested in using numericInput().
I will attach some sample code. The code essentially does nothing but it will give you a reproducible example.
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
WARNING: I have read online that the side arrows do not show up on all web browsers and some versions of RStudio. See here
It does not appear that there is a way to remove the arrows from a numericInput(), however, there is a way to hide them. Just to be clear there is a difference between removing and hiding. Removing the arrows, in theory, should completely remove the code for the arrows. Hiding the arrows will simply mask the code for the side arrows, however, the code will still be present but will not be seen by the user unless they inspect the page.
Below is CSS that can be used to hide the side arrows from numericInput().
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
)
If you wanted to apply this code to the example given in the question, then you could do something like this
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
),
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
Overall this is just a workaround because there is no option to remove the side arrows.
The Shinyglide package is just what I need, using a carousel for grouped radio buttons giving the user many choices for data parsing.
However, the "Next" (and "Back") button occupies a large white space. I'd like to shift the button in line with the glide row (see image at bottom). Does anyone know how to do this? Is there a CSS trick? Reading through the Glide manual, the only choices are "top" and "bottom".
If moving the Next/Back button isn't possible, a secondary option is to insert (a somewhat superfluous) line of text but in line with the Next/Back buttons, to at least cover up the annoyingly large white space.
The actual panel this is for has much more information presented than in this example, so I'm trying to make the page as clean as possible.
Please see image at bottom that better explains what I'm trying to do.
Reproducible example:
library(dplyr)
library(DT)
library(shiny)
library(shinyglide)
ui <-
fluidPage(
fluidRow(div(style = "margin-top:15px"),
strong("Input choices shown in row below, click ´Next´ to see more choices:"),
column(12, glide(
height = "25",
controls_position = "top",
screen(
div(style = "margin-top:10px"),
wellPanel(
radioButtons(inputId = 'group1',
label = NULL,
choiceNames = c('By period','By MOA'),
choiceValues = c('Period','MOA'),
selected = 'Period',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
),
screen(
div(style = "margin-top:10px"),
wellPanel(
radioButtons(inputId = 'group2',
label = NULL,
choiceNames = c('Exclude CT','Include CT'),
choiceValues = c('Exclude','Include'),
selected = 'Exclude',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
)
)
)
),
DTOutput("plants")
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)
You could use a custom control element with custom_controls, and then have it hover over the displayed screen on the top right with a container set to absolute positioning. Setting a limited width for the container will ensure that the back button won't fly too far out.
Something along these lines:
glide(custom_controls = div(class = "glide-controls", glideControls()), ...)
# Somewhere in the UI
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
)
Just make sure to also set controls_position = "bottom" so that the controls hover over the screen content, rather than under it.
A minimal example app:
library(shiny)
library(shinyglide)
ui <- fixedPage(
h3("Simple shinyglide app"),
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
),
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(wellPanel(p("First screen."))),
screen(wellPanel(p("Second screen.")))
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
I'm trying to put some Datatables and Histograms inside boxes of defined height in a Shiny Dashboard, the problem is that when I fix the height (lets say, to 250), the datatable exceeds the limits.
I know we have "autowidth" to use with datatables, but havent seen nothing similar for the Height. I tried to fix the height of the datatable too, but that didn't work for me neither. Also, when I open the shiny in a smaller screen, the box would resize, but the datatable don't.
Here's an example of the problem
library(shiny)
library(shinydashboard)
library(htmltools)
ui <- dashboardPage(skin = "black", title = "Dashboard",
dashboardHeader(title = "Dashboard"),
dashboardSidebar(width = 300),
dashboardBody(
tags$head(tags$style(HTML("
div.box {
text-align: center;
border-style: solid;
border-bottom-color:red;
border-left-color:red;
border-right-color:red;
border-top-color:red;
border-bottom-width:20px;
border-top-width:20px;
border-left-width:20px;
border-right-width:20px;
}
"))),
box(title = "Resume", width = 4, column(12, withSpinner(DT::dataTableOutput("tab"))),
align="center", status = "danger",solidHeader = T,height=250)
))
server <- function(input, output) {
output$tab <- DT::renderDataTable({
datatable(head(iris),options=list("autoWidth"=TRUE, "pagelength"=15,"scrollY"=TRUE,"scrollX"=TRUE,"searching"=FALSE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
Actually ScrollX works perfectly, why scrollY doesnt work aswell?
I read about using tabBox instead of Box, but that doesnt work neither.
Thank you very much in advance.
Try withSpinner(DT::dataTableOutput("tab", height = '240px'), currently your code is setting the height of the box, not the data table.
Also, try style = "overflow-x: scroll;" in the box() arguments for the scrolling
In the Shiny package of R, how can you make the text in the titlePanel be centred on the top of the page?
Here is an example of what I mean
The only code I've used for the titlePanel is:
ui <- fluidPage(
titlePanel("How to Centre Me??")
When I look at the documentation, the only variables the function takes is:
titlePanel(title, windowTitle = title)
So is it possible to centre the title?
Thanks
In case anyone is still in need of a simple solution:
titlePanel(
h1("First level title", align = "center")
)
You can use column() function.
like this:
fluidPage(
column(3,offset = 4, titlePanel("How to Centre Me??"))
)
where 3 is column width and offset you can adjust according to your requirement.
With css:
ui <- fluidPage(
tags$head(
tags$style(
".title {margin: auto; width: 200px}"
)
),
tags$div(class="title", titlePanel("Centered title"))
)
Or you could just give up on the titlePanel() which is usually centered over the sidebar and just do this:
titlePanel(""),
sidebarLayout(
sidebarPanel(
),
mainPanel(
h1("This is my title now")
)
Not elegant but oh-so-easy.
If you're using a navbarPage() you should you the header=h1("title",align="center") and footer('same syntax as header') arguments.