R语言 如何在selectizeInput中进行相同顺序的选择,同时单击或键入?

ijxebb2r  于 2023-03-27  发布在  其他
关注(0)|答案(1)|浏览(113)

我做了一个选择向量。当我点击selectizeInput时,我得到的选择顺序与我的向量中的顺序相同,但是当我开始输入selectizeInput时,我的选择顺序与我的向量中的顺序不同。
这是一个shiny app的例子。

library(shiny)

choices <- c("First choice", "Second choice", "Choice third", "Fourth choice", "Choice fifth")

ui <- fluidPage(

    selectizeInput("id", 
                   "My input", 
                   choices = choices,
                   multiple = TRUE,
                   options = list(placeholder = "All choices")
                   )
    )

server <- function(input, output) {

    
}

shinyApp(ui = ui, server = server)

当我点击输入选项时,按此顺序。https://i.stack.imgur.com/1tScm.png
在我开始输入“ch”之后,选择的顺序与第一张图片不一样。
https://i.stack.imgur.com/k5ofy.png
如何使选择总是按照相同的顺序进行?

2ul0zpep

2ul0zpep1#

首先,您看到的行为是有意的。selectize.jsselectInput的底层JavaScript库)使用sifter.js(另一个负责搜索行为的JavaScript库)。
sifter的默认设置是根据最佳得分对搜索结果进行排名(字符串开头的匹配项得分高于字符串中间的匹配项)。因此,您可以看到顺序是“混合”的,开头有匹配项的元素得分较高,因此排名较高。
幸运的是,你可以用一点JavaScript来覆盖这种行为。返回结果的顺序可以通过selectize.js的设置中的sortField属性来控制。默认情况下,这等于$order,查看selectize.js的文档,你可以看到,如果没有显式的$score字段,结果将根据$score进行优先排序,然后根据sortField属性中指定的字段进行排序。
因此,我们所需要的就是在$order之后显式地将$score字段添加到scoreField,这样结果首先根据内在顺序进行排序,然后然后到得分。
最后一块拼图是确定在哪里我们可以称之为自定义JavaScript B/c,原因很明显,在尝试更改其设置之前,输入元素必须已经存在。
我发现最简单的地方是等待shiny发出一个输入元素被绑定的信号。
长话短说,下面是确保搜索结果按顺序显示的代码:

library(shiny)

choices <- c("First choice", "Second choice", "Choice third", "Fourth choice", 
             "Choice fifth")

js <- HTML("
   $(document).on('shiny:bound', function(evt) {
      if (evt.target.id == 'id') {
         evt.target.selectize.settings.sortField = [{field: '$order'}, {field: '$score'}];
      }
   });
"
   
)

ui <- fluidPage(
   singleton(tags$head(tags$script(js))),
   selectizeInput("id", 
                  "My input", 
                  choices = choices,
                  multiple = TRUE,
                  options = list(placeholder = "All choices")
   )
)

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

}

shinyApp(ui = ui, server = server)

相关问题