web-dev-qa-db-ja.com

DT :: datatable内のSelectizeInputはhtmlとしてのみ機能します

時間追跡アプリでエンドユーザー向けにUXを最適化しようとしています。基本的には、GoogleカレンダーのAPIからデータを取得し、tibbleに配置して、ユーザーが会議を選択/選択解除/編集してプロジェクトに割り当てようとします。プロジェクトは、ビルドにselectizeInputを使用したドロップダウンメニューで選択されていますが、selectInputのようなものを取得しています

Shinyのshiny::selectizeInput内でDT::datatableを使用したい。ドロップダウンを動作させることができます。ただし、selectize入力に付属している検索機能が失われています。私のおもちゃの例では、トップselectizeInputをクリックして、探しているオプションを入力できます。データテーブル内の1つでも、それを行うことができますが、複雑な名前を使用している場合は、入力している内容を確認できれば、UXの方が適しています。

私はこの問題をgithubリポジトリで見つけました。DTパッケージのメーカーは、このようなことは不可能かもしれないと言っていました。しかし、それは3歳です、おそらく誰かが回避策を考え出しました。 https://github.com/rstudio/DT/issues/39

また、別のUIタイプ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)

私は他のアプローチにも心を開いています。理想は、データをカレンダービューに表示し、タイトルのすぐ下にチェックボックスとドロップダウンメニューを表示することです。しかし、この問題を解決できれば、自分でコードをカレンダーに適合させることができると思います。

3
NotThatKindODr

手動でJavaScript機能を追加する必要があります。対応するコードは次のようになります:$('#ID').selectize()

追加する必要なhtmlコードを取得するには、withTags(selectInput(inputId = "mselect", label = "multi", choices = letters[1:3], multiple = TRUE))を実行します。そこから必要なhtml部分を抽出できます。

ドキュメントでは、JS()the character options wrapped in JS() will be treated as literal JavaScript code instead of normal character stringsを使用してJavaScriptコードを引き継ぐことができます。

選択部分がレンダリングされた後にJavaScriptコードを追加したいとします。これは、initcompleteオプションを使用することで保証されます。

入力の値を使用するには、入力を光沢にバインドする必要があります。

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

Remkoが言及したように、彼のリンクされた投稿は非常に役立ちます。この情報のほとんどすべてが実際に投稿で利用できます。再現可能な例を作成するには、光沢のある経験が必要になる可能性があるため、次の例を追加しました。

再現可能な例:

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)
3
Tonio Liebrand