javascriptrshinysortablejs

Set default value in a "destination" sortable rank_list group in R Shiny App


I am using the R package sortable in a Shiny App in a similar way as described in this SO post, with the aim of drag-and-dropping values from one "source" rank_list to a "destination" rank_list.

I am facing the following issue : when the app starts, I would like the "destination" rank_list to be already filled with one of the value of the "source" rank_list. This means for the example here below that when the app starts the "Destination" box on the right already contains e.g. the "b" value.

Is it possible to achieve this ? How ? I guess there is probably a js solution, but I am really a newbie...

Thanks in advance for any help

library(shiny)
library(sortable)


ui <- fluidPage(
  
  fluidRow(
    column( 
      width = 6,
      uiOutput("main_rank")
    ),
    column( width =6,
            rank_list(
              text = "Destination",
              labels = c(),
              input_id = "other_rank",
              options = sortable_options(group = "my_shared_group"))
    )
    
    
  ) 
)

server <- function(input,output) {
  
  # Fixed Items as reactive
  rankvars = reactive({
    
    # Fixed Items
    fixedItems = c("a", "b", "c", "d")
    
    # used 
    used = c()
    used = c(unique(input$other_rank))
    
    # refill the list with unique items
    unique(c(setdiff(fixedItems, used),used))
  })
  
  # Make the main rank as a reactive object
  output$main_rank = renderUI({
    fluidRow(
      rank_list(
        text = "Source",
        labels = rankvars(), #colnames(Memory$data), #sample(paste0("list item ", 1:5)),
        input_id = "main_list",
        # be sure to have the same group name
        options = sortable_options(group = "my_shared_group")
      ) 
      
    )
    
  })
  
  
}

shinyApp(ui, server)

Solution

  • TL;DR I added a new solution and the one you asked for.

    In my opinion, the original question misleads you as there is a bucket function in the sortable package designed for such usage.

    The example but with sortable::bucket_list

    library(shiny)
    library(sortable)
    
    
    ui <- fluidPage(
      
      fluidRow(
        column( width = 12,
                bucket_list(
                  header = "Drag the items in any desired bucket",
                  group_name = "bucket_list_group",
                  orientation = "horizontal",
                  add_rank_list(
                    text = "Drag from here",
                    labels = list(
                      "a",
                      "b",
                      "c",
                      "d"
                    ),
                    input_id = "rank_list_1"
                  ),
                  add_rank_list(
                    text = "to here",
                    labels = list("e"),
                    input_id = "rank_list_2"
                  )
                )
        )
        
        
      ) 
    )
    
    server <- function(input,output) {
      
      # Fixed Items as reactive
      rankvars = reactive({
        
        # Fixed Items
        fixedItems = c("a", "b", "c", "d")
        
        # used 
        used = c()
        used = c(unique(input$other_rank))
        
        # refill the list with unique items
        unique(c(setdiff(fixedItems, used),used))
      })
      
      
      
    }
    
    shinyApp(ui, server)
    

    JS code to add an e element. The idea is to manually add a div with the rank-list-item class when the container is there.

    library(shiny)
    library(sortable)
    
    
    ui <- fluidPage(
      shinyjs::useShinyjs(),
      fluidRow(
        column( 
          width = 6,
          uiOutput("main_rank")
        ),
        column( width =6,
                rank_list(
                  text = "Destination",
                  labels = c(),
                  input_id = "other_rank",
                  options = sortable_options(group = "my_shared_group"))
        )
        
        
      ) 
    )
    
    server <- function(input,output) {
      
      # Fixed Items as reactive
      rankvars = reactive({
        # Fixed Items
        fixedItems = c("a", "b", "c", "d")
        
        # used 
        used = c()
        used = c(unique(input$other_rank))
        
        # refill the list with unique items
        unique(c(setdiff(fixedItems, used),used))
      })
      
      # Make the main rank as a reactive object
      output$main_rank = renderUI({
        fluidRow(
          rank_list(
            text = "Source",
            labels = rankvars(), #colnames(Memory$data), #sample(paste0("list item ", 1:5)),
            input_id = "main_list",
            # be sure to have the same group name
            options = sortable_options(group = "my_shared_group")
          ) 
          
        )
        
      })
      
      shiny::observeEvent(input$other_rank, {
        shinyjs::runjs('$("#other_rank").append("<div class=\'rank-list-item\'>e</div>")')
      })
    }
    
    shinyApp(ui, server)