简体   繁体   中英

jquery sortable scroll at edge inside shinydashboard

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可排序滚动在shinydashboard内不起作用

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)

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 here . The sortable options are listed here , from which we find, scroll, scrollSensitivity, scrollSpeed, which are options and sort, which controls the events of sorting.

To do what you want in javaScript is like this:

  $(".sortable").sortable({
    scroll: true,
    scrollSensitivity: 40,
    scrollSpeed: 1,[
    sort: function(event, ui) {
        var currentScrollTop = $(window).scrollTop(),
            topHelper = ui.position.top,
            delta = topHelper - currentScrollTop;
        setTimeout(function() {
            $(window).scrollTop(currentScrollTop + delta);
        }, 5);
    }
});

We can define these options in shinyjqui like so:

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

Notice I've simply set the scroll, scrollSpeed and scrollSensitivity as items in a list. The sort requires a function, as can be seen in the function above, as well as in the documentation :

sort( event, ui )

This then gives us the scroll:

在此处输入图像描述

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM