DT表中的闪亮小部件 [英] Shiny widgets in DT Table

查看:93
本文介绍了DT表中的闪亮小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在DT表的行中包含闪亮的小部件,如textInput,selectInput(single),sliderInput和selectInput(multiple)。当小部件直接在页面上时,它们会正确显示,但是当它们放入表格时,其中一些不能正确显示。



textInput很好对于某些css差异,selectInput(单个)大部分都很好,但是selectInput(multiple)没有正确显示,并且sliderInput肯定没有正确显示。似乎依赖于javascript的小部件是有问题的小部件。有没有办法让这些小部件在DT表中正常工作?



这是我可重复的例子。当我们将小部件放在表格中时,我使用原始HTML作为小部件,但我直接从每个小部件的闪亮函数生成的HTML中获取它。

 库(闪亮)
库(DT)

ui< - fluidPage(
h3(这就是我希望小部件在DT表。),
fluidRow(列(3,textInput(inputId =text,
label =TEXT)),
列(3,selectInput(inputId =single_select) ,
label =SINGLE SELECT,
choices = c(,A,B,C))),
列(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(这它们是如何实际出现在DT表中的。),
fluidRow(DTOutput(outputId =table))


服务器< - 函数(输入,输出) ,会话){

输出$ table< - renderDT({
data< - data.frame(ROW = 1:5,
TEXT ='< input id =texttype =textclass =form-controlvalue =/>',
SINGLE_SELECT ='< select id =single_selectstyle =width:100%;> ;
< option value =已选择>< / option>
< option value =A> A< / option>
< option value =B> B< / option>
< option value =C> C< / option>
< / select>',
SLIDER ='< input class =js-range-sliderid =sliderdata-type =doubledata-min =0data -max =10data-from =0data-to =10data-step =1data-grid =truedata-grid-num =10data-grid-snap = falsedata-prettify-separator =,data-prettify-enabled =truedata-keyboard =truedata-drag-interval =truedata-data-type =number/>',
MULTIPLE_SELECT ='< select id =multiple_selectclass =form-controlmultiple =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 =textid =s name =slidervalue =/>'

然后将其转换为滑块JavaScript:

  js<  -  c(
function(settings){,
$ ('#s')。ionRangeSlider({,
类型:'double',,
grid:true,,
grid_num:10,,
min:0,,
max:20,,
from:5,,
to:15,
});,
}

请参阅



这是因为五个文本输入具有相同的ID。您必须为五个文本输入设置不同的ID:

  SLIDER = sapply(1:5,function(i){ 
sprintf('< input type =textid =Slider%dname =slidervalue =/>',i)
}),

然后使用此JavaScript代码将它们变成滑块:

  js<  -  c(
function(settings){,
$('[id ^ = Slider]')。ionRangeSlider({,
type:'double',,
grid:true,,
grid_num:10,,
min:0,,
最高:20,,
从:5,,
到:15,
});,
}



要将的初始值和设置为,最好在<$中设置它们c $ c> value 输入文本的参数l ike this:

  SLIDER = sapply(1:5,function(i){
sprintf('< input type =textid =Slider%dname =slidervalue =5; 15/>',i)
})

js< - c (
function(settings){,
$('[id ^ = Slider]')。ionRangeSlider({,
type:'double',,
grid:true,
grid_num:10,,
min:0,,
max:20,
}); ,
}



多次选择



要获得所需的多重选择显示,您必须拨打 selectize()

  MULTIPLE_SELECT ='< select id =mselectclass =form-controlmultiple =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 ({,
类型:'double',,
grid:true,,
grid_num:10,,
min:0,,
max:20,
});,
$('#mselect')。selectize(),
}

同样,这仅适用于第一个多选。使用个人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 ());}')


现在你可以得到中的值输入$ Slider1 输入$ Slider2 ,...和输入$ M选中。请注意输入$ Slider [1/2/3/4/5] 以此格式返回滑块的值:3; 15


I'm trying to include shiny widgets such as textInput, selectInput (single), sliderInput, and selectInput (multiple) in the rows of a DT table. When the widgets are directly on the page, they display correctly, however, when they are put in the table, some of them do not display correctly.

The textInput is fine and the selectInput (single) is mostly fine save for some css differences, but the selectInput (multiple) isn't displaying correctly and the sliderInput definitely isn't displaying correctly. It seems the widgets that rely on javascript are the ones that have issues. Is there a way to make these widgets work correctly in the DT table?

Here is my reproducible example. I used the raw HTML for the widgets when putting them in the table, but I took that directly from the HTML generated by the shiny functions for each widget.

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)

解决方案

Sliders

For the sliders, you have to start with a text input:

SLIDER = '<input type="text" id="s" name="slider" value="" />'

and then turn it into a slider with JavaScript:

js <- c(
  "function(settings){",
  "  $('#s').ionRangeSlider({",
  "    type: 'double',",
  "    grid: true,",
  "    grid_num: 10,",
  "    min: 0,",
  "    max: 20,",
  "    from: 5,",
  "    to: 15",
  "  });",
  "}"
)

See ionRangeSlider for the options.

You can pass the JavaScript code with the initComplete option:

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)
                ))
  })

}

Then you get the slider for the first row only:

That's because the five text inputs have the same id. You have to set a different id for the five text inputs:

SLIDER = sapply(1:5, function(i) {
  sprintf('<input type="text" id="Slider%d" name="slider" value="" />', i)
}),

Then use this JavaScript code to turn them into sliders:

js <- c(
  "function(settings){",
  "  $('[id^=Slider]').ionRangeSlider({",
  "    type: 'double',",
  "    grid: true,",
  "    grid_num: 10,",
  "    min: 0,",
  "    max: 20,",
  "    from: 5,",
  "    to: 15",
  "  });",
  "}"
)

To set the initial values of from and to, it's better to give them in the value argument of the input text like this:

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",
  "  });",
  "}"
)

Multiple selects

To get the desired display of a multiple select, you have to call 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()",
  "}"
)

Similarly, this applies to the first multiple select only. Use individual id's to apply to the five ones.

Binding

Finally, you have to bind the inputs to get their value available in 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()); } ')
            )
)

Now you can get the values in input$Slider1, input$Slider2, ..., and input$mselect. Note that input$Slider[1/2/3/4/5] returns the values of the slider in this format: "3;15".

这篇关于DT表中的闪亮小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