编辑后的数据表行焦点

datatable row focus after editing

我在一个闪亮的应用程序中使用数据tables 包并且它运行良好,但是当我编辑 cell/value 时,焦点从当前行变为第一行。 table 很长,因此必须滚动回正在编辑的行是一个问题。有没有办法选择某一行?然后我可以 return 到 table 重新加载后正在编辑的行。

这是数据table 闪亮渲染的代码。有什么建议吗?

output$book_table <- DT::renderDT(RVTables$book %>% 
                                  filter(deal == as.numeric(input$deal_choice)),
                                  selection = 'single',
                                  editable = TRUE,
                                  rownames = FALSE,
                                  options = list(
                                  autoWidth = TRUE,
                                  ordering = FALSE,
                                  pageLength = 12,
                                  scrollX = TRUE,
                                  scrollY = TRUE,
                                  bLengthChange = FALSE,
                                  searching = FALSE
                                  )
)

编辑:

我找到了一种选择行的方法,但我无法动态更新它。

row_edit<-3
    output$book_table <- DT::renderDT(RVTables$book %>% 
                                      filter(deal == as.numeric(input$deal_choice)),
                                      selection = list(mode='single',selected=row_edit)
                                      editable = TRUE,
                                      rownames = FALSE,
                                      options = list(
                                      autoWidth = TRUE,
                                      ordering = FALSE,
                                      pageLength = 12,
                                      scrollX = TRUE,
                                      scrollY = TRUE,
                                      bLengthChange = FALSE,
                                      searching = FALSE
                                      )
    )

在编辑事件中使用全局分配也没有用:

row_edit<<- 22

编辑
这是一个示例应用程序,用于展示我正在尝试做的事情。 例如编辑第 42 行,看看突出显示的下一行如何回到第一页,如果您想多次编辑单个值以查看效果,这很烦人。

library(shiny)
library(shinyjs)
library(tidyverse)
library(DT) #load after shiny

data_input <- data.frame(ID=seq(1,50),
                   weight=sample(50:65,50,replace = TRUE),
                   height=sample(150:225,50,replace = TRUE)
)

#shiny---
shinyApp(

  #ui----
  ui= fluidPage(
    fluidRow(
      br(),
      column(2,
             actionButton("increase_weight","increase weight"),
             uiOutput("show_row_selected"),
             uiOutput("last_row_selected")
      ),
      column(4,DT::DTOutput("data_table"))

    )
  ),


  server=function(input,output,session){

    #save data frame as a reactive value
    RV <- reactiveValues(
      data=data_input
    )

    #try to save last row selected----
    row_select <- reactive({

      #case when code below fails, use row 3 to illustrate code
      3

      #uncomment code below and run to see error
      # case_when(
      #   #valid row selected
      #   length(input$data_table_rows_selected)>0 ~ as.numeric(input$data_table_rows_selected),
      #   #after update, row object is empty to use last selected row
      #   #this is now recursive and app fails - "evaluation nested too deeply: infinite recursion...."
      #   length(input$data_table_rows_selected)==0 ~ row_select()
      # )

    })

    #render data frame for output
        output$data_table <-  DT::renderDT(RV$data,
                                       selection = list(mode="single",selected=row_select()),
                                       editable = TRUE,
                                       rownames = FALSE,
                                       options=list(
                                         autoWidth=TRUE,
                                         scrollX = TRUE,
                                         ordering=FALSE,
                                         pageLength=12,
                                         scrollY = TRUE,
                                         bLengthChange= FALSE,
                                         searching=FALSE
                                       )
    )

        #edit a single cell----
        observeEvent(input$data_table_cell_edit, {
          info <-  input$data_table_cell_edit
          edit_row <-  info$row
          edit_col <-  info$col+1    # column index offset by 1
          edit_value <-  info$value

          #find leg to be edited
          ID <- edit_row
          RV$data[ID,edit_col] <-as.numeric(edit_value)

        })


        #increase weight by one----
        observeEvent(input$increase_weight, {
          edit_row <- input$data_table_rows_selected

          RV$data[edit_row,"weight"] <- RV$data[edit_row,"weight"]+1
        })

        #show current row selected----
        output$show_row_selected <- renderText({
          paste0("row selected:  ",as.character(as.numeric(input$data_table_rows_selected)))
        })

        #show last row selected----
        output$last_row_selected <- renderText({
          paste0("row selected:  ",as.character(row_select()))
        })

  })

问题的帮助下,这里有一些有效的代码。

library(shiny)
library(shinyjs)
library(tidyverse)
library(DT) #load after shiny

data_input <- data.frame(ID=seq(1,50),
                         weight=sample(50:65,50,replace = TRUE),
                         height=sample(150:225,50,replace = TRUE)
)

#shiny---
shinyApp(

  #ui----
  ui= fluidPage(
    fluidRow(
      br(),
      column(2,
             actionButton("increase_weight","increase weight"),
             uiOutput("show_row_selected")
      ),
      column(4,DT::DTOutput("data_table"))
    )
  ),


  server=function(input,output,session){

    #save data frame as a reactive value
    RV <- reactiveValues(
      data=data_input
    )
    previousSelection <- NULL
    previousPage <- NULL

    #render data table
    output$data_table <- DT::renderDataTable({
      DT::datatable(
        RV$data,
        editable = TRUE,
        selection = list(mode = "single", target = "row", selected = previousSelection),
        options = list(
          autoWidth=TRUE,
          scrollX = TRUE,
          pageLength = 10, 
          displayStart = previousPage))
    })


    #edit a single cell----
    observeEvent(input$data_table_cell_edit, {
      info <-  input$data_table_cell_edit
      edit_row <-  info$row
      edit_col <-  info$col   
      edit_value <-  info$value

      previousSelection <<- input$data_table_rows_selected
      previousPage <<- input$data_table_rows_current[1] - 1

      #find leg to be edited
      RV$data[edit_row,edit_col] <-as.numeric(edit_value)

    })


    #increase weight by one----
    observeEvent(input$increase_weight, {
      edit_row <- input$data_table_rows_selected

      previousSelection <<- input$data_table_rows_selected
      previousPage <<- input$data_table_rows_current[1] - 1

      RV$data[edit_row,"weight"] <- RV$data[edit_row,"weight"]+1
    })

    #show current row selected----
    output$show_row_selected <- renderText({
      paste0("row selected:  ",as.character(as.numeric(input$data_table_rows_selected)))
    })

  })