我正在研究一个CRUD应用程序,该应用程序需要用户输入并提交到表中。
由于某种原因,当我使用下拉选择选项而不是文本输入时。当我使用文本输入时,它很好并且可以使用。 SelectizeInput,使应用程序崩溃,由于某种原因我找不到错误。我要去哪里错了?
这是我的代码:
library(shiny)
library(shinyjs)
library(shinythemes)
######################### Get table metadata. For now, just the fields ##########################
######################## Further development: also define field types ##########################
####################### and create inputs generically ###########################
######## TABLE 1: ADD NEW PERSON
GetTableMetadata <- function() {
fields <- c(
id = "Id",
name = "Tribe/Task Name",
category = "Category",
task_num = "Task Order",
client_facing = "Client Facing?",
completion = "Task Completed?"
)
result <- list(fields = fields)
return (result)
}
########################## CREATE, READ, UPDATE, DELETE #######################################
#### CRUD
# Find the next ID of a new record
GetNextId <- function() {
if (exists("responses") && nrow(responses) > 0) {
max(as.integer(rownames(responses))) + 1
} else {
return (1)
}
}
#C
CreateData <- function(data) {
data <- CastData(data)
rownames(data) <- GetNextId()
if (exists("responses")) {
responses <<- rbind(responses, data)
} else {
responses <<- data
}
}
#R
ReadData <- function() {
if (exists("responses")) {
responses
}
}
#U
UpdateData <- function(data) {
data <- CastData(data)
responses[row.names(responses) == row.names(data),] <<- data
}
#D
DeleteData <- function(data) {
responses <<-
responses[row.names(responses) != unname(data["id"]),]
}
#######################################################################################
# Cast from Inputs to a one-row data.frame
CastData <- function(data) {
datar <- data.frame(
name = data["name"],
category = data["category"],
task_num = as.integer(data["task_num"]),
stringsAsFactors = FALSE,
client_facing = as.logical(data["client_facing"]),
completion = as.logical(data["completion"])
)
rownames(datar) <- data["id"]
return (datar)
}
# Return an empty, new record
CreateDefaultRecord <- function() {
mydefault <-
CastData(list(
id = "0",
name = "",
category ="",
task_num = 2,
client_facing = FALSE,
completion = FALSE
))
return (mydefault)
}
# Fill the input fields with the values of the selected record in the table
UpdateInputs <- function(data, session) {
updateTextInput(session, "id", value = unname(rownames(data)))
updateTextInput(session, "name", value = unname(data["name"]))
updateSelectizeInput(session, "category", value = unname(data["category"]))
updateTextInput(session, "task_num", value = unname(rownames(data)))
updateCheckboxInput(session, "client_facing", value = as.logical(data["client_facing"]))
updateCheckboxInput(session, "completion", value = as.logical(data["completion"]))
}
#######################################################################################
#######################################################################################
ui <- fluidPage(
#use shiny js to disable the ID field
shinyjs::useShinyjs(),
##
#data table
DT::dataTableOutput("responses", width = 300),
#input fields
tags$hr(),
shinyjs::disabled(textInput("id", "Id", "0")),
textInput("name", "Tribe/Task Name", ""),
selectizeInput("Category", label = "Category", choices = c(Choose = '', Tribal = 'Tribal', Individual = 'Individual', Other = 'Other'), FALSE),
textInput("task_num", "Task Order", ""),
checkboxInput("client_facing", "Client Facing?", FALSE),
checkboxInput("completion", "Task Completed?", FALSE),
#action buttons
actionButton("submit", "Submit"),
actionButton("new", "New"),
actionButton("delete", "Delete")
)
server <- function(input, output, session) {
# 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)
}
})
# display table
output$responses <- DT::renderDataTable({
#update after submit is clicked
input$submit
#update after delete is clicked
input$delete
ReadData()
}, server = FALSE, selection = "single",
colnames = unname(GetTableMetadata()$fields)[-1])
}
# Shiny app with 3 fields that the user can submit data for
shinyApp(ui = ui, server = server)
答案 0 :(得分:0)
selectizeinput()
上的ID错误。它应该是带有小“ c”的“类别”。这是因为您的GetTableMetadata()
中的名称具有“类别”作为名称。
另外,updateSelectizeInput()
没有值作为参数。
请告诉我这是否可以解决您的问题。
library(shiny)
library(shinyjs)
library(shinythemes)
######################### Get table metadata. For now, just the fields ##########################
######################## Further development: also define field types ##########################
####################### and create inputs generically ###########################
######## TABLE 1: ADD NEW PERSON
GetTableMetadata <- function() {
fields <- c(
id = "Id",
name = "Tribe/Task Name",
category = "Category",
task_num = "Task Order",
client_facing = "Client Facing?",
completion = "Task Completed?"
)
result <- list(fields = fields)
return (result)
}
########################## CREATE, READ, UPDATE, DELETE #######################################
#### CRUD
# Find the next ID of a new record
GetNextId <- function() {
if (exists("responses") && nrow(responses) > 0) {
max(as.integer(rownames(responses))) + 1
} else {
return (1)
}
}
#C
CreateData <- function(data) {
data <- CastData(data)
rownames(data) <- GetNextId()
if (exists("responses")) {
responses <<- rbind(responses, data)
} else {
responses <<- data
}
}
#R
ReadData <- function() {
if (exists("responses")) {
responses
}
}
#U
UpdateData <- function(data) {
data <- CastData(data)
responses[row.names(responses) == row.names(data),] <<- data
}
#D
DeleteData <- function(data) {
responses <<-
responses[row.names(responses) != unname(data["id"]),]
}
#######################################################################################
# Cast from Inputs to a one-row data.frame
CastData <- function(data) {
datar <- data.frame(
name = data["name"],
category = data["category"],
task_num = as.integer(data["task_num"]),
stringsAsFactors = FALSE,
client_facing = as.logical(data["client_facing"]),
completion = as.logical(data["completion"])
)
rownames(datar) <- data["id"]
return (datar)
}
# Return an empty, new record
CreateDefaultRecord <- function() {
mydefault <-
CastData(list(
id = "0",
name = "",
category ="",
task_num = 2,
client_facing = FALSE,
completion = FALSE
))
return (mydefault)
}
# Fill the input fields with the values of the selected record in the table
UpdateInputs <- function(data, session) {
updateTextInput(session, "id", value = unname(rownames(data)))
updateTextInput(session, "name", value = unname(data["name"]))
updateSelectizeInput(session, "category")
updateTextInput(session, "task_num", value = unname(rownames(data)))
updateCheckboxInput(session, "client_facing", value = as.logical(data["client_facing"]))
updateCheckboxInput(session, "completion", value = as.logical(data["completion"]))
}
#######################################################################################
#######################################################################################
ui <- fluidPage(
#use shiny js to disable the ID field
shinyjs::useShinyjs(),
##
#data table
DT::dataTableOutput("responses", width = 300),
#input fields
tags$hr(),
shinyjs::disabled(textInput("id", "Id", "0")),
textInput("name", "Tribe/Task Name", ""),
selectizeInput("category", label = "Category", choices = c(Choose = '', Tribal = 'Tribal', Individual = 'Individual', Other = 'Other'), FALSE),
textInput("task_num", "Task Order", ""),
checkboxInput("client_facing", "Client Facing?", FALSE),
checkboxInput("completion", "Task Completed?", FALSE),
#action buttons
actionButton("submit", "Submit"),
actionButton("new", "New"),
actionButton("delete", "Delete")
)
server <- function(input, output, session) {
# 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)
}
})
# display table
output$responses <- DT::renderDataTable({
#update after submit is clicked
input$submit
#update after delete is clicked
input$delete
ReadData()
}, server = FALSE, selection = "single",
colnames = unname(GetTableMetadata()$fields)[-1])
}
# Shiny app with 3 fields that the user can submit data for
shinyApp(ui = ui, server = server)