Skip to content

Commit 4777b5f

Browse files
committed
fix datatable style issue when display none at init
1 parent ee61b0e commit 4777b5f

File tree

2 files changed

+41
-26
lines changed

2 files changed

+41
-26
lines changed

pywebio/output.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,7 @@ def put_grid(content: List[List[Union[Output, None]]], cell_width: str = 'auto',
13931393
The format of width/height value in ``cell_width``,``cell_height``,``cell_widths``,``cell_heights``
13941394
can refer to the ``size`` parameter of the `put_row()` function.
13951395
1396-
:Example:
1396+
Example:
13971397
13981398
.. exportable-codeblock::
13991399
:name: put_grid
@@ -1515,6 +1515,7 @@ def put_datatable(
15151515
When not provide, the datatable will use the index in ``records`` to assign row ID.
15161516
:param int/str height: widget height. When pass ``int`` type, the unit is pixel,
15171517
when pass ``str`` type, you can specify any valid CSS height value.
1518+
In particular, you can use ``'auto'`` to make the widget auto-size it's height to fit the content.
15181519
:param str theme: datatable theme.
15191520
Available themes are: 'balham' (default), 'alpine', 'alpine-dark', 'balham-dark', 'material'.
15201521
:param bool cell_content_bar: whether to add a text bar to datatable to show the content of current focused cell.
@@ -1529,7 +1530,8 @@ def put_datatable(
15291530
:param str enterprise_key: `ag-grid enterprise <https://www.ag-grid.com/javascript-data-grid/licensing/>`_ license key.
15301531
When not provided, will use the ag-grid community version.
15311532
1532-
To pass JS function as value of ``column_args`` or ``grid_args``, you can use ``JSFunction`` object:
1533+
The ag-grid library is so powerful, and you can use the ``column_args`` and ``grid_args`` parameters to achieve
1534+
high customization. To pass JS functions as value of ``column_args`` or ``grid_args``, you can use ``JSFunction`` object:
15331535
15341536
.. py:function:: JSFunction([param1], [param2], ... , [param n], body)
15351537
@@ -1565,6 +1567,10 @@ def put_datatable(
15651567

15661568
if isinstance(height, int):
15671569
height = f"{height}px"
1570+
if height == 'auto' and len(records) > 1000:
1571+
height = '600px'
1572+
logger.warning("put_datatable: numbers of rows are too large to use auto height, use fix height instead")
1573+
15681574
if isinstance(id_field, str):
15691575
id_field = [id_field]
15701576

@@ -1938,20 +1944,6 @@ def popup(title: str, content: Union[str, Output, List[Union[str, Output]]] = No
19381944
After the context manager exits, the popup window will not be closed.
19391945
You can still use the ``scope`` parameter of the output function to output to the popup.
19401946
1941-
* decorator:
1942-
1943-
.. exportable-codeblock::
1944-
:name: popup-decorator
1945-
:summary: `popup()` as decorator
1946-
1947-
@popup('Popup title')
1948-
def show_popup():
1949-
put_html('<h3>Popup Content</h3>')
1950-
put_text("I'm in a popup!")
1951-
...
1952-
1953-
show_popup()
1954-
19551947
"""
19561948
if content is None:
19571949
content = []

webiojs/src/models/datatable.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {pushData} from "../session";
22

33
const tpl = `<div>
4-
<div class="ag-theme-{{theme}} ag-grid" style="width: 100%; height: {{height}}"></div>
4+
<div class="ag-theme-{{theme}} ag-grid" style="width: 100%; height: {{height}}">
5+
<div class="grid-loading">⌛️ Loading Datatable...</div>
6+
</div>
57
<div class="ag-grid-cell-bar"></div>
68
<div class="ag-grid-tools">
79
<div class="grid-status">
@@ -239,6 +241,7 @@ export let Datatable = {
239241
spec.field_args = parse_js_func(spec.field_args, spec.js_func_key);
240242
spec.path_args = parse_js_func(spec.path_args, spec.js_func_key);
241243
spec.grid_args = parse_js_func(spec.grid_args, spec.js_func_key);
244+
let auto_height = spec.height == 'auto';
242245

243246
let options = row_data_and_column_def(spec.records, spec.field_args, spec.path_args);
244247

@@ -294,17 +297,36 @@ export let Datatable = {
294297
},
295298
onGridReady: (param: any) => {
296299
grid_resolve(gridOptions);
300+
if (auto_height) {
301+
gridOptions.api.setDomLayout('autoHeight');
302+
}
297303

298-
gridOptions.columnApi.autoSizeAllColumns();
299-
let content_width = 0;
300-
gridOptions.columnApi.getColumns().forEach((column:any) => {
301-
if(!column.getColDef().hide)
302-
content_width += column.getActualWidth();
303-
});
304-
if (content_width < elem.find(".ag-grid")[0].clientWidth) {
305-
// the content is smaller than the grid, so we set columns to adjust in size to fit the grid horizontally
306-
gridOptions.api.sizeColumnsToFit();
304+
let grid_elem = elem.find(".ag-grid")[0];
305+
let on_grid_show = Promise.resolve();
306+
if (grid_elem.clientWidth === 0) { // the grid is hidden via `display: none`, wait for it to show
307+
on_grid_show = new Promise((resolve) => {
308+
// @ts-ignore
309+
let observer = new ResizeObserver((entries, observer) => {
310+
if (grid_elem.clientWidth > 0) {
311+
observer.disconnect();
312+
resolve();
313+
}
314+
});
315+
observer.observe(grid_elem);
316+
});
307317
}
318+
on_grid_show.then(() => {
319+
gridOptions.columnApi.autoSizeAllColumns();
320+
let content_width = 0;
321+
gridOptions.columnApi.getColumns().forEach((column: any) => {
322+
if (!column.getColDef().hide)
323+
content_width += column.getActualWidth();
324+
});
325+
if (content_width < grid_elem.clientWidth) {
326+
// the content is smaller than the grid, so we set columns to adjust in size to fit the grid horizontally
327+
gridOptions.api.sizeColumnsToFit();
328+
}
329+
})
308330

309331
if (spec.actions.length > 0) {
310332
elem.find('.ag-grid-tools').css('opacity', 1);
@@ -367,6 +389,7 @@ export let Datatable = {
367389
let ag_version = spec.enterprise_key ? 'ag-grid-enterprise' : 'ag-grid';
368390
// @ts-ignore
369391
requirejs([ag_version], function (agGrid) {
392+
elem.find('.grid-loading').remove();
370393
new agGrid.Grid(elem.find(".ag-grid")[0], gridOptions);
371394
if (spec.instance_id) {
372395
// @ts-ignore

0 commit comments

Comments
 (0)