If you run the app below, it works fine at the beginning: you can reorder the rows of mtcars
and the order appears in the verbatimTextOutput
. But once you change the data to iris
with the radio button, that does not work anymore.
library(shiny)
library(shinyjqui)
ui <- fluidPage(
radioButtons("radio", "Data", choices = c("mtcars", "iris")),
verbatimTextOutput("rows"),
sortableTableOutput("tbl")
)
server <- function(input, output) {
Dat <- reactive({
if(input[["radio"]] == "mtcars") {
mtcars
} else {
iris
}
})
output[["rows"]] <- renderPrint({ input[["tbl_order"]] })
output[["tbl"]] <- renderTable(Dat(), rownames = TRUE)
}
shinyApp(ui, server)
With the app below, using a renderUI
reacting to the radio button, this is slightly better: this works as expected sometimes.
library(shiny)
library(shinyjqui)
ui <- fluidPage(
radioButtons("radio", "Data", choices = c("mtcars", "iris")),
verbatimTextOutput("rows"),
uiOutput("tblUI")
)
server <- function(input, output) {
Dat <- reactive({
if(input[["radio"]] == "mtcars"){
mtcars
}else{
iris
}
})
output[["rows"]] <- renderPrint({input[["tbl_order"]]})
output[["tbl"]] <- renderTable(Dat(), rownames = TRUE)
output[["tblUI"]] <- renderUI({
Dat()
sortableTableOutput("tbl")
})
}
shinyApp(ui, server)
What can we do to get an app which correctly works? Maybe an alternative to shinyjqui::sortableTabbleOutput
?
You are close, but a little more needs to be done. This will work:
library(shiny)
library(shinyjqui)
ui <- fluidPage(
radioButtons("radio", "Data", choices = c("mtcars", "iris")),
verbatimTextOutput("rows"),
uiOutput("tblUI")
)
server <- function(input, output) {
Dat <- reactive({
if(input[["radio"]] == "mtcars"){
tbl_id(0)
mtcars
}else{
tbl_id(1)
iris
}
})
tbl_id <- reactiveVal(0)
output[["rows"]] <- renderPrint({input[[paste0("tbl", tbl_id(), "_order")]]})
observe({
output[[paste0("tbl", tbl_id())]] <- renderTable(Dat(), rownames = TRUE)
})
output[["tblUI"]] <- renderUI({
Dat()
sortableTableOutput(paste0("tbl", tbl_id()))
})
}
shinyApp(ui, server)
Let me explain why.
sortableTableOutput
function, you can see there is some JS code that will be run. The script binds the table to a sortable event and binds to shiny. Not entirely sure how jqui sets shiny input, but from this $.map(idx ...
I guess the listener is added to each row element.shinyjqui.msgCallback({"ui":"[id='tbl']"
. This is the same ID as the old table. Both tables' rows are pointing to the same ID, so ID conflicting usually causes trouble. This is my guess why it gives you NULL
.destroy
option you suggested will not work, because the sortable is applied on each row, you would need to apply nrow
times of destroy, and it cannot avoid the ID conflict problem.I think this is a critical feature that this package is missing. I would recommend filing an issue on Github.