skip to Main Content

basically, I’m trying to connect the answers of YBS here Shiny app with editable datatable: How can I enable the modification of the table when I use selectInput option? and Stéphane Laurent‘s from here Change backgorund color of cell of data table while its value is edited in Rshiny.

Here I have tried to combine the codes:
so what I want is to keep the changes when I switch between the categories on the left (works now) and that each changed cell is highlighted in color (does not work now).

library(tidyverse)
library(shiny)
library(DT)
library(shinyjs)

js <- HTML(
  "function colorizeCell(i, j){
    var selector = '#dtable tr:nth-child(' + i + ') td:nth-child(' + j + ')';
    $(selector).css({'background-color': 'yellow'});
  }"
)

colorizeCell <- function(i, j){
  sprintf("colorizeCell(%d, %d)", i, j)
}

ui<-fluidPage(  useShinyjs(),
                tags$head(
                  tags$script(js)
                ),
  
                 sidebarLayout(
                   sidebarPanel(width = 3,
                                inputPanel(
                                  selectInput("Species", label = "Choose species",
                                              choices = levels(as.factor(iris$Species)))
                                )),
                   
                   

                   mainPanel( tabsetPanel(
                     tabPanel("Data Table",DTOutput("iris_datatable"),
                             hr()))
                 )
               )

)


server <- function(input, output, session) {
  my_iris <- reactiveValues(df=iris,sub=NULL, sub1=NULL)

  observeEvent(input$Species, {
    my_iris$sub <- my_iris$df %>% filter(Species==input$Species)
    my_iris$sub1 <- my_iris$df %>% filter(Species!=input$Species)
  }, ignoreNULL = FALSE)
  
  output$iris_datatable <- renderDT({
    n <- length(names(my_iris$sub))
    DT::datatable(my_iris$sub,
                  options = list(pageLength = 10),
                  selection='none', editable= list(target = 'cell'), 
                  rownames= FALSE)
  }, server = FALSE)
  # 
  observeEvent(input$iris_datatable_cell_edit,{
    edit <- input$iris_datatable_cell_edit
    i <- edit$row
    j <- edit$col + 1
    v <- edit$value
    runjs(colorizeCell(i, j+1))
    my_iris$sub[i, j] <<- DT::coerceValue(v, my_iris$sub[i, j])

    my_iris$df <<- rbind(my_iris$sub1,my_iris$sub)
  })
  

  
}
shinyApp(ui, server)

2

Answers


  1. In this JavaScript code:

    js <- HTML(
      "function colorizeCell(i, j){
        var selector = '#dtable tr:nth-child(' + i + ') td:nth-child(' + j + ')';
        $(selector).css({'background-color': 'yellow'});
      }"
    )
    

    you can see #dtable. This is the selector of the HTML element with id dtable. But the id of your datatable is not dtable, it is iris_datatable. So you have to do the replacement.

    Login or Signup to reply.
  2. This will work: Remove these two lines:

    my_iris$sub[i, j] <<- DT::coerceValue(v, my_iris$sub[i, j])

    my_iris$df <<- rbind(my_iris$sub1,my_iris$sub)

    and adapt runjs

    library(tidyverse)
    library(shiny)
    library(DT)
    library(shinyjs)
    
    js <- HTML(
      "function colorizeCell(i, j){
        var selector = '#iris_datatable tr:nth-child(' + i + ') td:nth-child(' + j + ')';
        $(selector).css({'background-color': 'yellow'});
      }"
    )
    
    colorizeCell <- function(i, j){
      sprintf("colorizeCell(%d, %d)", i, j)
    }
    
    ui<-fluidPage(  useShinyjs(),
                    tags$head(
                      tags$script(js)
                    ),
                    
                    sidebarLayout(
                      sidebarPanel(width = 3,
                                   inputPanel(
                                     selectInput("Species", label = "Choose species",
                                                 choices = levels(as.factor(iris$Species)))
                                   )),
                      
                      
                      
                      mainPanel( tabsetPanel(
                        tabPanel("Data Table",DTOutput("iris_datatable"),
                                 hr()))
                      )
                    )
                    
    )
    
    
    server <- function(input, output, session) {
      my_iris <- reactiveValues(df=iris,sub=NULL, sub1=NULL)
      
      observeEvent(input$Species, {
        my_iris$sub <- my_iris$df %>% filter(Species==input$Species)
        my_iris$sub1 <- my_iris$df %>% filter(Species!=input$Species)
      }, ignoreNULL = FALSE)
      
      output$iris_datatable <- renderDT({
        n <- length(names(my_iris$sub))
        DT::datatable(my_iris$sub,
                      options = list(pageLength = 10),
                      selection='none', editable= list(target = 'cell'), 
                      rownames= FALSE)
      }, server = FALSE)
      # 
      observeEvent(input$iris_datatable_cell_edit,{
        edit <- input$iris_datatable_cell_edit
        i <- edit$row
        j <- edit$col + 1
        v <- edit$value
        runjs(colorizeCell(i, j))
      })
    }
    shinyApp(ui, server)
    

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search