How to add a custom menu to elements that are dragged and dropped using HTML?

Viewed 49

The reproducible code at the bottom allows the user to drag and drop elements from a menu of items, and replicates the dragged elements in a dataframe while adding a sequential count (using alpha characters) for the number of times the element was dragged-in.

As shown in the images below, is it possible to modify dragged-in elements using a custom menu that pops-up with a right-click of the mouse? How could this be done?

enter image description here

enter image description here

enter image description here

Reproducible code:

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('
      #dragFrom > div {cursor: move; #fallback
                        cursor: grab; cursor: pointer;
                        }
      #dragTo > div {cursor: move; #fallback
                      cursor: grab; cursor: pointer;
                      }                
      #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("A", "B", "C", "D", "E"))
        )
      ),
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Trash bin"),
        div(
          class = "panel-body",
          id = "trash_bin"
        )
      )
    ),
    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") # << solution by stefan on Jun 01, 2022
    )
  ),
  sortable_js(
    "trash_bin",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onAdd = htmlwidgets::JS("function (evt) { this.el.removeChild(evt.item); }")
    )
  ),
  helpText(h5(strong("Output to table:"))),
  tableOutput("table1")
)

server <- function(input, output) {

  dragToLabels <- reactive({
    req(input$selected)
    DT <- data.table(Item = input$selected)
    DT[, c("Nbr", "Class") := .(.I, LETTERS[seq_len(.N)]), by = Item]
    setcolorder(DT, c("Nbr", "Item", "Class"))
  })
  
  output$table1 <- renderTable({dragToLabels()})
  
}

shinyApp(ui, server)
0 Answers
Related