-1

MWE は次のとおりです。

library(shiny)

runApp(shinyApp(
ui = pageWithSidebar(

  fluidRow(
    column(3, wellPanel(

    numericInput("numFields", "Select number of fields", 2, min = 1),
    br(),
    uiOutput("fields"),
    br(),
    actionButton("goButton", "Go!")

    )),

    column(3, wellPanel(      
      uiOutput("morefields")      
    )),

    column(3, wellPanel(

      numericInput("numFields2", "Select number of fields 2", 2, min = 1),
      br(),
      actionButton("goButton2", "Go2!")      

    ))    
  ),

server = function(input, output, session){

  output$fields <- renderUI({
    numFields <- as.integer(input$numFields)
    lapply(1:numFields, function(i) {
      textInput(paste0("field", i), paste0("Type in field ", i))
    })
  })

  output$morefields <- renderUI({

    if (input$goButton == 0) return(NULL)

    isolate({
      numFields <- as.integer(input$numFields)
      lapply(1:numFields, function(i) {
        checkboxInput(paste0("checkbox", i), paste0("Checkbox for field ",
                                                input[[paste0("field", i)]]))
      })
    })
  })

  observeEvent(input$goButton2, {
    numFields2 <- as.integer(input$numFields2)
    last_field <- paste0("field", numFields2)
    updateNumericInput(session, "numFields", value = numFields2)
    updateTextInput(session, "field1", value = "This is the first field")
    updateTextInput(session, last_field, value = "This is the last field")
  })

}))

ここで、次の一連のアクションを実行します。

  1. アプリの起動
  2. の値Select number of fields 2をたとえば 3に設定します
  3. Go2!ボタンを押します
  4. 左側の列で入力フィールドの数が変更されていますが、最初と最後のフィールドにテキストを入力したいので、Go2!もう一度ボタンをクリックします
  5. ボタンをクリックするGo!と、真ん中のUIが生成されます。

私の目的は、ステップ 4 と 5 を回避することですが、同じ結果を得ることです。

reactiveValues-変数とシミュレートされたクリックで問題を解決しようとしました(ここで提案されているように):

library(shiny)
library(shinyjs)
jscode <- "shinyjs.click = function(id) { $('#' + id).click(); }"

runApp(shinyApp(
ui = pageWithSidebar(

  useShinyjs(),
  extendShinyjs(text = jscode),

  fluidRow(...)),

server = function(input, output, session){

  vals <- reactiveValues(update = 0)

  output$fields <- renderUI({...})

  output$morefields <- renderUI({...})

  observeEvent(input$goButton2, {
    numFields2 <- as.integer(input$numFields2)
    updateNumericInput(session, "numFields", value = numFields2)
    vals$update <- 1
  })

  observeEvent(vals$update, {
    if (vals$update != 1) return(NULL)

    numFields2 <- as.integer(input$numFields2)
    last_field <- paste0("field", numFields2)
    updateTextInput(session, "field1", value = "This is the first field")
    updateTextInput(session, last_field, value = "This is the last field")

    vals$update <- 2
  })

  observeEvent(vals$update, {
    if (vals$update != 2) return(NULL)    
    js$click("goButton")
    vals$update <- 0
  })

}))

これで 2 番目の UI が生成されましたが、フィールドは空のままです。Go2!すべての UI が完全に更新されるまでに 3 回クリックする必要があります。

server-part内で次のことも試しました:

  observeEvent(input$goButton2, {
    numFields2 <- as.integer(input$numFields2)
    updateNumericInput(session, "numFields", value = numFields2)
  }, priority = 2)

  observeEvent(vals$update, {
    numFields2 <- as.integer(input$numFields2)
    last_field <- paste0("field", numFields2)
    updateTextInput(session, "field1", value = "This is the first field")
    updateTextInput(session, last_field, value = "This is the last field")
  }, priority = 1)

  observeEvent(input$goButton2, {
    js$click("goButton")
  }, priority = 0)

この場合も、イベントの経過は少し異なりますが、必要なものを得るには 3 回クリックする必要があります。

ボタンを 1 回だけクリックして最終結果を得る方法について何か提案はありGo2!ますか?

4

1 に答える 1

2

私はあなたのアイデアを拡張して機能させることができましたが、それが最も美しい解決策ではないことを認めなければなりません. 最初の問題は、値を更新する呼び出しを行う前に、テキスト フィールドが生成されていることを確認する必要があることでした。

    isolate(
      if (vals$update == 1) {
        vals$update <- 2
      }
    )

output$fieldsそれに応じて残りの val$update 値を変更しました。これで手順 4 は処理されました。次の問題 (手順 5 を修正するため) は、テキスト入力が更新される前にラジオ ボタンの作成が呼び出されることがあるということでした。更新がいつ行われたかをシャイニーに知らせる方法がわからないので、代わりに、ボタンをクリックする JavaScript を変更して、クリックする前に 50 ミリ秒待機するようにしました。

jscode <- "shinyjs.click = function(id) { setTimeout(function(){ $('#' + id).click(); }, 50); }"

繰り返しますが、これは最適ではありませんが、遅く、少なくとも機能し、基礎として使用できるものです。ここに完全なコードがあります

library(shiny)
library(shinyjs)
jscode <- "shinyjs.click = function(id) { setTimeout(function(){ $('#' + id).click(); }, 50); }"

runApp(shinyApp(
  ui = fluidPage(
    useShinyjs(),
    extendShinyjs(text = jscode),

    fluidRow(
      column(3, wellPanel(

        numericInput("numFields", "Select number of fields", 2, min = 1),
        br(),
        uiOutput("fields"),
        br(),
        actionButton("goButton", "Go!")

      )),

      column(3, wellPanel(      
        uiOutput("morefields")      
      )),

      column(3, wellPanel(

        numericInput("numFields2", "Select number of fields 2", 2, min = 1),
        br(),
        actionButton("goButton2", "Go2!")      

      ))    
    )),

    server = function(input, output, session){
      vals <- reactiveValues(update = 0)

      output$fields <- renderUI({
        isolate(
          if (vals$update == 1) {
            vals$update <- 2
          }
        )
        numFields <- as.integer(input$numFields)
        lapply(1:numFields, function(i) {
          textInput(paste0("field", i), paste0("Type in field ", i))
        })
      })

      output$morefields <- renderUI({

        if (input$goButton == 0) return(NULL)

        isolate({
          numFields <- as.integer(input$numFields)
          lapply(1:numFields, function(i) {
            checkboxInput(paste0("checkbox", i), paste0("Checkbox for field ",
                                                        input[[paste0("field", i)]]))
          })
        })
      })

      observeEvent(input$goButton2, {
        numFields2 <- as.integer(input$numFields2)
        vals$update <- 1
        updateNumericInput(session, "numFields", value = numFields2)
      })

      observeEvent(vals$update, {
        if (vals$update != 2) return(NULL)

        numFields2 <- as.integer(input$numFields2)
        last_field <- paste0("field", numFields2)
        updateTextInput(session, "field1", value = "This is the first field")
        updateTextInput(session, last_field, value = "This is the last field")

        vals$update <- 3
      })

      observeEvent(vals$update, {
        if (vals$update != 3) return(NULL)    
        js$click("goButton")
        vals$update <- 0
      })

    })
)

お役に立てれば

于 2015-07-21T08:08:19.350 に答える