1

The slickR package has a focusOnSelect option - when clicking on an image in the carousel, it is highlighted. How can I access the selection event to use in R Shiny to trigger other actions? Specifically, I want to click on an image and have it update a textbox with the image name.

To use the example below, put 3 images (image1.jpg, image2.jpg, image3.jpg) in the same directory as the app.

library(shiny)

ui <- shiny::basicPage(

  slickROutput("my_slick",width='100%',height='200px')

)

server <- function(input, output) {

  output$my_slick <- renderSlickR({
      my_images <- c("image1.jpg", "image2.jpg", "image3.jpg")
      slickR(
        my_images,
        slideId = 'slick_images',
        width='90%'
      )
  })

}

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
Vlad
  • 3,058
  • 4
  • 25
  • 53
  • Please see the [slickR vignette](https://cran.r-project.org/web/packages/slickR/vignettes/shiny.html) for the "official" way. – ismirsehregal Feb 12 '21 at 13:48

1 Answers1

3

Is it what you want ?

library(shiny)
library(slickR)

my_images <- c("image1.png", "image2.png", "image3.png")

ui <- shiny::basicPage(

  slickROutput("my_slick",width='100%',height='200px'), 

  tags$p(id="textbox"),

  tags$script('var my_images = ["image1.png","image2.png","image3.png"];
              $("#my_slick").on("click", function(e){ 
                var slideClicked = $(this).find(".slick-active").attr("data-slick-index"); 
                document.getElementById("textbox").innerHTML = "Selected image: " + my_images[slideClicked];
              });')
)

server <- function(input, output) {

  output$my_slick <- renderSlickR({
    slickR(
      my_images,
      slideId = 'slick_images',
      width='90%'
    )
  })    
}

shinyApp(ui, server)

enter image description here

If you want to get the name of the selected image in Shiny, add a line in the script:

  tags$script('var my_images = ["image1.png","image2.png","image3.png"];
              $("#my_slick").on("click", function(e){ 
                var slideClicked = $(this).find(".slick-active").attr("data-slick-index"); 
                Shiny.setInputValue("selectedImage", my_images[slideClicked]); 
                document.getElementById("textbox").innerHTML = "Selected image: " + my_images[slideClicked];
              });')

Then the names of the selected image is in input$selectedImage.

EDIT

Here is the script for the improvements asked by the OP in a comment:

  tags$script('var my_images = ["image1.png","image2.png","image3.png"];
              var binary = true;
              $("#my_slick").on("click", function(e){ 
                if(e.target.localName == "img"){
                  if(binary){
                    var slideClicked = $(this).find(".slick-active").attr("data-slick-index"); 
                    Shiny.setInputValue("selectedImage", my_images[slideClicked]); 
                    document.getElementById("textbox").innerHTML = "Selected image: " + my_images[slideClicked];
                  }else{
                    document.getElementById("textbox").innerHTML = "";
                  }
                  binary = false;
                }else{
                  document.getElementById("textbox").innerHTML = "";
                  binary = true;
                }
              });')
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Learned a lot, it is almost what I want - is there a way to avoid having the arrows and dots trigger the event, so it is only clicking on the image. Also, is it possible if image is clicked twice then the text box becomes blank representing image is deselected. – Vlad Nov 18 '18 at 00:46
  • The EDIT does what I specified. Then I realised I'd like to toggle the text box on and off any number of times (not just once). This was easy enough by removing the `binary = false;` line and adding `binary = true;` and `binary = false;` into the previous if clauses. – Vlad Nov 18 '18 at 12:28
  • 2
    @Vlad, nice. I've just realised something. If you want to use the selected image in the shiny server, you have to add some `Shiny.setInputValue` in order to catch the cases when no image is selected. That is, add `Shiny.setInputValue("selectedImage", null)` each time you do `document.getElementById("textbox").innerHTML = ""`. – Stéphane Laurent Nov 19 '18 at 09:38