Home > Software design >  jquery sortable scroll at edge inside shinydashboard
jquery sortable scroll at edge inside shinydashboard

Time:12-31

I'm using {shinyjqui} R package to create jQuery sortable elements inside {shinydashboard}. When dragging an item to the top or bottom of the window, I want the window to automatically scroll. This is the default jQuery behavior.

I think I need to edit the overflow CSS property, but not sure what the best way to do this is or all the locations that need to be changed and what the implications are for my app.

In the following example, I can create multiple boxes that produce a scrollbar, but when the box is dragged to the edge, the window doesn't scroll.

library(shinydashboard)
library(shiny)
library(shinyjqui)

ui <- dashboardPage(
  header = dashboardHeader(),
  sidebar = dashboardSidebar(), 
  body = dashboardBody(
    actionButton("add", "add"),
    div(id = "lst"),
  ))

server <- function(input, output, session) {
  
  observeEvent(input$add, {
    jqui_sortable("#lst", operation = "destroy")
    
    insertUI(
      selector = "#lst",
      where = "beforeEnd",
      ui = fluidRow(box(title = paste0("test", input$add), h1("test")))
    )
    jqui_sortable("#lst", operation = "enable")
  })
}

shinyApp(ui, server)

jquery sortable scroll not working inside shinydashboard

CodePudding user response:

Setting the overflow property to visible worked for me.

Just add these three lines to the dashboardBody():

 tags$style(HTML('.wrapper { overflow: visible;}')),
 tags$style(HTML('.skin-blue { overflow: visible;}')),
 tags$style(HTML('.content-wrapper { overflow: visible !important;}'))

Full app example:

library(shiny)
library(shinydashboard)
library(shinyjqui)

ui <- dashboardPage(
  header = dashboardHeader(),
  sidebar = dashboardSidebar(), 
  body = dashboardBody(
    tags$style(HTML('.wrapper { overflow: visible;}')),
    tags$style(HTML('.skin-blue { overflow: visible;}')),
    tags$style(HTML('.content-wrapper { overflow: visible !important;}')),
    actionButton("add", "add"),
    div(id = "lst"),
  ))

server <- function(input, output, session) {
  
  observeEvent(input$add, {
    jqui_sortable("#lst", operation = "destroy")
    
    insertUI(
      selector = "#lst",
      where = "beforeEnd",
      ui = fluidRow(box(title = paste0("test", input$add), h1("test")))
    )
    jqui_sortable("#lst", operation = "enable")
  })
}

shinyApp(ui, server)

CodePudding user response:

Your solution works. However, it is also possible to use jQuery UI's power to control that. You can also use the options argument of the jqui_sortable function to control scrolling and much more of the interactions of jQuery Widgets, documented enter image description here

The benefit of this approach is you can enable or disable scroll, control scroll speed, scroll sensitivity (how close to the edge should the scroll start). For instance, with your solution I can disable scrolling by setting scroll = FALSE and it doesn't scroll. There many more interactions not just scrolling, which is what makes jQuery UI so great! I recommend this approach to take full advantage of jQuery UI.

Full App:


library(shiny)
library(shinyjqui)

ui <- dashboardPage(
  header = dashboardHeader(),
  sidebar = dashboardSidebar(), 
  body = dashboardBody(
    actionButton("add", "add"),
    div(id = "lst"),
  ))

server <- function(input, output, session) {
  
  observeEvent(input$add, {
    jqui_sortable("#lst", operation = "destroy")
    
    insertUI(
      selector = "#lst",
      where = "beforeEnd",
      ui = fluidRow(box(title = paste0("test", input$add), h1("test")))
    )
    
    jqui_sortable("#lst", operation = "enable", options = list(
      scroll = TRUE,
      scrollSensitivity = 40,
      scrollSpeed = 1,
      sort = JS('function(event, ui) {
        var currentScrollTop = $(window).scrollTop(),
        topHelper = ui.position.top,
        delta = topHelper - currentScrollTop;
        setTimeout(function() {
          $(window).scrollTop(currentScrollTop   delta);
        }, 5);
      }'))
    )
  })
}

shinyApp(ui, server)

  • Related