英文:
DT Datatable with selectInputs resets back to left after selection
问题
我正在在Shiny应用的DT数据表中的一列中使用selectInputs。多亏了这里的一些帮助,我包括了一些JavaScript来将selectInputs选择化,以保持selectize的样式和搜索功能。这是一个宽表格,因此需要水平滚动才能看到selectInputs。
当我第一次在任何selectInputs中进行选择时,一切都正常。然而,当我第二次单击任何selectInputs时,页面会滚动回到左边,而selectInputs则不可见。我如何保持我拥有的样式和搜索功能,但阻止这种情况发生?
编辑:我还尝试使用shinyWidgets::pickerInput,它没有滚动条问题。然而,在数据表中,对我来说,liveSearch功能不起作用。如果您可以解决这个问题,我将考虑这个问题已得到解答。
示例:
library(shiny)
library(DT)
# Function to selectize one or more input ids
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c(
"function(settings){",
myStrings,
"}"
)
}
shinyApp(
ui = fluidPage(
div(style = "display: none;", selectInput(inputId = "dummy", label = NULL, choices = 1:2)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = FALSE,
options = list(
initComplete = JS(selectize_ids(select_ids))
)
)
})
}
)
英文:
I am using selectInputs in a column of a DT datatable in a Shiny app. Thanks to some help here, I am including some JavaScript to selectize the selectInputs to keep the style and search capability of selectize. It is a wide table, so the selectInputs require scrolling horizontally to see them.
When I make a selection in any of the selectInputs the first time, everything works fine. However, when I click any of the selectInputs a second time, the page scrolls back to the left and the selectInputs are out of view. How can I keep the style and search capability I have but prevent this from happening?
EDIT: I also tried using shinyWidgets::pickerInput, and it does not have the scrollbar problem. However, the liveSearch feature does not work for me in a datatable. If you can solve that issue, I'll consider this question answered.
Example:
library(shiny)
library(DT)
# Function to selectize one or more input ids
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c(
"function(settings){",
myStrings,
"}"
)
}
shinyApp(
ui = fluidPage(
div(style = "display: none;", selectInput(inputId = "dummy", label = NULL, choices = 1:2)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = F,
options = list(
initComplete = JS(selectize_ids(select_ids))
)
)
})
}
)
答案1
得分: 0
以下是您要翻译的内容:
"The reason that the datatable
resets left after the second click on the SelectInput
is that selectize
has input fields which have position: absolute
and left: -10000px
. Disabling this fact can be implemented by adding CSS, e.g. for the first SelectInput
:
#myselect_1-selectized {
position: relative !important;
left: 0px !important;
}
This CSS can be generated dynamically for all your SelectInput
inside the datatable
selectize_css <- function(ids) {
css_list <- as.character(sapply(ids, function(id) {
paste0("#",
id,
"-selectized {position: relative !important; left: 0px !important;} ")
}))
paste(css_list, collapse = '')
}
and can then be included inside the fluidPage
by using
tags$style(HTML(selectize_css(select_ids)))
Complete minimal example:
library(shiny)
library(DT)
# Function to selectize one or more input ids
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c("function(settings){",
myStrings,
"}")
}
selectize_css <- function(ids) {
css_list <- as.character(sapply(ids, function(id) {
paste0("#",
id,
"-selectized {position: relative !important; left: 0px !important;} ")
}))
paste(css_list, collapse = '')
}
shinyApp(
ui = fluidPage(
tags$style(HTML(selectize_css(select_ids))),
div(style = "display: none;", selectInput(
inputId = "dummy",
label = NULL,
choices = 1:2
)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = FALSE,
options = list(initComplete = JS(selectize_ids(select_ids)))
)
})
}
)
请注意,这是您提供的内容的翻译,包括其中的代码部分。
英文:
The reason that the datatable
resets left after the second click on the SelectInput
is that selectize
has input fields which have position: absolute
and left: -10000px
. Disabling this fact can be implemented by adding CSS, e.g. for the first SelectInput
:
#myselect_1-selectized {
position: relative !important;
left: 0px !important;
}
This CSS can be generated dynamically for all your SelectInput
inside the datatable
selectize_css <- function(ids) {
css_list <- as.character(sapply(ids, function(id) {
paste0("#",
id,
"-selectized {position: relative !important; left: 0px !important;} ")
}))
paste(css_list, collapse = '')
}
and can then be included inside the fluidPage
by using
tags$style(HTML(selectize_css(select_ids)))
Complete minimal example:
library(shiny)
library(DT)
# Function to selectize one or more input ids
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c("function(settings){",
myStrings,
"}")
}
selectize_css <- function(ids) {
css_list <- as.character(sapply(ids, function(id) {
paste0("#",
id,
"-selectized {position: relative !important; left: 0px !important;} ")
}))
paste(css_list, collapse = '')
}
shinyApp(
ui = fluidPage(
tags$style(HTML(selectize_css(select_ids))),
div(style = "display: none;", selectInput(
inputId = "dummy",
label = NULL,
choices = 1:2
)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = F,
options = list(initComplete = JS(selectize_ids(select_ids)))
)
})
}
)
答案2
得分: -2
你正在遇到的问题是因为在datatable首次渲染时触发了initComplete
事件,然后当用户再次点击其中一个selectInput
时会再次触发该事件。initComplete
事件会将页面滚动到datatable的顶部,这就是为什么当用户再次点击它们时,selectInput
不可见的原因。
为了防止这种情况发生,你可以使用scrollY
选项来设置datatable的初始滚动位置。例如,你可以使用以下代码:
options = list(
initComplete = JS(selectize_ids(select_ids)),
scrollY = 300
)
这将把datatable的初始滚动位置设置为页面顶部的300像素。这将确保当用户点击它们时,selectInput
始终可见。
以下是完整的代码:
library(shiny)
library(DT)
# 选择一个或多个输入id的函数
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c(
"function(settings){",
myStrings,
"}"
)
}
shinyApp(
ui = fluidPage(
div(style = "display: none;", selectInput(inputId = "dummy", label = NULL, choices = 1:2)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = F,
options = list(
initComplete = JS(selectize_ids(select_ids)),
scrollY = 300
)
)
})
}
)
这段代码将防止页面在用户点击其中一个selectInput
时滚动回顶部。
英文:
The problem you are experiencing is caused by the fact that the initComplete
event is fired when the datatable is first rendered, and then again when the user clicks on one of the selectInputs. The initComplete
event scrolls the page to the top of the datatable, which is why the selectInputs are out of view when the user clicks on them a second time.
To prevent this from happening, you can use the scrollY
option to set the initial scroll position of the datatable. For example, you could use the following code:
options = list(
initComplete = JS(selectize_ids(select_ids)),
scrollY = 300
)
This will set the initial scroll position of the datatable to 300 pixels from the top of the page. This will ensure that the selectInputs are always visible when the user clicks on them.
Here is the complete code:
library(shiny)
library(DT)
# Function to selectize one or more input ids
selectize_ids <- function(ids) {
myStrings <- as.character(sapply(ids, function(id) {
paste0(" $('#", id, "').selectize();")
}))
c(
"function(settings){",
myStrings,
"}"
)
}
shinyApp(
ui = fluidPage(
div(style = "display: none;", selectInput(inputId = "dummy", label = NULL, choices = 1:2)),
fluidRow(DT::dataTableOutput("mytable"))
),
server = function(input, output, session) {
df <- as.data.frame(matrix(data = paste0("text", 1:60), ncol = 20))
colnames(df) <- paste0("column", 1:ncol(df))
df$myselect <- sapply(1:nrow(df), function(i) {
as.character(selectInput(
inputId = paste0("myselect_", i),
label = NULL,
choices = c("option1", "option2", "option3")
))
})
select_ids <- paste0("myselect_", 1:nrow(df))
output$mytable <- DT::renderDataTable({
DT::datatable(
data = df,
escape = F,
options = list(
initComplete = JS(selectize_ids(select_ids)),
scrollY = 300
)
)
})
}
)
This code will prevent the page from scrolling back to the top when the user clicks on one of the selectInputs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论