0

I'm using a piece of javascript from this question: SO

It works for buttons, but I would also like to disable things like sliderInput, selectInput and textInput as well.

I tried to replace the 'button' with 'input' which does disable the textinput fields. I am wondering whether there is a way to disable all elements in 1 go.

The bigger problem is the following: When you open the dropdownbutton, the close button normally should remove the modal dialog in case the javascript tag is removed from the demo app below. However, when the script is in the app, the close button doesn't work anymore for some reason. It still prints the text command, meaning it is observed, but the modal doesn't close. The other button in the dialog still works normally.

App:

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  h3('Disable buttons while running'),
  actionButton('btn_run','Run long process'),
  hr(),
  h3('Inputs'),
  actionButton('btn1','Button 1'),
  hr(),
  textInput('text1', 'Text1',"my text:"),
  hr(),
  selectInput('select1', 'Selectinput', choices = c('A', 'B', 'C'), selected = 'A'),
  hr(),
  h5('Dropdown'),
  dropdownButton(inputId = "MyDropDown",
                 h3("This is a dropdown"),
                 actionButton('btn_run2','Run other long process'),
                 fluidRow(actionButton( "CloseDropDown", "Close"), style = "float: right; margin-right:10px"),
                 icon = icon("tasks"),
                 tooltip = tooltipOptions(title = "Click to open"), width = "500px"),
  hr(),
  sliderInput('slid3','Slider 1',min=0,max=1,value=0.5),


tags$script(HTML("$(document).on('shiny:busy', function() {
  var inputs = document.getElementsByTagName('button');
console.log(inputs);
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = true;
}
});

$(document).on('shiny:idle', function() {
var inputs = document.getElementsByTagName('button');
console.log(inputs);
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = false;
}
})" ))
)

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

  observeEvent(input$btn_run,{
    Sys.sleep(5)
  })


  observeEvent(input$btn_run2,{
    Sys.sleep(5)
  })

  observeEvent(input$CloseDropDown, {print('closing?')
    toggleDropdownButton(inputId = 'MyDropDown') })

}

shinyApp(ui = ui, server = server)
Mark
  • 2,789
  • 1
  • 26
  • 66

1 Answers1

1

I cannot help you with the close button, though I found out that as soon as you set your shiny:idle handle, any call to JavaScript will fire shiny:idle and hence runs the handler instead of the JavaScript code behind toggleDropdownButton.

However, the first question of how to select more than one element in your JavaScript can be solved with a bit of jQuery. Change your code to

$(document).on('shiny:busy', function() {
  var $inputs = $('button,input');
console.log($inputs);
$inputs.prop('disabled', true);
});

$(document).on('shiny:idle', function() {
var $inputs = $('button,input');
console.log($inputs);
$inputs.prop('disabled', false);
})

With that you can select buttons and the text input. Now you can find out yourself which code to use to also disable the dropdown.

BTW: maybe you want to look at shinyjs::disable. With this function you can disable your controls from the R side. You would put that in the beginning of your long calculation and use shinyjs::enable at the end.

thothal
  • 16,690
  • 3
  • 36
  • 71
  • can you confirm that the close button isn't working? The maker of shinywidgets said to download the github version, but that didn't solve it either for me – Mark Sep 14 '18 at 17:39
  • was a matter of him pushing the latest version. fixed now by running devtools::install_github("dreamRs/shinyWidgets") – Mark Sep 15 '18 at 16:49
  • Any clue which keywords target sliders and selectinput? Having difficulty finding them – Mark Sep 15 '18 at 16:56
  • shinyjs::disable and enable I also use by the way, but they don't work for 'busy'. The app can calculate my entire model and plots in seconds, but the rendering of the plots sometimes takes 30 seconds (Plotly is very heavy to use), and R will think it's ok to enable long before app stops being busy. The javascript solution works perfect though. Now just need to find the right tags to target – Mark Sep 15 '18 at 18:02