komodovaran_
komodovaran_

Reputation: 2012

Interconnect slider and numeric input in Shiny

I want a slider for quick, visual input, but also a corresponding numeric input for exact calculations. I've managed to tie the slider value to input$, so they will follow whatever is written in the numeric inputs. However, I can't seem to make it work the other way around.

ui

    numericInput("num_l",
                 label = "Beam length in m.",
                 value = 10),

    numericInput("num_a",
                 label = "Choose position, where to apply force, starting from left, in m.",
                 value = input$slider_a), # THIS DOESN'T WORK

    numericInput("num_x",
                 label = "Calculate the deflection, at position starting from left, in m.",
                 value = input$slider_x), # NEITHER DOES THIS

server

output$slider <- renderUI({
    tagList( # Need this for multiple reactive sliders
        sliderInput("slider_a",
                    label = "Load force position:",
                    min = 0,
                    max = input$num_l,
                    value = input$num_a, # THIS WORKS
                    step = 0.1),

        sliderInput("slider_x",
                    label = "Deflection calculation position:",
                    min = 0,
                    max = input$num_l,
                    value = input$num_x, # THIS ALSO WORKS
                    step = 0.1)
    )
})

Upvotes: 5

Views: 2191

Answers (1)

Jakub Małecki
Jakub Małecki

Reputation: 634

Use update functions:

ui <- fluidPage(

      numericInput("num_i",
                   label = "my input:",
                   value = 4,
                   min = 0,
                   max = 10),

      sliderInput("num_s",
                  label = "my slider:",
                  value = 4,
                  min = 0,
                  max = 10)
    )


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

      observe({

        updateSliderInput(
          session = session,
          inputId = "num_s",
          value = input$num_i
        )
      })


      observe({

        updateSliderInput(
          session = session,
          inputId = "num_i",
          value = input$num_s
        )
      })
    }


shinyApp(ui, server)

However, it may cause some problems because the numeric input's update triggers updating the slider and vice versa. I noticed that one can encounter an infinite loop. I don't know how to solve this issue, so I'll be waiting for other answers of more advanced shiny developers.

One of possible solutions to the problem is following: you update an input control using jQuery functions. A slider is updated using a standard observer on server side. But, updating a control with jQuery isn't reflected on server, the update takes its effect only in a client (web browser). It seems to be not a problem, because you can track the slider and use its value in your application's code. The second control is only for display purposes.

So, write a jQuery function like this:

$('document').ready(function(){
  $('#num_s').change(function(){
    var new_val = $(this).val();
    $('#num_i').val(new_val);
  });
});

Save it in www folder and next include the file in your application using includeScript().

Upvotes: 2

Related Questions