Приложение ниже содержит selectInput
идентификаторов набора данных и кнопку View details
, которая отображает modalDialog при нажатии. Модальное диалоговое окно имеет таблицу данных, которая содержит некоторую информацию о наборах данных в раскрывающемся списке selectInput.
Вот скриншот приложения при запуске:
Поскольку пользователь может выбрать набор данных, выбрав опцию в раскрывающемся меню или выбрав строку в таблице данных, я создал реактивное значение rv$selectedRow
, в котором хранится значение выбранного набора данных. Когда модальное срабатывание, rv$selectedRow
принимает значение input$data
. При нажатии кнопки Select
в модальном нижнем колонтитуле rv$selectedRow
принимает значение input$dfs_rows_selected
, и selectInput
обновляется, чтобы отразить это новое значение. Это делается двумя observeEvents
в коде ниже.
Когда пользователь выбирает строку, закрывает модальное окно и открывает ее снова, я бы хотел, чтобы страница и строка выбранного набора данных (input$data
) были предварительно выбраны. Я пытался добиться этого, используя selection = list(mode = 'single', selected = rv$selectedRow)
в вызове renderDT
. Как вы можете видеть на скриншоте, строка 1 должна быть предварительно выбрана, но это не так. Я чувствую, что пропускаю req()
где-то в renderDT
, но я не уверен. Значение rv$selectedRow
проверяется при выводе его на консоль, поэтому я не знаю, почему выбранный аргумент renderDT
не работает. Я также не уверен, как сохранить страницу выбранной строки. Любое понимание будет высоко ценится, так как я немного растерялся.
Приложение выглядит следующим образом:
library(shiny)
library(DT)
datasets = data.frame(cbind(id = seq_len(4), name = c('iris', 'mtcars', 'satellite', 'credit')))
# UI ----------------------------------------------------------------------
ui = fluidPage(
selectInput('data', 'Select dataset:', choices = datasets$id),
actionButton('view', 'View details')
)
# SERVER ------------------------------------------------------------------
server <- shinyServer(function(input, output, session) {
rv = reactiveValues(selectedRow = NULL, selectedPage = NULL)
# Opening the modal
observeEvent(input$view, {
rv$selectedRow = req(input$data)
print(paste("selectedRow on 'View':", rv$selectedRow))
showModal(modalDialog(
title = 'Available datasets',
tags$b('Click on a row to select a dataset.'),
br(),
br(),
DT::dataTableOutput('dfs'),
easyClose = F,
footer = tagList(
modalButton('Cancel'),
bsButton('select', 'Select')
)
)
)
})
# Rendering the DT - pre-selection of row not working
output$dfs <- renderDT({
print(paste("selectedRow on 'renderDT':", rv$selectedRow))
datasets
},
options = list(
# displayStart = selectedPage,
pageLength = 2
),
filter = 'top',
selection = list(mode = 'single', selected = rv$selectedRow),
rownames = F
)
# Saving the selected row and updating the selectInput
observeEvent(input$select, {
rv$selectedRow = req(input$dfs_rows_selected)
print(paste("selectedRow on 'Select':", rv$selectedRow))
updateSelectInput(session = session, inputId = 'data', selected = datasets[rv$selectedRow, 1])
removeModal(session)
})
})
shinyApp(ui, server)
Обновленный код:
Согласно это решение и решение, опубликованное Вилмаром ниже, с использованием datatable () в renderDT, похоже, решило проблему -
library(shiny)
library(DT)
datasets = data.frame(cbind(id = seq_len(4), name = c('iris', 'mtcars', 'satellite', 'credit')))
# UI ----------------------------------------------------------------------
ui = fluidPage(
selectInput('data', 'Select dataset:', choices = datasets$id),
actionButton('view', 'View details')
)
# SERVER ------------------------------------------------------------------
server <- shinyServer(function(input, output, session) {
rv = reactiveValues(selectedRow = NULL, selectedPage = NULL)
# Opening the modal
observeEvent(input$view, {
print(paste("selectedRow on 'View':", rv$selectedRow))
showModal(modalDialog(
title = 'Available datasets',
tags$b('Click on a row to select a dataset.'),
br(),
br(),
DT::dataTableOutput('dfs'),
easyClose = F,
footer = tagList(
modalButton('Cancel'),
bsButton('select', 'Select')
)
)
)
})
# Rendering the DT - pre-selection of row not working
output$dfs <- renderDataTable({
r = rv$selectedRow
print(paste("selectedRow on 'renderDT':", r))
datatable(
datasets,
options = list(
displayStart = as.numeric(r)-1,
pageLength = 2
),
filter = 'top',
selection = list(mode = 'single', selected = r),
rownames = F
)
}, server = F)
# Saving the selected row and updating the selectInput
observeEvent(input$select, {
rv$selectedRow = req(input$dfs_rows_selected)
print(paste("selectedRow on 'Select':", rv$selectedRow))
updateSelectInput(session = session, inputId = 'data', selected = datasets[rv$selectedRow, 1])
removeModal(session)
})
observe({
rv$selectedRow = input$data
})
})
shinyApp(ui, server)