0

I am trying to make an editable table in shiny, and would like the end user to be able to select from a dropdown list for one of the columns.

Below is a working example of an editable datatable, where the columns competitor_brand and ratio may be edited. For ratio column, it is fine as is. But, I would like for the only possible inputs for the competitor_brand column to be the list of unique(input_data$Brand)

I have had a look around for code but struggling to find what I need

Many thanks! (Apologies if I have missed some info, I am a noob)

### Libraries
library(shiny)
library(dplyr)
library(DT)

### Data
input_data <- data.frame(Brand = c("Brand1", "Brand2","Brand3"),
                         competitor_brand = c("Brand1", "Brand2","Brand3"),
                         ratio = c (.5, .5, .5),
                         cost = c(2000, 3000, 4000),
                         stringsAsFactors = FALSE) 




### Module
modFunction <- function(input, output, session, data,reset) {
    
    v <- reactiveValues(data = data)
    
    proxy = dataTableProxy("mod_table")
    
    observeEvent(input$mod_table_cell_edit, {
        print(names(v$data))
        info = input$mod_table_cell_edit
        str(info)
        i = info$row
        j = info$col
        k = info$value
        str(info)
        
        isolate(
            if (j %in% match(c("competitor_brand","ratio"), names(v$data))) {
                print(match(c("competitor_brand", "ratio"), names(v$data)))
                v$data[i, j] <<- DT::coerceValue(k, v$data[i, j])
                print(v$data)
                
                           } else {
                stop("You are not supposed to change this column.") # check to stop the user from editing only few columns
            }
        )
        replaceData(proxy, v$data, resetPaging = FALSE)  # replaces data displayed by the updated table
    })
    
    ### Reset Table
    observeEvent(reset(), {
        v$data <- data # your default data
    })
    
    print(isolate(colnames(v$data)))
    output$mod_table <- DT::renderDataTable({
        DT::datatable(v$data, editable = TRUE)
        
    })
    
    return(v)
}

modFunctionUI <- function(id) {
    ns <- NS(id)
    DT::dataTableOutput(ns("mod_table"))
    
}

### Shiny App
shinyApp(
    ui = basicPage(
        mainPanel(
            
            actionButton("reset", "Reset"),
            tags$hr(),
            modFunctionUI("editable")
        )
    ),
    server = function(input, output) {
        demodata<-input_data
        edited <- callModule(modFunction,"editable", demodata,
                             reset = reactive(input$reset))
        observe(print(edited$data))
    }
)```
Kit_dr
  • 3
  • 1
  • Could you clarify the behavior a bit more? It sounds like you want `competitor_brand` to only contain values that are contained within `input_data$Brand` which appears to be a static data frame. Is that correct? If one edits `competitor_brand` from "Brand1" to "Brand5" - then "Brand5" should no longer be visible in the datatable, as not contained in `input_data`? And did you want a separate `inputSelect` to filter the datatable as well? Perhaps provide another example if I'm off on this. – Ben Jan 02 '21 at 14:19
  • I would like the user to be able to change the ```competitor_brand``` value to any of the static values in within ```input_data$Brand``` using a dropdown. Given this working example, the user should not be able to edit ```competitor_brand``` to "Brand 5" as the only values possible should be "Brand 1", "Brand 2", or "Brand 3". No additional filters needed - but I also need to retain the print function for edited$data (the last line) - does that make more sense? Happy to clarify more! – Kit_dr Jan 02 '21 at 15:13
  • Take a look at [this post](https://stackoverflow.com/questions/57215607/render-dropdown-for-single-column-in-dt-shiny) - does this have the functionality you are looking for? – Ben Jan 02 '21 at 16:53
  • Sort of, but I think I would have needed to modify the javascript code, and I have zero knowledge of js! I have managed to do what I needed using the rhandsontable package at https://jrowen.github.io/rhandsontable/#dropdown__autocomplete – Kit_dr Jan 03 '21 at 10:05

0 Answers0