I'm exploring ways to visualize a mathematical process (a series of sequential computations) and the sortable package may be the answer, with modifications. The below reproducible code is pulled from the basic examples of how to use sortable found online and in its reference manual (with a table output added so I can start manipulating the data frame).
I'm trying to see if there's a way to not deplete the bucket list as the user drags and drops from the left panel (labeled "Pool" in my example) to the right panel (labeled "Pool Ranking" in my example). So looking at the image at the bottom, the user can drag/drop items A, B, C, D, E, as many times as desired. The right "drag to" panel then grows longer than the left "drag from" panel due to the repetition of elements dragged/dropped.
Is this possible in sortable? How can it be done? Or should I be looking at other packages instead?
If I can figure this out, my next step will be to add another "drag from" panel of mathematical formulas to drag to the right of the dragged-to label elements A - E.
Reproducible code:
library(shiny)
library(sortable)
ui <-
fluidPage(
tags$head(tags$style(HTML("
.column_2 {
counter-reset: rank;
}
.column_2 .rank-list-item::before {
counter-increment: rank;
content: counter(rank) '. ';
}
"))),
htmlOutput("rankingForm"),
helpText(h5(strong("Output to table:"))),
tableOutput("table1")
)
server <- function(input, output, session) {
output$rankingForm <- renderUI({
fluidRow(
column(tags$b("Pool Ranking"), width = 12,
bucket_list(header = "Drag to the right from the Pool below to rank.",
group_name = "bucket_list_group", orientation = "horizontal",
add_rank_list("Pool:",
labels = c("A","B","C","D","E"),
input_id = "rank_list_1"
),
add_rank_list("Pool Ranking:", labels = NULL,
input_id = "rank_list_2")
)
)
)
})
output$table1 <- renderTable({input$rank_list_2})
}
shinyApp(ui=ui, server=server)
Through these listed StackOverflow posts and solutions, I arrived at the "Working solution" shown at the bottom:
Related posts:
vladimir_orbucina request at https://github.com/rstudio/sortable/issues/45 and How to pull list elements from HTML/CSS and into an R data frame? and How to make the label in the sortable package add_rank_list function reactive? and Any creative ways to add rank ordering numbering to this simple sortable package example?
And an important link that explains cloning: https://rstudio.github.io/sortable/articles/cloning.html
Working solution:
library(shiny)
library(sortable)
library(htmlwidgets)
icons <- function(x) {lapply(x,function(x){tags$div(tags$strong(x))})}
ui <- fluidPage(
# Below solution provided by I|O on Jun 1, 2022:
tags$head(
tags$style(HTML('
#drag_from > div {cursor: move; #fallback
cursor: grab; cursor: pointer;
}
#drag_to > div {cursor: move; #fallback
cursor: grab; cursor: pointer;
}
#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) ". ";}
')
)
),
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
),
onSort = sortable_js_capture_input(input_id = "selected") # << solution by stefan on Jun 01, 2022
)
),
helpText(h5(strong("Output to table:"))),
tableOutput("table1")
)
server <- function(input, output) {
output$table1 <- renderTable({input$selected})
}
shinyApp(ui, server)