Closed tsolloway closed 5 years ago
Hi @tsolloway,
I took a look at the example you provided. Looks like it won't be easy to implement with the orderInput. orderInput generates the divs itself and it won't be possible to include this structure into the datatables at this stage.
If you want to sort elements in a column of a datatable in shiny, you can take a look at following code that I wrote:
library(shiny)
library(purrr)
library(DT)
ui <- shinyUI(
fluidPage(
tags$head(tags$script(src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js")),
h2("Reorder"),
DT::dataTableOutput("mytable")
)
)
moveValue <- function(values, source, target) {
movedValue <- values[source]
values[-source] %>%
append(movedValue, target - 1)
}
server = shinyServer(function(input, output, session) {
data <- reactiveVal(cbind(list(id = c(1, 2, 3, 4, 5, 6)), head(mtcars)))
create_div <- function(value, row, column) {
as.character(
div(`data-row` = row, `data-column` = column, class = "droppable-container",
div(`data-row` = row, `data-column` = column, class = "btn btn-primary draggable-value", style = "cursor: pointer",
value)))
}
html_data <- reactive({
as.data.frame(imap(data(), function(values, column) {
unlist(imap(values, function(value, row) { create_div(value, row, column) }))
}))
})
output$mytable = DT::renderDataTable({
isolate(html_data())
}, server = T, escape = F, selection="none", filter="none", options = list(
dom = "t", ordering=F, paging=F,
preDrawCallback = JS("function() {Shiny.unbindAll(this.api().table().node());}"),
drawCallback = JS('
function() {
Shiny.bindAll(this.api().table().node());
jQuery(".draggable-value").draggable({
revert: "invalid",
cursor: "pointer"
});
jQuery(".droppable-container").droppable({
accept:".draggable-value",
drop: function( event, ui ) {
var data = {
targetColumn: event.target.attributes["data-column"].value,
targetRow: parseInt(event.target.attributes["data-row"].value),
sourceColumn: ui.draggable.attr("data-column"),
sourceRow: parseInt(ui.draggable.attr("data-row"))
}
ui.draggable.css({ top: 0, left: 0 })
Shiny.setInputValue("drag_and_drop_event", data);
}
})
}
')
))
proxy <- DT::dataTableProxy("mytable")
observe({
DT::replaceData(proxy, html_data())
})
observe({
dragAndDropEvent <- input[["drag_and_drop_event"]]
if (!is.null(dragAndDropEvent)) {
if (dragAndDropEvent$targetColumn == dragAndDropEvent$sourceColumn) {
values <- isolate(data())
values[dragAndDropEvent$sourceColumn] <- values[[dragAndDropEvent$sourceColumn]] %>%
moveValue(dragAndDropEvent$sourceRow, dragAndDropEvent$targetRow)
data(values)
}
}
})
})
shinyApp(ui = ui, server = server)
Best, Damian, Appsilon Data Science
Amazing. Thank you so much! Too cool! I'm sorry I was daft by going down a poor solution, but you're too kind leading me to the proper one. Thank you!
Hello,
I'm new to this and am having a problem placing a single orderInput into a DT cell and connecting with other orderInput in cells of the same column. My goal is to make each column cell dragable/sortable within the column. I can't figure out how to connect the orderInputs.
I'm noticing the orderInputs' html within the DT is different from orderInputs I would just generate in the UI. Any guidance on what I'm missing here?
Bests, Tyler