Search code examples
htmlrshinyrankingsortablejs

Any creative ways to add rank ordering numbering to this simple sortable package example?


I am trying to rank order number the list elements in the “Drag to” panel on the right when running the below "Reproducible Code". See image at the bottom for an illustration.

I found an example, Add index to sortable object text in R Sortable, where list elements are rank order numbered using HTML with the same sortable package. However, this example uses sortable's bucket_list() and add_rank_list() and that html snippet only works in conjunction with those functions. For “cloning” reasons I’m using sortable_js() instead of bucket_list() and add_rank_list().

How can I add rank order numbers to those list elements?

Reproducible Code:

library(shiny)
library(sortable)
library(htmlwidgets)

icons <- function(x) {lapply(x,function(x){tags$div(tags$strong(x))})}

ui <- fluidPage(
  
  div(
    style = "margin-top: 2rem; width: 60%; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start;",

    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag from here"),
        div(
          class = "panel-body",
          id = "drag_from",
          icons(c("A", "B", "C", "D", "E"))
        )
      ),
    ),
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag to here"),
        div(
          class = "panel-body",
          id = "drag_to"
        )
      )
    )
  ),
  sortable_js(
    "drag_from",
    options = sortable_options(
      group = list(
        pull = "clone",
        name = "group1",
        put = FALSE
      )
    )
  ),
  sortable_js(
    "drag_to",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onAdd = htmlwidgets::JS() # something that works here to rank order number to each element dragged in?
    )
  ),
)

server <- function(input, output) {}

shinyApp(ui, server)

Illustration:

enter image description here


Solution

  • If you only target the display format, you could include some custom CSS to enumerate the CSS-selected elements like so:

    ui <- fluidPage(
      tags$head(
             tags$style(HTML('
                 #drag_to {list-style-type: none;  counter-reset: css-counter 0;}
                 #drag_to > div {counter-increment: css-counter 1;}
                 #drag_to > div:before {content: counter(css-counter) ". ";}
          ')
          )
          ) ##, etc.
    

    I'd also suggest you choose a cursor style which signals a draggable item (currently you're using one for text input). Add this to above CSS declarations if desired:

        #drag_from > div {cursor: move; #fallback
                          cursor: grab; cursor: -moz-grab;
                          cursor: -webkit-grab;
                          }