jrowen / rhandsontable

A htmlwidgets implementation of Handsontable.js
http://jrowen.github.io/rhandsontable/
Other
383 stars 148 forks source link

How to dynamically resize a handsontable in a shiny app #355

Open javierdiegof opened 4 years ago

javierdiegof commented 4 years ago

Hi :)

I'm displaying a variable size data frame inside a shiny app using a handsontable. I want to implement a funcionality similar to CSS' property max-width, that is, I want the handsontable's height to take exactly the space associated to the amount of rows currently set until the table grows to a certain size, and after that size is reached, the hansontable should have a fixed height and not increase in size at all (a scroll should be shown after that point).

The default height property in the handsontable package is not useful since it will take a constant height no matter if the table rows take way less space than that height.

Since the max-height property is not available inside handson table (see this link, for example), the approach I'm currently trying is to dynamically set the height of the handsontable inside the renderRHandsontable function. Returning to it the appropriately formatted rhandsontable, with its height dynamically set inside the render.

That approach is not working. The reason is that the rHandsontableOutput function that generates the UI element has already defined the height and width of the element. So the values set inside the renderRHandsontable are not taken into account and are overriden by the ones specified inside the rHandsontableOutput.

Is there any way to display the handsontable just as the rhandsontable configures it, in a similar fashion as the one that would be displayed using the RStudio viewer?

Thanks in advance and I congratulate the great work you've done with the package!

D3SL commented 3 years ago

I solved this issue with the below javascript. Place it in your UI (tags$script or directly using shinyJS) and then you can reference input$dimension[0] for viewport width and 1 for height. The trick is rhandsontable doesn't seem to calculate height the way you'd expect, especially if you're using display scaling and/or zoom, so the results are a little fiddly.

Additionally anytime anything triggers the resizing you'll lose all user input. Essentially the table resets back to its state on first loading, and sends that as input to hot_to_r() as well.

  var dimension = [0, 0];
  $(document).on("shiny:connected", function(e) {
      dimension[0] = window.innerWidth;
      dimension[1] = window.innerHeight;
      Shiny.onInputChange("dimension", dimension);
  });
  $(window).resize(function(e) {
      dimension[0] = window.innerWidth;
      dimension[1] = window.innerHeight;
      Shiny.onInputChange("dimension", dimension);
  });