I wanted to extend solution presented here. This code renders dropdowns with options for last column of the dataset and it works perfectly for static dataset.
When I'm adding new row and re-rendering the table dropdown disappears
though I have callback variable in renderDT
function. Is it possible to have the dropdown for every rendering of the table? What could cause the issue?
Here's my code:
library(shiny)
library(DT)
library(data.table)
callback <- c(
"var id = $(table.table().node()).closest('.datatables').attr('id');",
"$.contextMenu({",
" selector: '#' + id + ' td.factor input[type=text]',",
" trigger: 'hover',",
" build: function($trigger, e){",
" var colindex = table.cell($trigger.parent()[0]).index().column;",
" var coldata = table.column(colindex).data().unique();",
" var options = coldata.reduce(function(result, item, index, array){",
" result[index] = item;",
" return result;",
" }, {});",
" return {",
" autoHide: true,",
" items: {",
" dropdown: {",
" name: 'Edit',",
" type: 'select',",
" options: options,",
" selected: 0",
" }",
" },",
" events: {",
" show: function(opts){",
" opts.$trigger.off('blur');",
" },",
" hide: function(opts){",
" var $this = this;",
" var data = $.contextMenu.getInputValues(opts, $this.data());",
" var $input = opts.$trigger;",
" $input.val(options[data.dropdown]);",
" $input.trigger('change');",
" }",
" }",
" };",
" }",
"});"
)
ui <- fluidPage(
tags$head(
tags$link(
rel = "stylesheet",
href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.css"
),
tags$script(
src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js"
)
),
sidebarLayout(
sidebarPanel(actionButton("add", "Add row"),),
mainPanel(DTOutput("dtable"))
)
)
server <- function(input, output){
output[["dtable"]] <- renderDT({
iris2 <<- iris
datatable(
iris2, editable = "cell", callback = JS(callback),
options = list(
columnDefs = list(
list(
targets = 5, className = "factor"
)
)
)
)
}, server = FALSE)
observeEvent(input$add, {
new.row <- t(rep(NA, ncol(iris2)))
colnames(new.row) <- colnames(iris2)
new.row <- data.table(new.row)
iris2 <<- rbind(new.row,iris2)
output$dtable <- renderDT({
datatable(
iris2, editable = "cell",
callback = JS(callback),
options = list(
columnDefs = list(
list(
targets = 5 , className = "factor"
)
)
)
)
}, server = TRUE)
})
}
shinyApp(ui, server)