Search code examples
rshinyslick.jsslickr

R Shiny: slickR select event


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)

Solution

  • 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;
                    }
                  });')