0

I am trying to build a shiny application where I am trying to build a functionality similar to below screenshot:-

enter image description here

I have build something similar using Shinyjqui/sortable but I want to allow multi select prior to moving the items. Please let me know if anyone has built/worked on something similar?

Below is an example that I have created using "shinyjqui" package:-

library(shiny)
library(shinyjqui)
attach(mtcars)


ui <- fluidPage(
  fluidRow(
    column(
      width = 12,
      uiOutput("OrderInputRender")
      )
    )
  )

server<- function(input,output){
  output$OrderInputRender <- renderUI({
    fluidRow(
      column(width = 6,
             orderInput(
               "All_Columns",
               width = "100%",
               label = "Available columns",
               items = colnames(mtcars),
               style="margin:5px 0 0 0%; overflow: auto; background-color:#DCDCDC; border: 0px solid; padding: 10px; padding: 10px; height:360px;",
               connect = c("Segment_Column","Channel_Column")##which dropboxes can interact
             )## close of order input
      ),
      column(width = 6,
             orderInput(
               "Channel_Column",
               width = "100%",
               label = "Selected Columns",
               items = NULL,
               style="margin:5px 0 0 0%; overflow: auto; background-color:#DCDCDC; border: 0px solid; padding: 10px; padding: 10px; height:360px;",
               connect = c("All_Columns","Segment_Column")##which dropboxes can interact
             )## close of order input
      )
    )
  })
}

