observeEvent用于Flexdashboard中的行选择

时间:2016-05-28 04:14:51

标签: r datatable flexdashboard

我试图重新创建Chris Glur提出的CRUD应用程序 http://ipub.com/apps/shiny_crud01/使用Flexdashboard。

当我在数据表中选择一行进行编辑时遇到一些问题,数据表中所选行的数据元素不会发送到左侧面板上的输入元素。

enter image description here

我想知道flexdashboard是否存在以下observeEvent代码部分未处理或者数据表背后的javascript未正确处理observeEvent的问题。

# Select row in table -> show details in inputs
  observeEvent(input$responses_rows_selected, {
    if (length(input$responses_rows_selected) > 0) {
      data <- ReadData()[input$responses_rows_selected, ]
      UpdateInputs(data, session)
    }

  })

此代码将所选行的数据发送到输入面板中的输入元素,但这在Flexdashboard中不起作用。

以下是我针对此问题的完整flexdashboard代码。我非常感谢有人可以提供一些反馈。提前谢谢。

---
title: "CRUD Prototype"
author: "Missy"
output: 
  flexdashboard::flex_dashboard:

    theme: United
    social: menu
    source_code: embed

    vertical_layout: scroll
    smooth_scroll: true
runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
library(DT)
library(shinyjs)

```

```{r}
CreateDefaultRecord <- function() {
  mydefault <- CastData(list(id = "0", name = "", used_shiny = FALSE, r_num_years = 2))
  return (mydefault)
}


# This method casts from the inputs to a one-row data.frame. We use it, for instance, when the user 
#creates a new record by typing in values into the inputs, and then clicks “Submit”

CastData <- function(data) {
  datar <- data.frame(name = data["name"], 
                      used_shiny = as.logical(data["used_shiny"]), 
                      r_num_years = as.integer(data["r_num_years"]),
                      stringsAsFactors = FALSE)

  rownames(datar) <- data["id"]
  return (datar)
}


# This method takes the data as selected in the DataTable, and updates the inputs with the respective values

UpdateInputs <- function(data, session) {
  updateTextInput(session, "id", value = unname(rownames(data)))
  updateTextInput(session, "name", value = unname(data["name"]))
  updateCheckboxInput(session, "used_shiny", value = as.logical(data["used_shiny"]))
  updateSliderInput(session, "r_num_years", value = as.integer(data["r_num_years"]))
}

# This function finds the next ID of a new record. In mysql, this could be done by an incremental index, 
# automatically. And then this method could be used to fetch the last insert ID. But here, we manage the ID ourselves:


GetNextId <- function() {
  if (exists("responses") && nrow(responses) > 0) {
    max(as.integer(rownames(responses))) + 1
  } else {
    return (1)
  }
}


#Create


CreateData <- function(data) {

  data <- CastData(data)
  rownames(data) <- GetNextId()
  if (exists("responses")) {
    responses <<- rbind(responses, data)
  } else {
    responses <<- data
  }
}


#Read

ReadData <- function() {
  if (exists("responses")) {
    responses
  }
}


#Update

UpdateData <- function(data) {
  data <- CastData(data)
  responses[row.names(responses) == row.names(data), ] <<- data
}

#Delete

DeleteData <- function(data) {
  responses <<- responses[row.names(responses) != unname(data["id"]), ]
}



GetTableMetadata <- function() {
  fields <- c(id = "Id", 
              name = "Name", 
              used_shiny = "Used Shiny", 
              r_num_years = "R Years")

  result <- list(fields = fields)
  return (result)
}

```

Inputs {.sidebar}
-----------------------------------------------------------------------

```{r , echo = F}

                                              shinyjs::useShinyjs()

                                              shinyjs::disabled(textInput("id", "Id", "0"))
                                              textInput("name", "Name", "")
                                              checkboxInput("used_shiny", "Used Shiny", FALSE)
                                              sliderInput("r_num_years", "R Years", 0, 25, 2, ticks = FALSE)


                                              actionButton("submit", "Submit")
                                              actionButton("new", "New")
                                              actionButton("delete", "Delete")

```

```{r}

 # input fields are treated as a group
  formData <- reactive({
    sapply(names(GetTableMetadata()$fields), function(x) input[[x]])
  })

  # Click "Submit" button -> save data
  observeEvent(input$submit, {
    if (input$id != "0") {
      UpdateData(formData())
    } else {
      CreateData(formData())
      UpdateInputs(CreateDefaultRecord(), session)
    }
  }, priority = 1)

  # Press "New" button -> display empty record
  observeEvent(input$new, {
    UpdateInputs(CreateDefaultRecord(), session)
  })

  # Press "Delete" button -> delete from data
  observeEvent(input$delete, {
    DeleteData(formData())
    UpdateInputs(CreateDefaultRecord(), session)
  }, priority = 1)

  # Select row in table -> show details in inputs
  observeEvent(input$responses_rows_selected, {
    if (length(input$responses_rows_selected) > 0) {
      data <- ReadData()[input$responses_rows_selected, ]
      UpdateInputs(data, session)
    }

  })

```

Column 
-----------------------------------------------------------------------
```{r}

DT::renderDataTable({
    #update after submit is clicked
    input$submit
  input$new
    #update after delete is clicked
    input$delete
    ReadData()
  }, server = FALSE, selection = "single",
  colnames = unname(GetTableMetadata()$fields)[-1]
  )     

```

0 个答案:

没有答案