Some right-aligned tabPanels in shiny - css

Using navbarPage I would like to have some tabPanels to be right-aligned while the rest of tabPanels and navbarMenus to be left-aligned:
So, instead of this
library(shiny)
ui = tagList(
navbarPage(
title = "My app",
navbarMenu("Left1",
tabPanel("Subleft11"),
tabPanel("Subleft12")),
tabPanel("Left2"),
tabPanel("Left3"),
tabPanel("Right1"),
tabPanel("Right2")
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
I would like to get something like this:
Solution from GyD works fine for tabsetPanel but I was not able to adapt it to navbarPage. I tried to add
tags$head(
tags$style(HTML(
".navbar ul li:nth-child(4) { float: right; }
.navbar ul li:nth-child(5) { float: right; }"
))),
but without desired effect.

You could do that with some css.
This would be an easy example which aligns the 4th and 5th list elements inside the class navbar-nav a float: right;.
By including right: 150px; to the 4th child, you keep the tabs in correct order.
App.R
library(shiny)
library(shinythemes)
ui = tagList(
tags$head(tags$style(HTML("
.navbar-nav {
float: none !important;
}
.navbar-nav > li:nth-child(4) {
float: right;
right: 150px;
}
.navbar-nav > li:nth-child(5) {
float: right;
}
"))),
navbarPage(
title = "My app",
theme = shinytheme("cerulean"),
navbarMenu("Left1",
tabPanel("Subleft11"),
tabPanel("Subleft12")),
tabPanel("Left2"),
tabPanel("Left3"),
tabPanel("Right1"),
tabPanel("Right2")
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)

Maybe something along these lines:
tags$head(
tags$style(HTML(
"
.navbar-header { width: 10% }
.navbar-nav { width: 90% }
.navbar-nav>li:nth-child(4) { float: right; }
.navbar-nav>li:nth-child(5) { float: right; }"
)))

Related

Remove newline from RShiny CSS SortableJS

I have a 99% working minimal example here. The only thing I would like to change is to have the rank number next to the letter rather than on the line above it.
library(shiny)
library(sortable)
addDiv <- function(x) {lapply(x,function(x){tags$div(x)})}
ui <- fluidPage(
tags$head(
tags$style(HTML('
#rank_list_basic > div {cursor: move; #fallback
cursor: grab; cursor: pointer;}
#rank_list_basic {list-style-type: none; counter-reset: css-counter 0;}
#rank_list_basic > div {counter-increment: css-counter 1;}
#rank_list_basic > div:before {content: counter(css-counter) ". ";}
')
)
),
fluidRow(
rank_list(
text = "Drag the items in any desired order",
labels = addDiv(c("A","B","C","D","E")),
input_id = "output",
css_id = "rank_list_basic"
),
verbatimTextOutput("results_basic")
)
)
server <- function(input, output) {
output$results_basic <- renderPrint({
input$output
})
}
shinyApp(ui, server)
You need to simply put your labels in a list instead of using addDiv:
library(shiny)
library(sortable)
addDiv <- function(x) {lapply(x,function(x){tags$div(x)})}
ui <- fluidPage(
tags$head(
tags$style(HTML('
#rank_list_basic > div {cursor: move; #fallback
cursor: grab; cursor: pointer;}
#rank_list_basic {list-style-type: none; counter-reset: css-counter 0;}
#rank_list_basic > div {counter-increment: css-counter 1;}
#rank_list_basic > div:before {content: counter(css-counter) ". ";}
')
)
),
fluidRow(
rank_list(
text = "Drag the items in any desired order",
labels = list("A","B","C","D","E"),
input_id = "output",
css_id = "rank_list_basic"
),
verbatimTextOutput("results_basic")
)
)
server <- function(input, output) {
output$results_basic <- renderPrint({
input$output
})
}
shinyApp(ui, server)

Position carousel chevrons alongside bullets

I am using R's bsplus package to build a carousel of images. I want to move the chevrons next to the bullets.
I am aware of this SO sol'n regarding how to reposition the prev/next chevrons.
I can get close (see the 'right' chevron) but when I position it where I want it (see the 'left' chevron) it's no longer clickable.
Why is this?
How can I position the chevrons next to the bullets and maintain their functionality?
R Script
library("shiny")
library("bsplus")
ui <- fluidPage(
includeCSS("/home/law/whatbank_home/tests/bullet.css"),
# Application title
titlePanel("Carousel Demo"),
uiOutput("carousel")
)
server <- shinyServer(function(input, output) {
output$carousel <- renderUI({
bs_carousel(id = "images", use_indicators = TRUE) %>%
bs_append(
content = bs_carousel_image(src = "https://placehold.it/900x500/3c8dbc/ffffff&text=Merry")
) %>%
bs_append(
content = bs_carousel_image(src = "https://placehold.it/900x500/3c8dbc/ffffff&text=Christmas")
) %>%
bs_append(
content = bs_carousel_image(src = "https://placehold.it/900x500/3c8dbc/ffffff&text=To")
) %>%
bs_append(
content = bs_carousel_image(src = "https://placehold.it/900x500/3c8dbc/ffffff&text=All")
)
})
})
# Run the application
shinyApp(ui = ui, server = server)
css
.carousel-control.left,
.carousel-control.right {
background: transparent;
}
.carousel-indicators .active {
background-color: #FCB700;
margin-bottom: 70px;
}
.carousel-indicators li {
background-color: #D8D8D8;
border: 1px solid #000;
margin-bottom: 70px;
}
.carousel-control.left .glyphicon {
left: 180px;
margin-left: 180px;
top: 183px;
margin-top: 183px;
}
.carousel-control.right .glyphicon {
right: 180px;
margin-right: 180px;
top: 160px;
margin-top: 160px;
}
You should try
.carousel-control {
width: 2%
}
In the example below, I use 2%.
library(shiny)
library(shinydashboardPlus) ### carousel() is from this package
library(DT)
jscode <-"
$(document).ready(function(){
$('#mycarousel').carousel( { interval: false } );
});"
shinyApp(
ui = dashboardPage(
header = dashboardHeader(),
sidebar = dashboardSidebar(),
body = dashboardBody(
tags$head(
tags$style(HTML("
#mycarousel {
width:900px;
height:600px;
}
.carousel-control{
color:#FF0000;
width: 2%;
}
"))
),
tags$head(tags$script(HTML(jscode))),
carousel(
id = "mycarousel",
carouselItem(
DTOutput("show_iris_dt")
),
carouselItem(
caption = "An image file",
tags$img(src = "YBS.png")
),
carouselItem(
caption = "Item 3",
tags$img(src = "http://placehold.it/900x500/39CCCC/ffffff&text=Happy+New+Year")
)
)
),
title = "Carousel Demo"
),
server = function(input, output) {
output$show_iris_dt <- renderDT({
datatable(iris)
})
}
)

Is there a way to *output* star rating in R Shiny?

Dears,
In my app, users rate some stuff.
I want to output 5-star ratings based on their ratings just like the ones in IMDB.
There are fractions in my numbers, and I want the stars to accommodate them.
I don't know Java nor JavaScript at all.
Is there something like a package for this? or what to do?
Thanks in advance.
You'll need to create two files, a css and then your app...ie:
app.R
-- www/
------ stars.css
Your stars.css file will have the rules for the HTML markup which will update based on our app after using includeCSS in the header::
.ratings {
position: relative;
vertical-align: middle;
display: inline-block;
color: #b1b1b1;
overflow: hidden;
}
.full-stars{
position: absolute;
left: 0;
top: 0;
white-space: nowrap;
overflow: hidden;
color: #fde16d;
}
.empty-stars:before,
.full-stars:before {
content: "\2605\2605\2605\2605\2605";
font-size: 44pt; /* Make this bigger or smaller to control size of stars*/
}
.empty-stars:before {
-webkit-text-stroke: 1px #848484;
}
.full-stars:before {
-webkit-text-stroke: 1px orange;
}
/* Webkit-text-stroke is not supported on firefox or IE */
/* Firefox */
#-moz-document url-prefix() {
.full-stars{
color: #ECBE24;
}
}
/* IE */
<!--[if IE]>
.full-stars{
color: #ECBE24;
}
<![endif]-->
In our app we want the final markup to appear as follows:
<div class="ratings">
<div class="empty-stars"></div>
<div class="full-stars" style="width:70%"></div>
</div>
So to do this we use a combination of UI static elements and then uiOutput, which matches a renderUI on the server side:
library(shiny)
ui <- fluidPage(
includeCSS("www/stars.css"),
sliderInput(inputId = "n_stars", label = "Ratings", min = 0, max = 5, value = 3, step = .15),
tags$div(class = "ratings",
tags$div(class = "empty-stars",
uiOutput("stars_ui")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
output$stars_ui <- renderUI({
# to calculate our input %
n_fill <- (input$n_stars / 5) * 100
# element will look like this: <div class="full-stars" style="width:n%"></div>
style_value <- sprintf("width:%s%%", n_fill)
tags$div(class = "full-stars", style = style_value)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Our app then using the slider inpout to create the fill % of stars.
I wrote a package to solve similar problem so that others don't need to work with CSS and JS. https://github.com/shahronak47/shinyRatings
#Installation of the package from Github
#devtools::install_github('shahronak47/shinyRatings')
library(shiny)
library(shinyRatings)
ui <- fluidPage(
shinyRatings('star'),
textOutput('text')
)
server <- function(input, output, session) {
output$text <- renderText({paste("No. of stars : ", input$star)})
}
shinyApp(ui, server)

Target specific dropdown css from shinywidget package

I'm struggling to find out how to target 1 of the two dropdowns specifically with css styling code.
I can style the dropdowns in general, but not individually
I have tried to target it in the following ways, but none work.
#MyDropDown1 .sw-show.sw-dropdown-content {
#sw-content-MyDropDown1 .sw-show.sw-dropdown-content {
.dropdown-content-MyDropDown1 {
#dropdown-content-MyDropDown1 {
#dropdown-menu-MyDropDown1 {
How to find the right syntax to target the 1st dropdown?
here is the app:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
tags$head(tags$style(HTML('
.sw-show.sw-dropdown-content {
display: block;
left: 200px;
top: 100px;
height: 300px;
width:
} '))),
dropdown(inputId = "MyDropDown1",
tags$h3("List of Input")),
dropdown(inputId = "MyDropDown2",
tags$h3("List of Input"))
)
server <- function(input, output, session){
}
shinyApp(ui = ui, server = server)
Maybe this is a way to go. But unfortunately because of the margin I end up with 2 boxes...
But at least the css style apply only on the first dropdown
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
tags$head(tags$style(HTML('
.test {
display: block;
background-color:red;
left: 200px;
top: 100px;
height: 300px;
width:
} '))),
dropdown(inputId = "MyDropDown1",
tags$h3("List of Input"), class = "test"),
dropdown(inputId = "MyDropDown2",
tags$h3("List of Input"))
)
server <- function(input, output, session){
}
shinyApp(ui = ui, server = server)

Add text on right of shinydashboard header

How do I add text to the right of a dashboard header sidebar icon? It seems that previous similar solutions no longer work under updates to dashboardHeader().
This is what I am trying to do in a basic shinydashboard setting:
I can use the strategy from this answer to get text in the header, but it's right-justified (which I can likely fix custom css) and also feels pretty hacky.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(dashboardHeader(title = "demo",
tags$li(class = "dropdown",
tags$p("foo")
)
), dashboardSidebar(), dashboardBody())
server <- function(input, output) { }
shinyApp(ui, server)
Is there a better way to do this?
The dashboardHeader is expecting elements of type dropdownMenu. So it will be hard to find a not hacky solution. The possible (hacky) options are: a) Modify the dashboardHeader function, or b) use some JavaScript code to add the text after creating the header. Below is my attempt to solve your problem using JavaScript, maybe it could help you.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(
title = "demo"
),
dashboardSidebar(),
dashboardBody(
tags$head(tags$style(HTML(
'.myClass {
font-size: 20px;
line-height: 50px;
text-align: left;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
padding: 0 15px;
overflow: hidden;
color: white;
}
'))),
tags$script(HTML('
$(document).ready(function() {
$("header").find("nav").append(\'<span class="myClass"> Text Here </span>\');
})
'))
)
)
server <- function(input, output) { }
shinyApp(ui, server)
Adding to Geovany & Tiffany's answers, if you'd like the text content to be dynamic, you can have it change based on user input with the shinyjs::html function.
For example, I'm using it to display the name of the selected tab in the header. You can access the selected tab name in the server function as long as you have given the sidebar menu an id, in my case this is tabs.
I also had to add an id to the div that is appended to the header in Geovany's code, in this case pageHeader.
Then adding this to the server function will change the header text to display the selected tab, with switch being used to create a more presentable header format. Note the useShinyJs() in dashboardPage parameters:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(
title = "demo"
),
dashboardSidebar(),
dashboardBody(
tags$head(tags$style(HTML(
'.myClass {
font-size: 20px;
line-height: 50px;
text-align: left;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
padding: 0 15px;
overflow: hidden;
color: white;
}
'))),
tags$script(HTML('
$(document).ready(function() {
$("header").find("nav").append(\'<div id="pageHeader" class="myClass"></div>\');
})
'))
),
useShinyjs()
)
server <- function(input, output) {
observeEvent(input$tabs, {
header <- switch(input$tabs,
tab1 = "Tab 1",
tab2 = "Tab 2",
tab3 = "Tab 3")
# you can use any other dynamic content you like
shinyjs::html("pageHeader", header)
})
}
shinyApp(ui, server)
A slightly modified version of Geovany's code to customize font auto-sizing, placement etc. would be:
ui.R file in directory1 containing:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(
title = "demo"
),
dashboardSidebar(),
dashboardBody(
tags$script(HTML('
$(document).ready(function() {
$("header").find("nav").append(\'<div class="myClass"> Text Here </div>\');
})
')),
tags$head(
# Include our custom CSS
includeCSS("styles.css"),
)
)
)
server.R file in directory1 containing:
library(shiny)
library(shinydashboard)
server <- function(input, output) { }
a css style sheet (style.css in directory1) that controls the text parameters on resizing windows with a defined maximum size and unlimited shrink with the following code:
.myClass {
line-height: 50px;
text-align: center;
font-family: "Arial";
padding: 0 15px;
color: black;
font-size: 2vw;
}
#media (min-width: 1200px) {
.myClass {
line-height: 50px;
text-align: center;
font-family: "Arial";
padding: 0 15px;
color: black;
font-size: x-large
}
}
run using:
shiny::runApp("path to directory1")
Adding the padding properties can be a possible fix. Other options such as width, border and margin can be explored based on your requirements.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(dashboardHeader(title = "demo",
tags$li(class = "dropdown",
style = "padding: 10px 1200px 0px 0px;",
tags$p("foo")
)
), dashboardSidebar(), dashboardBody())
server <- function(input, output) { }
shinyApp(ui, server)
Hope this helps!

Resources