This is a good example use case that we missed.
To achieve "independently working" sortable items, we need to move them out of a single renderUI statement.
To link the independent rank_lists, we can use sortable_options(group = "GROUP") in the rank_list definitions. (We can think of bucket lists as rank lists that share the same group value.). See https://rstudio.github.io/sortable/reference/sortable_options.html for more details.
I've updated the code to add the grouped rank_lists above the broken bucket_list. The extra div containers were needed to make the grouped rank_lists appear like a bucket_list.
(I turned the reactiveValues into a set of reactives. Personal preference.)
library(shiny)
library(sortable)
ui <- fluidPage(
tags$head(
tags$style(HTML(".bucket-list-container {min-height: 350px;}"))
),
fluidRow(
column(
width = 12,
#choose list of variable names to send to bucket list
radioButtons(inputId="variableList",
label="Choose your variable list",
choices = c("names(mtcars)"="names(mtcars)","state.name"="state.name")),
#input text to subset variable names
textInput(
inputId = "subsetChooseListText",
label = "Input text to subset list of states to choose from",
value = "c"
),
div(
# class value is current default class value for container
class = "bucket-list-container default-sortable",
"Drag the items in any desired bucket",
div(
# class value is current default class value for list
class = "default-sortable bucket-list bucket-list-horizontal",
# need to make sure the outer div size is respected
# use the current default flex value
uiOutput("selection_list", style="flex:1 0 200px;"),
rank_list(
text = "to here",
labels = list(),
input_id = "rank_list_2",
options = sortable_options(group = "mygroup")
),
rank_list(
text = "and also here",
labels = list(),
input_id = "rank_list_3",
options = sortable_options(group = "mygroup")
)
)
),
uiOutput("dragAndDropList")
)
),
fluidRow(
column(
width = 12,
tags$b("Result"),
column(
width = 12,
tags$p("input$rank_list_1"),
verbatimTextOutput("results_1"),
tags$p("input$rank_list_2"),
verbatimTextOutput("results_2"),
tags$p("input$rank_list_3"),
verbatimTextOutput("results_3")
)
)
)
)
server <- function(input,output) {
#initialize reactive values
varList <- reactive({
req(input$variableList)
if (input$variableList == "state.name") {
state.name
} else {
names(mtcars)
}
})
subsetChooseList <- reactive({
items <- varList()
pattern <- input$subsetChooseListText
if (nchar(pattern) < 1) {
return(items)
}
items[
grepl(
x = items,
pattern = input$subsetChooseListText,
ignore.case = TRUE
)
]
})
output$selection_list <- renderUI({
labels <- subsetChooseList()
# remove already chosen items
labels <- labels[!(
labels %in% input$rank_list_2 |
labels %in% input$rank_list_3
)]
rank_list(
text = "Drag from here",
labels = labels,
input_id = "rank_list_1",
options = sortable_options(group = "mygroup")
)
})
#visual output for debugging
output$results_1 <- renderPrint(input$rank_list_1)
output$results_2 <- renderPrint(input$rank_list_2)
output$results_3 <- renderPrint(input$rank_list_3)
#drag and drop input
output$dragAndDropList <- renderUI({
#bucket list to be output
return(bucket_list(
header = "Broken - Drag the items in any desired bucket",
group_name = "bucket_list_group",
orientation = "horizontal",
add_rank_list(
text = "Drag from here",
labels = subsetChooseList(),
input_id = "rank_list_11"
),
add_rank_list(
text = "to here",
labels = NULL,
input_id = "rank_list_22"
),
add_rank_list(
text = "and also here",
labels = NULL,
input_id = "rank_list_33"
)
)
)
})
}
shinyApp(ui, server)