本日は、numericInput
という数字を入力するUIパーツのバグの話です。
numericInput
で出てくるスピンをクリックして入力している間はmax, minで指定した範囲を超える入力ができないように
なっていますが、BOXに直接入力すると指定範囲を超えていても値が反映されてしまいます。
困ったことにnumericInputのようなreactiveパーツは入力結果が即他の参照部分に波及するので
対応処理を加えておかないとエラーなど思わぬ動きの原因になります。
基本は入力数値を利用する際に処理を加えることになるかと思いますが、ここでは入力BOX直後のプロセスを修正して
範囲外の入力値を受け付けないようにする方法を紹介します。
結果は以下のサンプルコードを見てもらえばわかるとおもいますが、
numericInput
で入力された値を直接は使わずに、範囲チェック(CAPロジック)を入れている点がポイントです。
その後の処理はCAPチェックをかけた後のoutValue()
を利用して各種処理が行えます。
注意点としては、numericInputから得た値(以下の例では、input$testInput
)や`outValue()はreactive環境でのみ利用可能なので、
observe( )やreactive( )などの中で使う必要がある点です。
library(shiny) ui <- fluidPage( column(width=6, numericInput(inputId = "testInput", label = "Test Input", value = 70, min = 0, max = 100, step = 1, width = "50%" ), #CAP後の入力結果の出力 verbatimTextOutput("newValue") ) ) server <- function(session, input, output) { #上下CAPを適用するロジック outValue = reactive({ if(input$testInput > 100) return(100) else if(input$testInput < 0) return( 0) else return(input$testInput) }) #CAP後の値を出力BOXに描画:その後のプログラムではこのoutValue値を利用すればよい。 output$newValue <- renderText({ outValue() }) #CAP後の値を入力ボックスにUpdate observe({ updateNumericInput(session=session, inputId = "testInput", value = outValue()) }) } shinyApp(ui, server)
もしくはserver
部分は一連の処理をobserve( )
で囲んでも同じ挙動となります。この場合はoutValue
はobserve( )
の中で
作成した変数なので上記とは異なり変数の後に( )
がなくてもOKです。
server <- function(session, input, output) { observe({ if(input$testInput > 100) { outValue = 100 } else if(input$testInput < 0) { outValue = 0 } else { outValue = input$testInput } updateNumericInput(session=session, inputId = "testInput", value = outValue) output$newValue <- renderText({ outValue }) }) }