shinyApp(ui, server)
kawsleo
  • 560
  • 4
  • 23
  • 2
    We are always glad to help and support new coders but you need to help yourself first. After [doing more research](https://meta.stackoverflow.com/q/261592/1011527), if you have a problem, please post what you've tried with a clear explanation of what isn't working and provide [a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Read the ['How to Ask a good question' guide](http://stackoverflow.com/help/how-to-ask). Also, be sure to [take the tour](http://stackoverflow.com/tour) and read [this](https://meta.stackoverflow.com/q/347937/1011527) – Rory McCrossan Sep 09 '19 at 12:01
  • 1
    Possible duplicate of [Move items between two list boxes shiny](https://stackoverflow.com/questions/57503861/move-items-between-two-list-boxes-shiny) – ismirsehregal Sep 09 '19 at 12:54
  • Thanks for highlighting....But question is diffrent – kawsleo Sep 09 '19 at 14:48
  • I want to create something with which I can move multiple items between boxes.......I have also mentioned it in the question that Shinyjqui/sortable but That is not a solution.... – kawsleo Sep 09 '19 at 14:49
  • Please let me know if something exactly like screenshot can be created or not? – kawsleo Sep 09 '19 at 14:50
  • @kawsleo It could be created but it may not look exactly like that. Would that be okay? – Shree Sep 09 '19 at 17:34
  • Yes thats totally fine....but I need to have multiple select open...I mean, user should be able to select multiple items and move in a single go – kawsleo Sep 09 '19 at 17:38
  • 1
    @kawsleo I will answer when I get home in 6-7 hours. In the meantime you may want to add a minimal working example to your post to avoid downvotes and closure. At least provide a basic app that people so that others don't have to code from scratch. – Shree Sep 09 '19 at 17:51
  • @Shree- Added the working example...let me know if this works...but the example is based on "shinyjqui" package where drag and drop could provide movable items but multi select is not an option. – kawsleo Sep 09 '19 at 18:42
  • 1
    @kawsleo I can't do drag-n-drop. I can do select/multi-select + arrow. Is that useful? – Shree Sep 09 '19 at 20:47

2 Answers2

3

This is just a proof of concept using DT package. Multiple items can be selected from either side and moved over to the other.

I do not intend to spend time on making this pretty but it should be possible using DT options and css. Lastly, it can be easily reused by packaging in a module.

ui -

library(shiny)
library(DT)

ui <- fluidPage(
  br(),
  splitLayout(cellWidths = c("45%", "10%", "45%"),
    DTOutput("pool"),
    list(
      br(),br(),br(),br(),br(),br(),br(),
      actionButton("add", label = NULL, icon("arrow-right")),
      br(),br(),
      actionButton("remove", label = NULL, icon("arrow-left"))
    ),
    DTOutput("selected")
  )
)

server -

server <- function(input, output, session) {
  mem <- reactiveValues(
    pool = data.frame(LETTERS[1:10]), selected = data.frame()
  )

  observeEvent(input$add, {
    req(input$pool_rows_selected)
    mem$selected <- rbind(isolate(mem$selected), mem$pool[input$pool_rows_selected, , drop = F])
    mem$pool <- isolate(mem$pool[-input$pool_rows_selected, , drop = F])
  })

  observeEvent(input$remove, {
    req(input$selected_rows_selected)
    mem$pool <- rbind(isolate(mem$pool), mem$selected[input$selected_rows_selected, , drop = F])
    mem$selected <- isolate(mem$selected[-input$selected_rows_selected, , drop = F])
  })

  output$pool <- renderDT({
    mem$pool
  })

  output$selected <- renderDT({
    mem$selected
  })
}

shinyApp(ui, server)

App Snapshot -

enter image description here

Shree
  • 10,835
  • 1
  • 14
  • 36
  • Oh, God! You are genius! I've been looking exactly for this for days now and even posted a question about something similar (see https://stackoverflow.com/questions/62782414/move-rows-from-one-dt-to-other-dts-using-action-buttons-in-r-shiny). Is it possible to have double arrow buttons as well for moving all from left to right and vice versa? Also, what If I have more tables on the right to move from the left and vice versa (i.e. more extensible? I am eligible to open a bounty in few hours ;) – panman Jul 09 '20 at 13:01
  • And the bounty was started: https://stackoverflow.com/questions/62782414/move-rows-from-one-dt-to-other-dts-using-action-buttons-in-r-shiny – panman Jul 13 '20 at 17:12
1

Sorry for my poor English. I found jQuery Two side select box and I made shiny demo include this scripts. https://www.jqueryscript.net/form/Two-side-Multi-Select-Plugin-with-jQuery-multiselect-js.html

shiny with two side select box jQuery

It seems good but there is one problem that server can't get input values only options selected in right box.

# function for make UI HTML
MultiselectHTML <- function(mylist,myname){
  paste_sum <- ""
  for(i in 1:length(mylist)){
    paste_sum <- paste0(paste_sum,"<option value=",i,">",mylist[i],"</option>")
  }

  # make tag list
  tagList(
    div(
      class = "item_search"
      ,div(class = "row",
           div(class = "col-xs-5",
               tags$select(name="from[]",id=myname,class = "form-control",multiple = "multiple",size = "8"
                           ,HTML(paste_sum)
               )
           )
           ,div(class = "col-xs-2"
                ,tags$button(type = "button",class = "btn btn-primary btn-block",id=paste0(myname,"_undo"),"undo")
                ,tags$button(type = "button",class = "btn btn-block",id=paste0(myname,"_rightAll"),tags$i(class = "glyphicon glyphicon-forward"))
                ,tags$button(type = "button",class = "btn btn-block",id=paste0(myname,"_rightSelected"),tags$i(class = "glyphicon glyphicon-chevron-right"))
                ,tags$button(type = "button",class = "btn btn-block",id=paste0(myname,"_leftSelected"),tags$i(class = "glyphicon glyphicon-chevron-left"))
                ,tags$button(type = "button",class = "btn btn-block",id=paste0(myname,"_leftAll"),tags$i(class = "glyphicon glyphicon-backward"))
                ,tags$button(type = "button",class = "btn btn-warning btn-block",id=paste0(myname,"_redo"),"redo")
           )
           ,div(class = "col-xs-5"
                ,tags$select(name="to[]",id=paste0(myname,"_to"), class="form-control" ,size="8", multiple="multiple")
           )
      )
    )
    ,br()
  )
}

ui <- fluidPage(
  tags$head(includeScript("www/multiselect.js"))
  ,tags$script(HTML(
    'jQuery(document).ready(function($) {
      $("#multiselect1").multiselect({
       search: {
       left: \'<input type="text" name="q" class="form-control" placeholder="Search..." />\',
       right: \'<input type="text" name="q" class="form-control" placeholder="Search..." />\',
       },
       fireSearch: function(value) {
       return value.length >= 1;
       }
       });
       });
     ')
  )
  ,MultiselectHTML(c("a","b","c","d","e"),"multiselect1")
  ,h5("Selected List :")
  ,textOutput("mselect")
)

server <- function(input, output, session) {
  output$mselect <- renderText({input$multiselect1_to})
}

shinyApp(ui = ui,server = server)
Takuro Ikeda
  • 158
  • 6