1

I have a shiny app that uses knobInputs from shinywidgets. I need to change some of the parameters dynamically in the server. I know how to change the value of a knob using updateKnobInput, but I don't understand how to change the other parameters. Specifically, I need to set readOnly from FALSE to TRUE, when a certain thing is clicked by the user.

In the documentation of updateKnobInput it states: "options List of additional parameters to update, use knobInput's arguments." Unfortunately, I do not understand how to actually code this

Please see my example. When the user clicks the button, the knob's value should change from 50 to 15 (that works) and the knobs readOnly should change from FALSE to TRUE (that does not work).

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
    knobInput("myknob", label = "My Knob", min = 0, max = 100, value = 50, readOnly = F),
    actionButton("changeknob", label = "Change the knob")
)


server <- function(input, output, session) {
    observeEvent(input$changeknob, {
        updateKnobInput(session, "myknob", value = 15, options = list(readOnly = T))
    })
}


shinyApp(ui = ui, server = server)

Thank you very much for your help!

Jans
  • 13
  • 2
  • This looks like a bug. `shinyjs::disable()` does not work either on knobInputs. You can file an issue on https://github.com/dreamRs/shinyWidgets/issues – mnist Apr 06 '21 at 08:25

1 Answers1

0

After looking into the code of the widget, it seems to me that the API is buggy.

  • In principal the widget could receive a change in the readOnly attribute on the JavaScript side
  • However, this API is not implemented on the R side
  • Diving even further into the underlying jQuery Knob element it seems to me (but bear in mind that my JS is not that solid) that the readOnly attribute can be only set upon startup of the element.

To make a longs tory short, in my opinion with the current implementation of both shinyWidgets::knobInput and the jQuery knob widget itself it is not possible to achieve it in the way you want.

Thus, you need a workaround. You could re-render the widget based on the button press like in this example:

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
    uiOutput("knob_container"), 
    actionButton("changeknob", label = "Change the knob")
)


server <- function(input, output, session) {
    output$knob_container <- renderUI({
       was_pressed <- input$changeknob > 0
       knobInput("myknob", label = "My Knob", min = 0, max = 100, 
                 value = ifelse(was_pressed, 15, 50), readOnly = was_pressed)
    })
 }


shinyApp(ui = ui, server = server)
thothal
  • 16,690
  • 3
  • 36
  • 71
  • You are welcome, if this answers your question would you kindly accept this as an answer (using the checkmark in the answer)? – thothal Apr 12 '21 at 10:16