1
votes

I am making an app with drag and drop feature using the ShinyDND package. I would like to pass a list from input as a parameter of dragSetUI, a function that needs to be run in ui.R. I tried renderUI and uiOutput, and it almost works, but the dragged elements fail to be dropped in the drop area. As you can see in the example below, nonreactive choices work like charm. I tried creating a reactive object as well as text output, but I could not find documentation on how to refer to these objects in ui.R. Normally one would refer to output$x as "x" in Output, but here, if I add anything between quotes, it reads as string. I am really stuck with this.

library(shiny)
library(shinyDND)

nonreactive_choices<-as.list(c("a","b","c"))

ui <- shinyUI(
  mainPanel(
    textInput("choices","Put here a,b,c:"),
  dragSetUI("drag", textval = "reactive_choices"),
  dragSetUI("drag", textval = "choice_rv"),
  textOutput("reactive_choices"),
  dragSetUI("drag", textval = nonreactive_choices),
  dropUI("drop")
  )
)

server = shinyServer(function(input, output,session) {

   output$reactive_choices<-reactive({
     strsplit(input$choices,",")
     })

   observe({
     chlist<-strsplit(input$choices,",")
     choice_rv<-reactiveVal(chlist)
   })

})

# Run the application 
shinyApp(ui = ui, server = server)
2
I would think you would need an update function that includes session information in order to push reactive choices to the ui. This is common for many shiny widgets but does not seem to have been created for the shinyDND package.Chabo
I once implemeted a similar approach using orderInput() from library(shinyjqui). You might want to have a look at it.ismirsehregal

2 Answers

0
votes

Comment by @ismirsehregal helped me find the solution: shinyjqui can be used for my purposes and it seems to work from inside renderUI. Here is the edited code that does exactly what I needed.

library(shiny)
library(shinyjqui)


ui <- fluidPage(
  textInput("choices","Put here a,b,c:"),
  uiOutput("reactiveselect"),
  orderInput(inputId = 'drop', label = 'Reactive drop', items = NULL,placeholder = "drop here..."),
  verbatimTextOutput("droppedorder")
)


server <- function(input, output) {



  output$reactiveselect <- renderUI({
    req(input$choices)
    reactiveitems<- unlist(strsplit(input$choices,","))
    orderInput("groupstochoose", "groups to choose from:", connect='drop',items=reactiveitems)

  })

  output$droppedorder<-
    renderPrint({input$drop_order})

}



shinyApp(ui, server)
0
votes

Let's see why the renderUI approach does not work with shinyDND. An app using shinyDND is linked to the dragndrop.js file, which is in the shinyDND folder. In this file one can see:

$(document).ready(function(){
  ......
  $(".dragelement").on("dragstart",function(e){
    e.originalEvent.dataTransfer.setData("Text",e.target.id);
  });
  ......
});

This defines the action to perform on elements having class dragelement when a drag is starting, and this is defined when the document is ready. dragSetUI creates such elements.

When you use a dragSetUI inside a renderUI, this creates new elements of class dragelement. But the action defined on such elements in $(document).ready is not effective for these new elements, because this action has been defined just after the document is ready, and then before the effect of renderUI.

A solution consists in defining the action of the event dragstart inside the renderUI. This works:

library(shiny)
library(shinyDND)

nonreactive_choices<-as.list(c("a","b","c"))

ui <- shinyUI(
  mainPanel(
    textInput("choices","Put here d,e,f:"),
    dragSetUI("drag", textval = nonreactive_choices),
    uiOutput("dragset"),
    dropUI("drop")
  )
)

server = shinyServer(function(input, output,session) {

  reactive_choices <- reactive({
    strsplit(input$choices,",")[[1]]
  })

  output$dragset <- renderUI({
    tagList(
      dragSetUI("drag2", textval = as.list(reactive_choices())),
      tags$script('$(".dragelement").on("dragstart",function(e){
        e.originalEvent.dataTransfer.setData("Text",e.target.id);
      });'
      )
    )
  }) 
})

# Run the application 
shinyApp(ui = ui, server = server)