I have been impressed by the slick
javascript library (http://kenwheeler.github.io/slick/) and want to incorporate it into my shiny apps/flexboard pages.
I would like to use the htmlwidgets
package in R incorporate the slick js library, so have started by trying to create a package as is suggested in the online documentation (http://www.htmlwidgets.org/develop_intro.html), by carrying out the following...
devtools::create("slick")
setwd("slick")
htmlwidgets::scaffoldWidget("slick")
I downloaded the js library from https://github.com/kenwheeler/slick/archive/1.6.0.zip
and placed it into the structure of the package so that I have a file structure that looks a bit like this.
R/
| slick.R
inst/
|-- htmlwidgets/
| |-- slick.js
| |-- slick.yaml
| |-- lib/
| | |-- slick-1.6.0/
| | | |-- slick/
| | | | |-- slick.min.js
| | | | |-- slick.js
| | | | |-- slick.css
| | | | |-- slick-theme.css
My slick.yaml
file looks like this...
dependencies:
- name: slick
version: 1.6.0
src: htmlwidgets/lib/slick-1.6.0
script:
- slick/slick.min.js
- slick/slick.js
stylesheet:
- slick/slick.css
- slick/slick-theme.css
But am really stuck as to how to adjust the inst/htmlwidget/slick.js
file and the R/slick.R
file in a way that can take a vector of urls and display them in a shiny app. The reason for this, is that it does not seem to match a similar input data concept as the example provided.
For reproducibility and to use the same URLs that are provided in the examples in the package, I am providing a vector of placeholder img urls that I would like to use as the contents. For each image in the carousel.
image_vec <- paste0("http://placehold.it/350x300?text=",seq(1:9))
Perhaps I might need to use something like this?...
lapply(image_vec,function(y){div(img(src=y))})
As always any help on this would be much appreciated.
EDIT
My new slick.yaml
file looks like the following...after @NicE's answer post...am I missing something?
dependencies:
- name: jquery
version: 3.1.0
src: htmlwidgets/lib
script:
- jquery-3.1.0.min.js
- name: slick
version: 1.6.0
src: htmlwidgets/lib/slick-1.6.0
script:
- slick/slick.min.js
- slick/slick.js
stylesheet:
- slick/slick.css
- slick/slick-theme.css
and now my file structure looks like the following:
R/
| slick.R
inst/
|-- htmlwidgets/
| |-- slick.js
| |-- slick.yaml
| |-- lib/
| | |-- jquery-3.1.0.min.js
| | |-- slick-1.6.0/
| | | |-- slick/
| | | | |-- slick.min.js
| | | | |-- slick.js
| | | | |-- slick.css
| | | | |-- slick-theme.css
and my /inst/htmlwidgets/slick.js
looks like the following
HTMLWidgets.widget({
name: 'slick',
type: 'output',
factory: function(el, width, height) {
// TODO: define shared variables for this instance
// create new slick object witht the given id?
var sl = new slick(el.id);
return {
renderValue: function(x) {
//add class to the div and center it
el.setAttribute("class",x.class);
el.style.margin = "auto";
//add images to the div
content='';
for(var image in x.message)
{
content += '<div><img src="' + x.message[image] + '"/></div>';
}
el.innerHTML = content;
//initialize the slider.
$(document).ready(function(){
$("."+x.class).slick(x.options);
});
},
resize: function(width, height) {
// TODO: code to re-render the widget with a new size
}
};
}
});
Here's an attempt, using htmlwidgets_0.6
:
For the dependencies, the yaml
file looks the same, I just added jQuery above slick
:
dependencies:
- name: jquery
version: 3.1.0
src: htmlwidgets/lib
script:
- jquery-3.1.0.min.js
- name: slick ...
You can get it here and put it in the lib
folder.
In the slick.R
file, you need to change the arguments of the slick
function to add options and change x
to forward all the arguments to the JS code:
slick <- function(message, class="slick_slider", options = list(), width = NULL, height = NULL) {
# forward options using x
x = list(
message = message,
class = class,
options = options
)
...
In the slick.js
, you mainly need to change the renderValue
to add the images/content to the div
and display the carousel:
renderValue: function(x) {
//add class to the div and center it
el.setAttribute("class",x.class)
el.style.margin = "auto";
//add images to the div
content='';
for(var image in x.message)
{
content += '<div><img src="' + x.message[image] + '"/></div>';
}
el.innerHTML = content;
//initialize the slider.
$(document).ready(function(){
$("."+x.class).slick(x.options);
});
}
Once you've installed it using devtools::install()
, you can use it in a shiny
app:
library(shiny)
library(htmlwidgets)
library(slick)
server <- function(input, output) {
output$test_slick <- renderSlick({
slick(paste0("http://placehold.it/350x300?text=",1:9),
options=list(dots=TRUE,autoplay=TRUE))
})
}
ui <- fluidPage(
tags$style(HTML("body {background-color: #2682d5}")),
slickOutput('test_slick',width="350px",height="300px")
)
shinyApp(ui = ui, server = server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With