rstudio / DT

R Interface to the jQuery Plug-in DataTables
https://rstudio.github.io/DT/
Other
596 stars 182 forks source link

DT not shown when it's the child of a <details> element #690

Open rubenarslan opened 5 years ago

rubenarslan commented 5 years ago

I wanted to make DTs that can be toggled/minimally displayed behind a details arrow, but the DT isn't shown (all the code is there though).

(It works in a hidden tabset, unlike e.g. DiagrammeR, I guess it checks the anticipated height of the widget at some point during rendering?). To reproduce render the following Rmd.

<details>
<summary>Iris</summary>

```{r}
DT::datatable(iris)



<!--
Please keep the portion below in your issue. Your issue will be closed if any of the boxes is not checked. In certain (rare) cases, you may be exempted if you give a brief explanation (e.g., you are only making a suggestion for improvement). Thanks!
-->

---

By filing an issue to this repo, I promise that

- [x] I have fully read the issue guide at https://yihui.name/issue/.
- [x] I have provided the necessary information about my issue.
- [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.
yihui commented 5 years ago

Generally HTML Widgets won't actually be rendered until they are visible. There is a delayed rendering mechanism:

On the DT side

https://github.com/rstudio/DT/blob/7ddf590824b923f6df1d51c9fbc3940f1740e9df/inst/htmlwidgets/datatables.js#L114 https://github.com/rstudio/DT/blob/7ddf590824b923f6df1d51c9fbc3940f1740e9df/inst/htmlwidgets/datatables.js#L1205

On the htmlwidgets side

https://github.com/ramnathv/htmlwidgets/blob/853b1b0c6bd86d37f2245e7204fd6567fb5302d4/inst/www/htmlwidgets.js#L592-L642

When the content of <details> becomes visible, the resize method should be called, but currently htmlwidgets does not seem to be aware of the visibility changes of <details>. I don't know how to fix this issue. Sorry.

rubenarslan commented 5 years ago

Based on that code, I thought I could quickly fix it using <summary onclick="$(window).trigger('resize');"> or <summary onclick="$(window).trigger('slideenter');"> but that doesn't seem to change anything. Maybe it's something else after all?

Should I raise an issue in htmlwidgets instead?

yihui commented 5 years ago

If your try other widgets (e.g. leaflet) and find this issue is not specific to DT, I think it's worth filing an issue to htmlwidgets. Otherwise we need more debugging in DT, for which I don't have time.

timelyportfolio commented 5 years ago

@rubenarslan for some reason $('window').resize() and $('window').trigger('resize') do not invoke the htmlwidgets resize handler. Using window.dispatchEvent(new Event('resize')); does. See below.

<script>
  $(function() {
    $('details').on('toggle', function() {
      if(this.open) {
        // jquery $('window').resize or $('window').trigger('resize') do not work
        window.dispatchEvent(new Event('resize'));
      }
    })
  })
</script>

<details>
<summary>Iris</summary>

```{r}
DT::datatable(iris)



As to the broader issue of where this issue should be solved, I definitely don't think it should be in each `htmlwidget` like `DT`.  Also, there are many events that "should" probably trigger `resize` in `htmlwidgets`, but I think the decision has been that it is beyond the scope to handle all of these events from all of the various frameworks and elements.  However, I am most certainly not the final authority on this, so feel free to file an issue on `htmlwidget` if you like.
rubenarslan commented 5 years ago

@timelyportfolio thanks for the fix. I can see that the <details> element is a bit niche, so I'll hold off on filing another issue. It doesn't happen with leaflet though. Maybe I'll dig into it at some later point.

Related Diagrammer issue

glin commented 2 years ago

From an RStudio Community post, some users have found that DT tables in <details> actually render fine in Chrome, but not other browsers like Safari/Firefox. Here's some more detail on that:

Apparently, a recent Chrome 97 update changed how <details> works, and content within collapsed <details> is now rendered (but still hidden) so find-in-page works for the hidden content. So in Chrome 97+, the widget will actually have a non-zero width inside <details> and get rendered correctly. The <details> change was added to the HTML spec, so Firefox/Safari may eventually work the same way.