在DT::datable中的SelectizeInput只能作为html使用。

问题描述 投票:1回答:1

我正试图为我的终端用户优化一个时间跟踪应用的用户体验。本质上,它从google日历的api中获取数据,并将其安排在 "时间追踪 "中。tibble让用户选择选定的会议,并将它们分配给项目。项目是在一个下拉菜单中选择的,我用的是 selectizeInput 构建,但得到的东西类似于 selectInput

我想用一个 shiny::selectizeInput 之内 DT::datatable 在闪亮。我可以让下拉菜单工作。但是,我失去了selectize input的搜索功能。在我的玩具例子中,最上面的selectizeInput你可以点击并输入你要找的选项。在datatable内的那个,你还是可以做到这一点,但是对于复杂的名字,如果你能看到你输入的内容,对UX会更好。

我在github仓库里发现了这个问题,DT包的制作者说这样的东西可能无法实现。不过,这已经是3年前的事了,也许有人已经想出了解决方法。https:/github.comrstudioDTissues390

我也尝试过移动到不同的用户界面类型。tuicalendr对我的目的来说,这很好用,但我遇到了同样的问题。我在JS方面的经验是有限的,所以我在Shiny中定制JS时遇到了麻烦。

library(shiny)
library(DT)

ui <- fluidPage(
  selectizeInput("input", 
                 label = "",
                 choices = letters[1:26],
                 selected = letters[1]),
DTOutput("datatable")
)


server <- function(input, output) {

output$datatable<- renderDataTable({
  DT::datatable(data.frame(a = as.character(selectizeInput("dtinput",
                                label = "",
                                choices = letters[1:26],
                                selected = letters[1]),
             stringsAsFactors = F)),
             escape = F)
})


}

# Run the application 
shinyApp(ui = ui, server = server)

我对其他的方法持开放态度,最理想的方法是将数据显示在日历视图中,并在标题下方设置一个复选框和下拉菜单。但如果我能解决这个问题,我想我可以自己把代码改编成日历。

r shiny dt
1个回答
3
投票

必须手动添加javascript功能。相应的代码应该是。$('#ID').selectize().

为了得到所需的html代码,你可以运行。withTags(selectInput(inputId = "mselect", label = "multi", choices = letters[1:3], multiple = TRUE)). 你可以从那里提取所需的html部分。

在文档中,你会发现你可以用以下方法来交接javascript代码。JS(): the character options wrapped in JS() will be treated as literal JavaScript code instead of normal character strings.

你要在选择部分渲染后添加javascript代码。这是通过使用 initcomplete 选项。

为了使用输入的值,你必须将输入绑定到shiny上。

preDrawCallback = JS('function(){Shiny.unbindAll(this.api().table().node());}'),
drawCallback = JS('function(){Shiny.bindAll(this.api().table().node());}')

正如Remko所提到的,他的链接帖子非常有用。几乎所有这些信息都可以在帖子中找到。可能需要一些shiny的经验来创建一个可重复的例子,所以我为你添加了一个。

可复制的例子

library(shiny)
library(DT)

ui <- fluidPage(

  selectizeInput(
    inputId = "input",
    label = "",
    choices = letters[1:26],
    selected = letters[1]
  ),

  fluidRow(
    DTOutput(outputId = "table")
  )

)

#withTags(selectInput(inputId = "mselect", label = "multi", choices = letters[1:3], 
#    multiple = TRUE))
df <- data.frame(mselect = 
  '<select id="mselect" class="form-control" multiple="multiple">
     <option value="car">car</option>
     <option value="cars">cars</option>
     <option value="dog">dog</option>
  </select>'  
)


js <- c(
  "function(settings){",
  "  $('#mselect').selectize()",
  "}"
)

server <- function(input, output, session) {

  observe({
    print(input$mselect)
  })

  output$table <- renderDT({

    datatable(
      data = df,
      escape = FALSE,
      options = 
        list(
          initComplete = JS(js),
          preDrawCallback = JS('function(){Shiny.unbindAll(this.api().table().node());}'),
          drawCallback = JS('function(){Shiny.bindAll(this.api().table().node());}')
      )
    )

  })

}

shinyApp(ui = ui, server = server)
© www.soinside.com 2019 - 2024. All rights reserved.