Very similar to this SO question, I would like to move the previous/next arrow buttons. I want to move them so that they inline with dots, and the result should look like this:
Default placement for the arrows in slickR
are to the sides of the carousel (code to produce is below):
According to the linked SO question, in settings
function there is an argument called appendArrows
which allows us to specify which div
should the arrows appear in.
If I inspect the following shiny app, the slickR dots appear in a class called slick-dots
. When I add appendArrows = ".slick-dots"
the existing arrows completely disappear.
Info related to the original, JavaScript-based slick
, (of which 'slickR' is based on, seem to suggest creating a new class and then assigning appendRows
to the new class. However I am trying to add to existing dots class.
My JavaScript/HTML is very limited but I found some helpful resources:
slick-arrow
and slick-dots
withinslick
Shiny app code:
library(shiny)
library(slickR)
ui <- fluidPage(
slickROutput("slickr_test", width = "95%")
)
server <- function(input, output) {
output$slickr_test <- renderSlickR({
slickR(
obj = c(
"https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg",
"https://upload.wikimedia.org/wikipedia/commons/0/09/Flag_of_South_Korea.svg",
"https://upload.wikimedia.org/wikipedia/commons/6/69/Flag_of_Monaco_%28state%29.svg"
)
) +
settings(
dots = TRUE
# ,appendArrows = ".slick-dots"
)
})
}
shinyApp(ui = ui, server = server)
UPD following @Tim's answer.
Using Tim's normal arrow code, and with the inclusion of a DT Datatable, there seems to be multiple arrows introduced:
library(shiny)
library(slickR)
ui <- fluidPage(
tags$head(
tags$style(HTML("
.slick-pager {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
}
.slick-prev, .slick-next {
position: relative;
display: inline-block;
margin: 0px 30px; /* adjust distance between buttons and dots in second margin*/
}
.slick-dots {
bottom: 9px; /* slight height adjust to make dots align with buttons*/
}
ul.slick-dots { /* this is the div that wraps the dots, we need to paint it black */
background: black;
width: 160px;
}
.slick-dots li button:before {
color: white; /* Inactive dots */
opacity: 1;
font-size: 12px; /* change dot size! */
}
.slick-dots li.slick-active button:before {
color: orange; /* Active dot */
opacity: 1;
font-size: 12px; /* change dot size! */
}
/* Style the previous and next buttons */
.slick-prev, .slick-next {
background-color: black; /* Black background */
color: white; /* White arrow */
}
.slick-next:before, .slick-prev:before{
color:white !important;
opacity: 1;
}
"))
),
slickROutput("slickr_test", width = "95%"),
tags$script(HTML("
$(document).on('shiny:value', function(event) {
setTimeout(function() {
$('.slick-dots').wrap('<div class=\"slick-pager\"></div>');
$('.slick-prev, .slick-next').appendTo('.slick-pager');
}, 10);
});
")),
DTOutput("iris_dt")
)
server <- function(input, output) {
output$slickr_test <- renderSlickR({
slickR(
obj = c(
"https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg",
"https://upload.wikimedia.org/wikipedia/commons/0/09/Flag_of_South_Korea.svg",
"https://upload.wikimedia.org/wikipedia/commons/6/69/Flag_of_Monaco_%28state%29.svg"
)
) +
settings(
dots = TRUE
)
})
output$iris_dt <- renderDT({iris})
}
shinyApp(ui = ui, server = server)
It seems like when there is a DTOutput
, the slick-pager
HTML code gets nested inside another slick-pager
. And while the arrows are floating over DT for this example - preventing the arrows from being clicked, in my own they are between images and DT. In my own code (since I can click on the arrows), there are even more arrows as the carousel is swiped forward.
In my own code, the arrows look like this before carousel is swiped:
This comes fairly close to your requirement.
If you add a DTOutput below the carousel, the dots will overlap the table by default. I added some margins to create some space between the dots and the table. Also Im now placing the prev- & next buttons inside the .slick-dots
div.
library(shiny)
library(slickR)
library(DT)
ui <- fluidPage(
tags$head(
tags$style(HTML("
.slick-prev, .slick-next {
margin: 0px 30px; /* adjust distance between buttons and dots in second margin*/
/* position: relative; */
display: inline-block;
margin: 0px 30px;
}
.slick-dots {
position: relative;
bottom: 30px;
}
ul.slick-dots { /* this is the div that wraps the dots, we need to paint it black */
background: black;
width: 160px;
}
.slick-dots li button:before {
color: white; /* Inactive dots */
opacity: 1;
font-size: 12px; /* change dot size! */
}
.slick-dots li.slick-active button:before {
color: orange; /* Active dot */
opacity: 1;
font-size: 12px; /* change dot size! */
}
/* Style the previous and next buttons */
.slick-prev, .slick-next {
background-color: black; /* Black background */
color: white; /* White arrow */
}
.slick-next:before, .slick-prev:before{
color:white !important;
opacity: 1;
}
.dataTables_wrapper {
position: relative;
clear: both;
margin-top: 250px;
}
"))
),
slickROutput("slickr_test", width = "95%"),
tags$script(HTML("
$(document).on('shiny:value', function(event) {
setTimeout(function() {
$('.slick-prev, .slick-next').appendTo('.slick-dots');
}, 10);
});
")),
DTOutput("iris_dt")
)
server <- function(input, output) {
output$slickr_test <- renderSlickR({
slickR(
obj = c(
"https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg",
"https://upload.wikimedia.org/wikipedia/commons/0/09/Flag_of_South_Korea.svg",
"https://upload.wikimedia.org/wikipedia/commons/6/69/Flag_of_Monaco_%28state%29.svg"
)
) +
settings(
dots = TRUE
)
})
output$iris_dt <- renderDT({iris})
}
shinyApp(ui = ui, server = server)
F12
to open the Developer console.CTRL+Shift+C
and then hover your mouse over div elements you want to inspect.