DT 中的闪亮小部件 Table
Shiny widgets in DT Table
我正在尝试在 DT table 的行中包含闪亮的小部件,例如 textInput、selectInput(单个)、sliderInput 和 selectInput(多个)。当小部件直接在页面上时,它们显示正确,但是,当它们放在 table 中时,其中一些无法正确显示。
textInput 很好,selectInput(单个)除了一些 css 差异外大部分都很好,但是 selectInput(多个)显示不正确,sliderInput 肯定显示不正确。似乎依赖 javascript 的小部件是有问题的。有没有办法让这些widgets在DT中正常工作table?
这是我的可重现示例。我在将小部件放入 table 时使用了原始 HTML,但我直接从每个小部件的闪亮函数生成的 HTML 中获取了它。
library(shiny)
library(DT)
ui <- fluidPage(
h3("This is how I want the widgets to look in the DT table."),
fluidRow(column(3, textInput(inputId = "text",
label = "TEXT")),
column(3, selectInput(inputId = "single_select",
label = "SINGLE SELECT",
choices = c("", "A", "B", "C"))),
column(3, sliderInput(inputId = "slider",
label = "SLIDER",
min = 0,
max = 10,
value = c(0, 10))),
column(3, selectizeInput(inputId = "multiple_select",
label = "MULTIPLE SELECT",
choices = c("", "A", "B", "C"),
multiple = TRUE))),
h3("This is how they actually appear in a DT table."),
fluidRow(DTOutput(outputId = "table"))
)
server <- function(input, output, session) {
output$table <- renderDT({
data <- data.frame(ROW = 1:5,
TEXT = '<input id="text" type="text" class="form-control" value=""/>',
SINGLE_SELECT = '<select id="single_select" style="width: 100%;">
<option value="" selected></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
SLIDER = '<input class="js-range-slider" id="slider" data-type="double" data-min="0" data-max="10" data-from="0" data-to="10" data-step="1" data-grid="true" data-grid-num="10" data-grid-snap="false" data-prettify-separator="," data-prettify-enabled="true" data-keyboard="true" data-drag-interval="true" data-data-type="number"/>',
MULTIPLE_SELECT = '<select id="multiple_select" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
stringsAsFactors = FALSE)
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE)
})
}
shinyApp(ui = ui, server = server)
滑块
对于滑块,您必须从文本输入开始:
SLIDER = '<input type="text" id="s" name="slider" value="" />'
然后用 JavaScript:
把它变成一个滑块
js <- c(
"function(settings){",
" $('#s').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20,",
" from: 5,",
" to: 15",
" });",
"}"
)
有关选项,请参阅 ionRangeSlider。
您可以使用 initComplete
选项传递 JavaScript 代码:
server <- function(input, output, session) {
output$table <- renderDT({
data <- data.frame(ROW = 1:5,
TEXT = '<input id="text" type="text" class="form-control" value=""/>',
SINGLE_SELECT = '<select id="single_select" style="width: 100%;">
<option value="" selected></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
SLIDER = '<input type="text" id="s" name="slider" value="" />',
MULTIPLE_SELECT = '<select id="multiple_select" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
stringsAsFactors = FALSE)
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE,
options =
list(
initComplete = JS(js)
))
})
}
然后你只得到第一行的滑块:
那是因为五个文本输入具有相同的 ID。您必须为五个文本输入设置不同的 ID:
SLIDER = sapply(1:5, function(i) {
sprintf('<input type="text" id="Slider%d" name="slider" value="" />', i)
}),
然后使用此 JavaScript 代码将它们变成滑块:
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20,",
" from: 5,",
" to: 15",
" });",
"}"
)
要设置 from
和 to
的初始值,最好在输入文本的 value
参数中给出它们,如下所示:
SLIDER = sapply(1:5, function(i) {
sprintf('<input type="text" id="Slider%d" name="slider" value="5;15" />', i)
})
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20",
" });",
"}"
)
多个select
要获得所需的倍数 select 显示,您必须调用 selectize()
:
MULTIPLE_SELECT = '<select id="mselect" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>'
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20",
" });",
" $('#mselect').selectize()",
"}"
)
同样,这仅适用于第一个倍数 select。使用个人 ID 申请五个。
绑定
最后,您必须绑定输入以获得它们在 Shiny 中可用的值:
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE,
options =
list(
initComplete = JS(js),
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
现在您可以获取 input$Slider1
、input$Slider2
、... 和 input$mselect
中的值。请注意,input$Slider[1/2/3/4/5]
returns 滑块的值采用以下格式:"3;15"
.
我正在尝试在 DT table 的行中包含闪亮的小部件,例如 textInput、selectInput(单个)、sliderInput 和 selectInput(多个)。当小部件直接在页面上时,它们显示正确,但是,当它们放在 table 中时,其中一些无法正确显示。
textInput 很好,selectInput(单个)除了一些 css 差异外大部分都很好,但是 selectInput(多个)显示不正确,sliderInput 肯定显示不正确。似乎依赖 javascript 的小部件是有问题的。有没有办法让这些widgets在DT中正常工作table?
这是我的可重现示例。我在将小部件放入 table 时使用了原始 HTML,但我直接从每个小部件的闪亮函数生成的 HTML 中获取了它。
library(shiny)
library(DT)
ui <- fluidPage(
h3("This is how I want the widgets to look in the DT table."),
fluidRow(column(3, textInput(inputId = "text",
label = "TEXT")),
column(3, selectInput(inputId = "single_select",
label = "SINGLE SELECT",
choices = c("", "A", "B", "C"))),
column(3, sliderInput(inputId = "slider",
label = "SLIDER",
min = 0,
max = 10,
value = c(0, 10))),
column(3, selectizeInput(inputId = "multiple_select",
label = "MULTIPLE SELECT",
choices = c("", "A", "B", "C"),
multiple = TRUE))),
h3("This is how they actually appear in a DT table."),
fluidRow(DTOutput(outputId = "table"))
)
server <- function(input, output, session) {
output$table <- renderDT({
data <- data.frame(ROW = 1:5,
TEXT = '<input id="text" type="text" class="form-control" value=""/>',
SINGLE_SELECT = '<select id="single_select" style="width: 100%;">
<option value="" selected></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
SLIDER = '<input class="js-range-slider" id="slider" data-type="double" data-min="0" data-max="10" data-from="0" data-to="10" data-step="1" data-grid="true" data-grid-num="10" data-grid-snap="false" data-prettify-separator="," data-prettify-enabled="true" data-keyboard="true" data-drag-interval="true" data-data-type="number"/>',
MULTIPLE_SELECT = '<select id="multiple_select" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
stringsAsFactors = FALSE)
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE)
})
}
shinyApp(ui = ui, server = server)
滑块
对于滑块,您必须从文本输入开始:
SLIDER = '<input type="text" id="s" name="slider" value="" />'
然后用 JavaScript:
把它变成一个滑块js <- c(
"function(settings){",
" $('#s').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20,",
" from: 5,",
" to: 15",
" });",
"}"
)
有关选项,请参阅 ionRangeSlider。
您可以使用 initComplete
选项传递 JavaScript 代码:
server <- function(input, output, session) {
output$table <- renderDT({
data <- data.frame(ROW = 1:5,
TEXT = '<input id="text" type="text" class="form-control" value=""/>',
SINGLE_SELECT = '<select id="single_select" style="width: 100%;">
<option value="" selected></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
SLIDER = '<input type="text" id="s" name="slider" value="" />',
MULTIPLE_SELECT = '<select id="multiple_select" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>',
stringsAsFactors = FALSE)
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE,
options =
list(
initComplete = JS(js)
))
})
}
然后你只得到第一行的滑块:
那是因为五个文本输入具有相同的 ID。您必须为五个文本输入设置不同的 ID:
SLIDER = sapply(1:5, function(i) {
sprintf('<input type="text" id="Slider%d" name="slider" value="" />', i)
}),
然后使用此 JavaScript 代码将它们变成滑块:
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20,",
" from: 5,",
" to: 15",
" });",
"}"
)
要设置 from
和 to
的初始值,最好在输入文本的 value
参数中给出它们,如下所示:
SLIDER = sapply(1:5, function(i) {
sprintf('<input type="text" id="Slider%d" name="slider" value="5;15" />', i)
})
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20",
" });",
"}"
)
多个select
要获得所需的倍数 select 显示,您必须调用 selectize()
:
MULTIPLE_SELECT = '<select id="mselect" class="form-control" multiple="multiple">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>'
js <- c(
"function(settings){",
" $('[id^=Slider]').ionRangeSlider({",
" type: 'double',",
" grid: true,",
" grid_num: 10,",
" min: 0,",
" max: 20",
" });",
" $('#mselect').selectize()",
"}"
)
同样,这仅适用于第一个倍数 select。使用个人 ID 申请五个。
绑定
最后,您必须绑定输入以获得它们在 Shiny 中可用的值:
datatable(data = data,
selection = "none",
escape = FALSE,
rownames = FALSE,
options =
list(
initComplete = JS(js),
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
现在您可以获取 input$Slider1
、input$Slider2
、... 和 input$mselect
中的值。请注意,input$Slider[1/2/3/4/5]
returns 滑块的值采用以下格式:"3;15"
.