0

The below reproducible code works fine for dragging elements from one panel to another, and in the "Drag to" panel automatically, using HTML/CSS, rank order numbering each element dragged in.

However, I'm now trying to append to the end of each "Drag to" list element (using some form of paste0(...) I assume) the alphabetic equivalent of the number of times that element appears in the "Drag to" list, as illustrated at the bottom. How can this done?

Reproducible code:

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

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

ui <- fluidPage(
  
  tags$head(
    tags$style(HTML('
      #dragTo {list-style-type: none;  counter-reset: css-counter 0;}
      #dragTo > div {counter-increment: css-counter 1;}
      #dragTo > div:before {content: counter(css-counter) ". ";}
      ')
    )
  ),
  
  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 = "dragFrom",
          icons(c("Puppies", "Kittens"))
        )
      ),
    ),
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag to here"),
        div(
          class = "panel-body",
          id = "dragTo"
        )
      )
    )
  ),
  sortable_js(
    "dragFrom",
    options = sortable_options(
      group = list(
        pull = "clone",
        name = "group1",
        put = FALSE
      )
    )
  ),
  sortable_js(
    "dragTo",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onSort = sortable_js_capture_input(input_id = "selected")
    )
  ),
  helpText(h5(strong("Output to table:"))),
  tableOutput("table1")
)

server <- function(input, output) {
  dragToLabels <- reactive({
    data.frame(data = paste0(seq_along(input$selected), ". ", input$selected))
  })
  
  output$table1 <- renderTable({dragToLabels()})
}

shinyApp(ui, server)

Illustration:

enter image description here

1 Answers1

1

A first draft using data.table:

library(shiny)
library(sortable)
library(htmlwidgets)
library(data.table)

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

ui <- fluidPage(
  
  tags$head(
    tags$style(HTML('
      #dragTo {list-style-type: none;  counter-reset: css-counter 0;}
      #dragTo > div {counter-increment: css-counter 1;}
      #dragTo > div:before {content: counter(css-counter) ". ";}
      ')
    )
  ),
  
  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 = "dragFrom",
          icons(c("Puppies", "Kittens"))
        )
      ),
    ),
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag to here"),
        div(
          class = "panel-body",
          id = "dragTo"
        )
      )
    )
  ),
  sortable_js(
    "dragFrom",
    options = sortable_options(
      group = list(
        pull = "clone",
        name = "group1",
        put = FALSE
      )
    )
  ),
  sortable_js(
    "dragTo",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onSort = sortable_js_capture_input(input_id = "selected")
    )
  ),
  helpText(h5(strong("Output to table:"))),
  tableOutput("table1")
)

server <- function(input, output) {
  dragToLabels <- reactive({
    # browser()
    # DT <- data.table(data = paste0(seq_along(input$selected), ". ", input$selected))
    req(input$selected)
    DT <- data.table(item = input$selected)
    DT[, c("rownumber", "letter") := .(.I, LETTERS[seq_len(.N)]), by = item]
    setcolorder(DT, c("rownumber", "item", "letter"))
    # DT[, data := paste0(rownumber, ". ", item, " ", letter)][, c("rownumber", "item", "letter") := NULL] # paste to a single column
  })
  
  output$table1 <- renderTable({dragToLabels()})
}

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • I've wrestled a bit with the question, as I carry this sortable section further, whether or not to mush the elements together ( (1. Puppies A) for example as my OP proposes) or to separate the elements the way your data table approach does. Probably your way, as your solution shows me the benefit. However is there a way to mush the elements together in that upper right "Drag to" panel? I figure that takes some fancy HTML/CSS, or can that html div() part for the upper right panel take as input what data table is assigning for A/B/C? – Curious Jorge - user9788072 Jun 02 '22 at 15:13