[英]DT in a Shiny app: select one row at the time with UP and DOWN keyboard's buttons
I have a DT object embed in a Shiny app.我在 Shiny 应用程序中嵌入了一个 DT 对象。 With the code below, I am able to select one row at the time with a left click of the mouse:使用下面的代码,我可以通过鼠标左键一次选择一行:
library(DT)
library(shiny)
library(tidyverse)
ui <- fluidPage(
fluidRow(
column(width = 12,
DTOutput(outputId = "table",
width = "100%"))
)
)
server <- function(input, output, session) {
output$table <- renderDT({
datatable(data = iris,
selection = "single",
rownames = FALSE,
escape = FALSE,
extension = "KeyTable",
options = list(pageLength = 10,
autoWidth = FALSE,
scrollX = TRUE,
keys = TRUE,
columnDefs = list(list(
targets = 4,
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data != null && data.length > 125 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 125) + '...</span>' : data;",
"}")
))),
class = "display")
})
}
shinyApp(ui = ui,
server = server)
However, I would like to obtain the same result with the UP and DOWN arrow of the keyboard.但是,我想用键盘的向上和向下箭头获得相同的结果。 In this way, I can select (and automatically deselect) a row only through these two buttons, which is useful when the table is pretty long and there are lots of rows to check.这样,我可以只通过这两个按钮选择(并自动取消选择)一行,这在表格很长并且有很多行要检查时很有用。 Thanks for your help!谢谢你的帮助!
EDIT : I've modified the code to insert the extension "KeyTable" as suggested by silentdevildoll .编辑:我已经修改了代码,按照 silentdevildoll 的建议插入了扩展名“ KeyTable ”。 Although I can move in the table's cells with the keyboard, I am still not able to select them with the UP and DOWN arrow.虽然我可以使用键盘在表格的单元格中移动,但我仍然无法使用向上和向下箭头选择它们。
combined and adapted from different sources but mainly https://laustep.github.io/stlahblog/posts/DTcallbacks.html#select-rows-on-click-and-drag结合并改编自不同的来源,但主要是https://laustep.github.io/stlahblog/posts/DTcallbacks.html#select-rows-on-click-and-drag
Key points:关键点:
key-focus
, which is the event triggered because KeyTable already handles the arrow keys to move on the grid.您需要事件key-focus
,这是触发的事件,因为 KeyTable已经处理箭头键在网格上移动。key
would only handle events that are not handled by key-focus or other built-in KeyTable functionality.相反, key
只会处理 key-focus 或其他内置 KeyTable 功能未处理的事件。 https://datatables.net/reference/event/#keytable https://datatables.net/reference/event/#keytableserver=FALSE
in the renderDT
call.您需要server=FALSE
在renderDT
调用中。 If you use server-side handling, the indexes will be incorrect if there has been any sorting applied.如果您使用服务器端处理,则如果应用了任何排序,则索引将不正确。Select
extension which apparently clashes with Shiny's select functionality. Shiny 抱怨Select
扩展显然与 Shiny 的选择功能冲突。 However it seems to be working fine.但是,它似乎工作正常。 I just overwrite the existing {outputname}_rows_selected
input so the latest entry wins, both click and arrow row selection work.我只是覆盖现有的{outputname}_rows_selected
输入,以便最新条目获胜,单击和箭头行选择都有效。library(shiny)
library(DT)
js_select_dt <- c(
"var dt = table.table().node();",
"var tblID = $(dt).closest('.datatables').attr('id');",
"var inputName = tblID + '_rows_selected'",
"var incrementName = tblID + '_rows_selected2_increment'",
"table.on('key-focus', function(e, datatable, cell, originalEvent){",
" if (originalEvent.type === 'keydown'){",
" table.rows().deselect(); ",
" table.row(cell[0][0].row).select();",
" row = table.rows({selected: true})",
# Note: this ID is zero-based so add one
" Shiny.setInputValue(inputName, [parseInt(row[0]) + 1]);",
" }",
"});"
)
ui <- fluidPage(
textOutput("selectedRow"),
DT::DTOutput("irisTable")
)
server <- function(input, output) {
output$irisTable<- DT::renderDT({
iris %>%
datatable(
# This datatable uses both shiny's select for conventional selection
# and keytable + select for selection by keyboard (callback js_select_dt, see above).
# The keyboard-selected row just overwrites the regular input$peaksTable_rows_selected
# field.
selection = "single",
editable = FALSE,
callback = JS(js_select_dt),
extensions = c("KeyTable", "Select"),
options = list(
keys = TRUE,
# keys = list(keys = c(38, 40))
select = TRUE
)
)
}, server=FALSE)
output$selectedRow <- renderText(input$irisTable_rows_selected)
}
runApp(shinyApp(ui, server))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.