library(shiny) library(tibble) library(DT) # Define the choices for the drop down menu # choices <- c("A", "B", "C") # Define the data table with a column that has drop down menu data <- read.csv("C:/Users/jyang29/Downloads/saved_data.csv") # data$Choice <- sapply(data$Species, function(x) { # as.character(selectInput(paste0("choice_", x), "", choices, selected = x)) # }) ui <- fluidPage( div(id = "dropdown-container"), DTOutput("myDataTable"), actionButton('update', 'Refresh Table'), actionButton("saveBtn", "Save as CSV"), # tags$script(src = "www/custom.js") ) server <- function(input, output, session) { # Reactive values to store the data rv <- reactiveValues(data = data) # Render the DataTable output$myDataTable <- renderDataTable({ datatable( rv$data, editable = TRUE, escape = FALSE, selection = 'none', options = list( columnDefs = list(list( targets = 5, render = JS( "function(data, type, row, meta) {", " if (type === 'display') {", " var dropdownValue = data;", " var rowIndex = meta.row;", " return '';", " }", " return data;", "}" ) )), # Use JavaScript to make the drop down menu work preDrawCallback = JS( "function() {", " Shiny.unbindAll(this.api().table().node());", "}" ), drawCallback = JS( "function() {", " Shiny.bindAll(this.api().table().node());", "}" ), initComplete = JS( "function(settings, json) {", # " var table = settings.oInstance.api();", # " table.column(5).data().unique().sort().each(function(d, j) {", # " $('.dropdown').eq(j).val(d);", # " });", " $('.dropdown').on('mousedown', function(e) { e.stopPropagation(); });", # " var proxy = new $.fn.dataTable.Api(settings);", " var api = this.api();", # " $('#pageLength').change(function() {", # " api.page.len($(this).val()).draw();", # " pageInfo.pageLength = $(this).val();", # " });", # " api.on('draw.dt', function() {", # " currentPage = api.page()+1;", # " pageLength = api.page.len();", # " console.log('Current Page:', currentPage);", # " console.log('Page Length:', pageLength);", # " });", # " console.log(api);", " $('.dataTables_length select').on('change', function() {", " console.log('RRR');", " currentPage = api.page()+1;", " pageLength = api.page.len();", " console.log('Current Page:', currentPage);", " console.log('Page Length:', pageLength);", " });", " $('#myDataTable').on('change', '.dropdown', function() {", # " $ ('[class=\"dropdown\"]').on ('change', function () {", " var selectedValue = $(this).val();", " var rowIndex = $(this).closest('tr').index();", # " var table = $().dataTables();", # " table.draw(true);", #Check these 2 lines of code!! # " var currentPage = dataTable.page() + 1;", # " var pageLength = dataTable.page.len();", " currentPage = api.page()+1;", " pageLength = api.page.len();", " console.log('Current Page:', currentPage);", " console.log('Page Length:', pageLength);", " console.log(rowIndex);", " console.log(selectedValue);", # " var currentPage = table.page();", # Get current page number # " console.log(proxy);", # " console.log(table);", #" var pageLength = table.page.info().length;", # Get page length " Shiny.setInputValue('myDataTable_cell_edit', {", " row: rowIndex+1+(currentPage-1)*pageLength,", " col: 5,", " value: selectedValue", #" currentPage: currentPage + 1,", #" pageLength: pageLength", " }, {priority: 'event'});", " });", "}" ), buttons = list('copy', 'print', list( extend = 'collection', buttons = c('csv', 'excel', 'pdf'), text = 'Download' )) ), # callback = JS( # "table.rows().every(function(i, tab, row) {", # " var $this = $(this.node());", # " $this.attr('id', this.data()[0]);", # " $this.addClass('shiny-input-container');", # "});", # "Shiny.unbindAll(table.table().node());", # "Shiny.bindAll(table.table().node());" # ) ) }, server = TRUE ) # Observe changes to the DataTable and update reactiveValues accordingly proxy <- dataTableProxy('myDataTable') # observeEvent(input$myDataTable_cell_edit, { # info <- input$myDataTable_cell_edit # str(info) # rv$data[info$row, info$col] <<- info$value # print(head(rv$data, 12)) # }) observeEvent(input$myDataTable_cell_edit, { info <- input$myDataTable_cell_edit str(info) i = info$row j = info$col k = info$value print(i) print(j) print(k) # isolate( # for (m in 1:length(info$row)) { # print(i[m]) # print(j[m]) # print(k[m]) # rv$data[i[m], j[m]] <<- DT::coerceValue(k[m], rv$data[i[m], j[m]]) # } # ) isolate({ rv$data[i, j] <<- DT::coerceValue(k, rv$data[i, j]) }) rv$data <<- editData(rv$data, info) replaceData(proxy, rv$data, resetPaging = FALSE) print(head(rv$data)) # If the edited cell is in the Choice column, update the drop down menu # if (j == 6) { # # rv$data[i, j] <<- as.character(selectInput( # # paste0("choice_", k), "", choices, selected = k # # )) # rv$data[i, j] <<- coerceValue(k, rv$data[i, j]) # } else { # # Otherwise, update the cell value # rv$data[i, j] <<- coerceValue(k, rv$data[i, j]) # } }) # Event reactive to update the data based on the selection df <- eventReactive(input$update, { # tibble(Column1 = c("Item1", "Item2", "Item3"), Column2 = as.character(input$selection1)) input$myDataTable_cell_edit$data }) # Observe changes in the event reactive and update reactiveValues observe({ rv$data <- df() }) # Save the data as CSV observeEvent(input$saveBtn, { print(input) write.csv(rv$data, "C:/Users/jyang29/Downloads/saved_data.csv", row.names = FALSE) }) } shinyApp(ui, server)