简体   繁体   English

R Shiny - 动态显示/隐藏可编辑的数据表

[英]R Shiny - Dynamically show/hide editable datatables

I want to create a tabsetPanel that displays a selection of dataframes based on a selectizeInput , while also allowing for permanent edits of the data.我想创建一个tabsetPanel来显示基于selectizeInput的数据selectizeInput ,同时还允许对数据进行永久编辑。 I use editable DataTables to render the dataframes but couldn't find a way to save the edits.我使用可编辑的DataTables来呈现数据框,但找不到保存编辑的方法。 This example code illustrates my problem:此示例代码说明了我的问题:

library(shiny)
library(shinyWidgets)
library(shinyjs)
library(DT)

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            selectizeInput(inputId = "dataframes", label = "select dataframes", 
                           choices = c("iris", "mtcars", "DNase", "ChickWeight"), multiple = TRUE, options = list(create = T))
        ),
        mainPanel(
            uiOutput("dataframes_rendered")
        )
    )
)

server <- function(input, output) {
    output$dataframes_rendered =  renderUI({
        # create one tab per df
        tabs = lapply(input$dataframes, function(df){
            output[[df]] = DT::renderDT(get(df), editable = T, rownames = F, options = list(dom = "t"))
            tabPanel(title = df, value = NULL, dataTableOutput(outputId = df), br())
        })

        # create tabsetPanel
        do.call(tabsetPanel, c(tabs, id = "df_tabset"))
    })
}

shinyApp(ui = ui, server = server)

I understand why the edits are not saved in my example (the dataframes are re-rendered with every change in the selectizeInput) but, so far, everything I tried to to save the edits and re-render the editeed tables did not work.我理解为什么我的示例中没有保存编辑(数据框会随着 selectizeInput 中的每次更改而重新呈现),但到目前为止,我试图保存编辑并重新呈现已编辑表的所有内容都不起作用。

Please try the below:请尝试以下操作:

library(shiny)
library(shinyWidgets)
library(shinyjs)
library(DT)

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            selectizeInput(inputId = "dataframes", label = "select dataframes", 
                           choices = c("iris", "mtcars", "DNase", "ChickWeight"), multiple = TRUE, options = list(create = T))
        ),
        mainPanel(
            tabsetPanel(id = "df_tabset")
        )
    )
)

server <- function(input, output, session) {

    tables <- reactiveValues(
        iris = iris,
        mtcars = mtcars,
        DNase = DNase,
        ChickWeight = ChickWeight,
        df_tabset = NULL
    )

    observeEvent(input$dataframes, {
        if (length(input$dataframes) > length(tables$df_tabset)) {
            df = input$dataframes[! input$dataframes %in% tables$df_tabset]
            output[[df]] = renderDT(tables[[df]], editable = T, rownames = F, options = list(dom = "t"))
            appendTab(inputId = "df_tabset", select = TRUE,
                      tabPanel(title = df, value = df, DTOutput(outputId = df))
            )
            tables$df_tabset = input$dataframes
        } else {
            df = tables$df_tabset[! tables$df_tabset %in% input$dataframes]
            removeTab(inputId = "df_tabset", target = df)
            tables$df_tabset = input$dataframes
        }

    }, ignoreNULL = FALSE, ignoreInit = TRUE)

    observeEvent(input$iris_cell_edit, {
        tables$iris[input$iris_cell_edit$row, input$iris_cell_edit$col + 1] = input$iris_cell_edit$value
    })

    observeEvent(input$mtcars_cell_edit, {
        tables$mtcars[input$mtcars_cell_edit$row, input$mtcars_cell_edit$col + 1] = input$mtcars_cell_edit$value
    })

    observeEvent(input$DNase_cell_edit, {
        tables$DNase[input$DNase_cell_edit$row, input$DNase_cell_edit$col + 1] = input$DNase_cell_edit$value
    })

    observeEvent(input$ChickWeight_cell_edit, {
        tables$ChickWeight[input$ChickWeight_cell_edit$row, input$ChickWeight_cell_edit$col + 1] = input$ChickWeight_cell_edit$value
    })

}

shinyApp(ui = ui, server = server)

I also made a change to your code by adding and removing tabs rather than rerendering all of them each time.我还通过添加和删除选项卡而不是每次重新呈现所有选项卡对您的代码进行了更改。

The select = TRUE takes you to the added tab but this can be changed to the default of FALSE to remain on the current tab. select = TRUE会将您带到添加的选项卡,但这可以更改为默认值FALSE以保留在当前选项卡上。

The main way of saving changes is to use reactives / reactiveValues .保存更改的主要方法是使用reactives / reactiveValues See DT Shiny and examples .请参阅DT Shiny示例

Update更新

Based on the comment below, I now create each observeEvent() as needed.根据下面的评论,我现在根据需要创建每个observeEvent()

library(shiny)
library(shinyWidgets)
library(shinyjs)
library(DT)

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            selectizeInput(inputId = "dataframes", label = "select dataframes", 
                           choices = c("iris", "mtcars", "DNase", "ChickWeight"), multiple = TRUE, options = list(create = T))
        ),
        mainPanel(
            tabsetPanel(id = "df_tabset")
        )
    )
)

server <- function(input, output, session) {

    tables <- reactiveValues(
        iris = iris,
        mtcars = mtcars,
        DNase = DNase,
        ChickWeight = ChickWeight,
        df_tabset = NULL
    )

    observeEvent(input$dataframes, {
        if (length(input$dataframes) > length(tables$df_tabset)) {
            df = input$dataframes[! input$dataframes %in% tables$df_tabset]
            output[[df]] = renderDT(tables[[df]], editable = T, rownames = F, options = list(dom = "t"))
            appendTab(inputId = "df_tabset", select = TRUE,
                      tabPanel(title = df, value = df, DTOutput(outputId = df))
            )
            observeEvent(input[[paste0(df, '_cell_edit')]], {
                tables[[df]][input[[paste0(df, '_cell_edit')]]$row, input[[paste0(df, '_cell_edit')]]$col + 1] = input[[paste0(df, '_cell_edit')]]$value
            })
            tables$df_tabset = input$dataframes
        } else {
            df = tables$df_tabset[! tables$df_tabset %in% input$dataframes]
            removeTab(inputId = "df_tabset", target = df)
            tables$df_tabset = input$dataframes
        }

    }, ignoreNULL = FALSE, ignoreInit = TRUE)

}

shinyApp(ui = ui, server = server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM