@yuneta/gobj-ui 7.23.49 → 7.23.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/gobj-ui.cjs.js +70 -1
- package/dist/gobj-ui.es.js +70 -1
- package/package.json +1 -1
- package/src/c_yui_treedb_topic_with_form.css +14 -4
- package/src/c_yui_treedb_topic_with_form.js +146 -2
- package/src/tabulator.css +27 -0
package/README.md
CHANGED
|
@@ -1780,6 +1780,51 @@ this facility: it is `formatter: "rowSelection"` with no `titleFormatter` and
|
|
|
1780
1780
|
`selectableRows: 1`, and the header checkbox, the count and the bar all mean
|
|
1781
1781
|
nothing there.
|
|
1782
1782
|
|
|
1783
|
+
### Clearing a header filter — `yui_table_filter_clear.js`
|
|
1784
|
+
|
|
1785
|
+
A column filter is set by typing and undone by deleting what you typed, letter
|
|
1786
|
+
by letter, and nothing in the header says it can be dropped at all. With
|
|
1787
|
+
several columns filtered, getting back to the whole table is an exercise in
|
|
1788
|
+
remembering which ones you touched. One call, on a table that is already built:
|
|
1789
|
+
|
|
1790
|
+
```js
|
|
1791
|
+
import {yui_table_filter_clear} from "@yuneta/gobj-ui/src/yui_table_filter_clear.js";
|
|
1792
|
+
|
|
1793
|
+
table.on("tableBuilt", () => {
|
|
1794
|
+
yui_table_filter_clear(table);
|
|
1795
|
+
});
|
|
1796
|
+
```
|
|
1797
|
+
|
|
1798
|
+
The app must define the i18n key **`"clear"`**. Three decisions are baked in:
|
|
1799
|
+
|
|
1800
|
+
- **The ✕ is visible whenever the filter has content, focus or not** — the
|
|
1801
|
+
opposite of the ✕ in a form (`yui_inputs.js`), which shows only on the field
|
|
1802
|
+
being edited so a form full of filled fields does not light up an ✕ on every
|
|
1803
|
+
one. Here the filter is already set, the focus is elsewhere, and the whole
|
|
1804
|
+
point is to see it and drop it; hidden behind focus it would take two clicks.
|
|
1805
|
+
- **It clears through `setHeaderFilterValue()`**, not by synthesising a
|
|
1806
|
+
keystroke on the input — what a header filter listens to depends on that
|
|
1807
|
+
column's filter editor.
|
|
1808
|
+
- **It decorates the header by walking it**, because a table's columns are
|
|
1809
|
+
often built from data (a treedb schema) and the header rebuilds itself when
|
|
1810
|
+
they change. The walk is idempotent and gated by a single `querySelector`, so
|
|
1811
|
+
repeating it on every render costs nothing.
|
|
1812
|
+
|
|
1813
|
+
### Searching a row that is not flat — `yui_row_search.js`
|
|
1814
|
+
|
|
1815
|
+
`row_matches(row, term)` is what the treedb topic table's search box uses, and
|
|
1816
|
+
it exists because **a treedb row is not flat**: with `list_dict` an fkey
|
|
1817
|
+
arrives as a list of objects — `[{id, topic_name, hook_name}]` — and
|
|
1818
|
+
`String(val)` of that is `"[object Object]"`. A search written the obvious way
|
|
1819
|
+
therefore never finds the place a node is linked to, while the cell plainly
|
|
1820
|
+
renders that id: what you see and what is searched are not the same thing.
|
|
1821
|
+
|
|
1822
|
+
It walks into lists and objects, and reads only the **`id`** of an fkey:
|
|
1823
|
+
`topic_name` and `hook_name` are the same two words on every row, so matching
|
|
1824
|
+
them turns any such term into a wildcard over the whole topic. Keys starting
|
|
1825
|
+
with `_` are never searched, at any level — scaffolding (`_operation`) and
|
|
1826
|
+
metadata (`__md_treedb__`).
|
|
1827
|
+
|
|
1783
1828
|
## Conventions
|
|
1784
1829
|
|
|
1785
1830
|
### i18n: a string must be able to CHANGE language, not just be translated once
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -22864,6 +22864,33 @@ function delete_impact(desc, records) {
|
|
|
22864
22864
|
* Constants
|
|
22865
22865
|
***************************************************************/
|
|
22866
22866
|
var GCLASS_NAME$5 = "C_YUI_TREEDB_TOPIC_WITH_FORM";
|
|
22867
|
+
var PAGE_SIZE_STORE_PREFIX = "yui_treedb_page_size:";
|
|
22868
|
+
/************************************************************
|
|
22869
|
+
* The size the reader left, or null when there is none.
|
|
22870
|
+
* `true` is Tabulator's "All" and it round-trips as the boolean:
|
|
22871
|
+
* JSON.parse gives it back as one, and a string "true" would be
|
|
22872
|
+
* read by Tabulator as a size of NaN.
|
|
22873
|
+
************************************************************/
|
|
22874
|
+
function load_page_size(gobj) {
|
|
22875
|
+
try {
|
|
22876
|
+
let raw = window.localStorage.getItem(PAGE_SIZE_STORE_PREFIX + (0, _yuneta_gobj_js.gobj_name)(gobj));
|
|
22877
|
+
if (raw === null) return null;
|
|
22878
|
+
let size = JSON.parse(raw);
|
|
22879
|
+
if (size === true) return true;
|
|
22880
|
+
if (typeof size === "number" && size > 0) return size;
|
|
22881
|
+
return null;
|
|
22882
|
+
} catch (e) {
|
|
22883
|
+
return null;
|
|
22884
|
+
}
|
|
22885
|
+
}
|
|
22886
|
+
/************************************************************
|
|
22887
|
+
*
|
|
22888
|
+
************************************************************/
|
|
22889
|
+
function save_page_size(gobj, size) {
|
|
22890
|
+
try {
|
|
22891
|
+
window.localStorage.setItem(PAGE_SIZE_STORE_PREFIX + (0, _yuneta_gobj_js.gobj_name)(gobj), JSON.stringify(size));
|
|
22892
|
+
} catch (e) {}
|
|
22893
|
+
}
|
|
22867
22894
|
/***************************************************************
|
|
22868
22895
|
* Data
|
|
22869
22896
|
***************************************************************/
|
|
@@ -22920,6 +22947,7 @@ var PRIVATE_DATA$5 = {
|
|
|
22920
22947
|
_pending_pages: null,
|
|
22921
22948
|
_page_seq: 0,
|
|
22922
22949
|
_page_total: null,
|
|
22950
|
+
_page_size: null,
|
|
22923
22951
|
$container: null,
|
|
22924
22952
|
treedb_name: "",
|
|
22925
22953
|
topic_name: "",
|
|
@@ -23806,6 +23834,9 @@ function create_tabulator(gobj) {
|
|
|
23806
23834
|
}
|
|
23807
23835
|
});
|
|
23808
23836
|
}
|
|
23837
|
+
let remembered_size = load_page_size(gobj);
|
|
23838
|
+
if (remembered_size !== null && tabulator_settings.pagination) tabulator_settings.paginationSize = remembered_size;
|
|
23839
|
+
gobj.priv._page_size = tabulator_settings.paginationSize;
|
|
23809
23840
|
Object.assign(tabulator_settings, {
|
|
23810
23841
|
index: pkey,
|
|
23811
23842
|
columns,
|
|
@@ -23841,12 +23872,26 @@ function create_tabulator(gobj) {
|
|
|
23841
23872
|
single_page = max === false || max <= 1;
|
|
23842
23873
|
} else {
|
|
23843
23874
|
let size = tabulator.getPageSize();
|
|
23844
|
-
single_page = !size || n <= size;
|
|
23875
|
+
single_page = size === true || !size || n <= size;
|
|
23845
23876
|
}
|
|
23846
23877
|
} catch (e) {
|
|
23847
23878
|
single_page = true;
|
|
23848
23879
|
}
|
|
23880
|
+
let total_rows;
|
|
23881
|
+
if (paged) total_rows = total;
|
|
23882
|
+
else try {
|
|
23883
|
+
total_rows = tabulator.getDataCount();
|
|
23884
|
+
} catch (e) {
|
|
23885
|
+
total_rows = n;
|
|
23886
|
+
}
|
|
23887
|
+
let min_size = 0;
|
|
23888
|
+
let sizes = tabulator.options ? tabulator.options.paginationSizeSelector : null;
|
|
23889
|
+
if (Array.isArray(sizes)) sizes.forEach(function(size) {
|
|
23890
|
+
if (typeof size === "number" && (!min_size || size < min_size)) min_size = size;
|
|
23891
|
+
});
|
|
23892
|
+
let no_paginator = single_page && (!min_size || typeof total_rows !== "number" || total_rows <= min_size);
|
|
23849
23893
|
tabulator.element.classList.toggle("yui-single-page", single_page);
|
|
23894
|
+
tabulator.element.classList.toggle("yui-no-paginator", no_paginator);
|
|
23850
23895
|
}
|
|
23851
23896
|
tabulator._ready = false;
|
|
23852
23897
|
tabulator.on("tableBuilt", function() {
|
|
@@ -23860,6 +23905,9 @@ function create_tabulator(gobj) {
|
|
|
23860
23905
|
});
|
|
23861
23906
|
tabulator.on("dataProcessed", update_rowcount);
|
|
23862
23907
|
tabulator.on("dataChanged", update_rowcount);
|
|
23908
|
+
tabulator.on("pageSizeChanged", function(size) {
|
|
23909
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_PAGE_SIZE_CHANGED", { size }, gobj);
|
|
23910
|
+
});
|
|
23863
23911
|
tabulator.on("cellEdited", function(cell) {
|
|
23864
23912
|
let pkey = ((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "desc") || {}).pkey || "id";
|
|
23865
23913
|
let data = cell.getRow().getData();
|
|
@@ -25311,6 +25359,21 @@ function ac_open_columns(gobj, event, kw, src) {
|
|
|
25311
25359
|
return 0;
|
|
25312
25360
|
}
|
|
25313
25361
|
/************************************************************
|
|
25362
|
+
* The reader picked another page size: remember it, so coming back to
|
|
25363
|
+
* this topic opens where they left it instead of at 200.
|
|
25364
|
+
************************************************************/
|
|
25365
|
+
function ac_page_size_changed(gobj, event, kw, src) {
|
|
25366
|
+
let size = kw ? kw.size : void 0;
|
|
25367
|
+
if (size !== true && !(typeof size === "number" && size > 0)) {
|
|
25368
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: bad page size: ${size}`);
|
|
25369
|
+
return -1;
|
|
25370
|
+
}
|
|
25371
|
+
if (size === gobj.priv._page_size) return 0;
|
|
25372
|
+
gobj.priv._page_size = size;
|
|
25373
|
+
save_page_size(gobj, size);
|
|
25374
|
+
return 0;
|
|
25375
|
+
}
|
|
25376
|
+
/************************************************************
|
|
25314
25377
|
* Show / hide one column.
|
|
25315
25378
|
************************************************************/
|
|
25316
25379
|
function ac_toggle_column(gobj, event, kw, src) {
|
|
@@ -25515,6 +25578,11 @@ function create_gclass$5(gclass_name) {
|
|
|
25515
25578
|
ac_open_columns,
|
|
25516
25579
|
null
|
|
25517
25580
|
],
|
|
25581
|
+
[
|
|
25582
|
+
"EV_PAGE_SIZE_CHANGED",
|
|
25583
|
+
ac_page_size_changed,
|
|
25584
|
+
null
|
|
25585
|
+
],
|
|
25518
25586
|
[
|
|
25519
25587
|
"EV_TOGGLE_COLUMN",
|
|
25520
25588
|
ac_toggle_column,
|
|
@@ -25565,6 +25633,7 @@ function create_gclass$5(gclass_name) {
|
|
|
25565
25633
|
["EV_REQUEST_PAGE", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
25566
25634
|
["EV_SEARCH", 0],
|
|
25567
25635
|
["EV_OPEN_COLUMNS", 0],
|
|
25636
|
+
["EV_PAGE_SIZE_CHANGED", 0],
|
|
25568
25637
|
["EV_TOGGLE_COLUMN", 0],
|
|
25569
25638
|
["EV_EXPORT_TABLE", 0],
|
|
25570
25639
|
["EV_CREATE_RECORD", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -22859,6 +22859,33 @@ function delete_impact(desc, records) {
|
|
|
22859
22859
|
* Constants
|
|
22860
22860
|
***************************************************************/
|
|
22861
22861
|
var GCLASS_NAME$5 = "C_YUI_TREEDB_TOPIC_WITH_FORM";
|
|
22862
|
+
var PAGE_SIZE_STORE_PREFIX = "yui_treedb_page_size:";
|
|
22863
|
+
/************************************************************
|
|
22864
|
+
* The size the reader left, or null when there is none.
|
|
22865
|
+
* `true` is Tabulator's "All" and it round-trips as the boolean:
|
|
22866
|
+
* JSON.parse gives it back as one, and a string "true" would be
|
|
22867
|
+
* read by Tabulator as a size of NaN.
|
|
22868
|
+
************************************************************/
|
|
22869
|
+
function load_page_size(gobj) {
|
|
22870
|
+
try {
|
|
22871
|
+
let raw = window.localStorage.getItem(PAGE_SIZE_STORE_PREFIX + gobj_name(gobj));
|
|
22872
|
+
if (raw === null) return null;
|
|
22873
|
+
let size = JSON.parse(raw);
|
|
22874
|
+
if (size === true) return true;
|
|
22875
|
+
if (typeof size === "number" && size > 0) return size;
|
|
22876
|
+
return null;
|
|
22877
|
+
} catch (e) {
|
|
22878
|
+
return null;
|
|
22879
|
+
}
|
|
22880
|
+
}
|
|
22881
|
+
/************************************************************
|
|
22882
|
+
*
|
|
22883
|
+
************************************************************/
|
|
22884
|
+
function save_page_size(gobj, size) {
|
|
22885
|
+
try {
|
|
22886
|
+
window.localStorage.setItem(PAGE_SIZE_STORE_PREFIX + gobj_name(gobj), JSON.stringify(size));
|
|
22887
|
+
} catch (e) {}
|
|
22888
|
+
}
|
|
22862
22889
|
/***************************************************************
|
|
22863
22890
|
* Data
|
|
22864
22891
|
***************************************************************/
|
|
@@ -22915,6 +22942,7 @@ var PRIVATE_DATA$5 = {
|
|
|
22915
22942
|
_pending_pages: null,
|
|
22916
22943
|
_page_seq: 0,
|
|
22917
22944
|
_page_total: null,
|
|
22945
|
+
_page_size: null,
|
|
22918
22946
|
$container: null,
|
|
22919
22947
|
treedb_name: "",
|
|
22920
22948
|
topic_name: "",
|
|
@@ -23801,6 +23829,9 @@ function create_tabulator(gobj) {
|
|
|
23801
23829
|
}
|
|
23802
23830
|
});
|
|
23803
23831
|
}
|
|
23832
|
+
let remembered_size = load_page_size(gobj);
|
|
23833
|
+
if (remembered_size !== null && tabulator_settings.pagination) tabulator_settings.paginationSize = remembered_size;
|
|
23834
|
+
gobj.priv._page_size = tabulator_settings.paginationSize;
|
|
23804
23835
|
Object.assign(tabulator_settings, {
|
|
23805
23836
|
index: pkey,
|
|
23806
23837
|
columns,
|
|
@@ -23836,12 +23867,26 @@ function create_tabulator(gobj) {
|
|
|
23836
23867
|
single_page = max === false || max <= 1;
|
|
23837
23868
|
} else {
|
|
23838
23869
|
let size = tabulator.getPageSize();
|
|
23839
|
-
single_page = !size || n <= size;
|
|
23870
|
+
single_page = size === true || !size || n <= size;
|
|
23840
23871
|
}
|
|
23841
23872
|
} catch (e) {
|
|
23842
23873
|
single_page = true;
|
|
23843
23874
|
}
|
|
23875
|
+
let total_rows;
|
|
23876
|
+
if (paged) total_rows = total;
|
|
23877
|
+
else try {
|
|
23878
|
+
total_rows = tabulator.getDataCount();
|
|
23879
|
+
} catch (e) {
|
|
23880
|
+
total_rows = n;
|
|
23881
|
+
}
|
|
23882
|
+
let min_size = 0;
|
|
23883
|
+
let sizes = tabulator.options ? tabulator.options.paginationSizeSelector : null;
|
|
23884
|
+
if (Array.isArray(sizes)) sizes.forEach(function(size) {
|
|
23885
|
+
if (typeof size === "number" && (!min_size || size < min_size)) min_size = size;
|
|
23886
|
+
});
|
|
23887
|
+
let no_paginator = single_page && (!min_size || typeof total_rows !== "number" || total_rows <= min_size);
|
|
23844
23888
|
tabulator.element.classList.toggle("yui-single-page", single_page);
|
|
23889
|
+
tabulator.element.classList.toggle("yui-no-paginator", no_paginator);
|
|
23845
23890
|
}
|
|
23846
23891
|
tabulator._ready = false;
|
|
23847
23892
|
tabulator.on("tableBuilt", function() {
|
|
@@ -23855,6 +23900,9 @@ function create_tabulator(gobj) {
|
|
|
23855
23900
|
});
|
|
23856
23901
|
tabulator.on("dataProcessed", update_rowcount);
|
|
23857
23902
|
tabulator.on("dataChanged", update_rowcount);
|
|
23903
|
+
tabulator.on("pageSizeChanged", function(size) {
|
|
23904
|
+
gobj_send_event(gobj, "EV_PAGE_SIZE_CHANGED", { size }, gobj);
|
|
23905
|
+
});
|
|
23858
23906
|
tabulator.on("cellEdited", function(cell) {
|
|
23859
23907
|
let pkey = (gobj_read_attr(gobj, "desc") || {}).pkey || "id";
|
|
23860
23908
|
let data = cell.getRow().getData();
|
|
@@ -25306,6 +25354,21 @@ function ac_open_columns(gobj, event, kw, src) {
|
|
|
25306
25354
|
return 0;
|
|
25307
25355
|
}
|
|
25308
25356
|
/************************************************************
|
|
25357
|
+
* The reader picked another page size: remember it, so coming back to
|
|
25358
|
+
* this topic opens where they left it instead of at 200.
|
|
25359
|
+
************************************************************/
|
|
25360
|
+
function ac_page_size_changed(gobj, event, kw, src) {
|
|
25361
|
+
let size = kw ? kw.size : void 0;
|
|
25362
|
+
if (size !== true && !(typeof size === "number" && size > 0)) {
|
|
25363
|
+
log_error(`${gobj_short_name(gobj)}: bad page size: ${size}`);
|
|
25364
|
+
return -1;
|
|
25365
|
+
}
|
|
25366
|
+
if (size === gobj.priv._page_size) return 0;
|
|
25367
|
+
gobj.priv._page_size = size;
|
|
25368
|
+
save_page_size(gobj, size);
|
|
25369
|
+
return 0;
|
|
25370
|
+
}
|
|
25371
|
+
/************************************************************
|
|
25309
25372
|
* Show / hide one column.
|
|
25310
25373
|
************************************************************/
|
|
25311
25374
|
function ac_toggle_column(gobj, event, kw, src) {
|
|
@@ -25510,6 +25573,11 @@ function create_gclass$5(gclass_name) {
|
|
|
25510
25573
|
ac_open_columns,
|
|
25511
25574
|
null
|
|
25512
25575
|
],
|
|
25576
|
+
[
|
|
25577
|
+
"EV_PAGE_SIZE_CHANGED",
|
|
25578
|
+
ac_page_size_changed,
|
|
25579
|
+
null
|
|
25580
|
+
],
|
|
25513
25581
|
[
|
|
25514
25582
|
"EV_TOGGLE_COLUMN",
|
|
25515
25583
|
ac_toggle_column,
|
|
@@ -25560,6 +25628,7 @@ function create_gclass$5(gclass_name) {
|
|
|
25560
25628
|
["EV_REQUEST_PAGE", event_flag_t.EVF_OUTPUT_EVENT],
|
|
25561
25629
|
["EV_SEARCH", 0],
|
|
25562
25630
|
["EV_OPEN_COLUMNS", 0],
|
|
25631
|
+
["EV_PAGE_SIZE_CHANGED", 0],
|
|
25563
25632
|
["EV_TOGGLE_COLUMN", 0],
|
|
25564
25633
|
["EV_EXPORT_TABLE", 0],
|
|
25565
25634
|
["EV_CREATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
package/package.json
CHANGED
|
@@ -23,10 +23,20 @@
|
|
|
23
23
|
line-height: 1.5;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/* All rows fit in one page: the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
26
|
+
/* All rows fit in one page: the First/Prev/1/Next/Last strip is pure
|
|
27
|
+
* noise (worst on mobile) — update_rowcount() toggles the class on every
|
|
28
|
+
* data change. The page-size SELECTOR stays: it is what made the table
|
|
29
|
+
* one page in the first place ("All" on a topic of 300 rows), so hiding
|
|
30
|
+
* it together with the buttons left the reader no way back to 50. */
|
|
31
|
+
.tabulator.yui-single-page .tabulator-footer .tabulator-paginator .tabulator-page,
|
|
32
|
+
.tabulator.yui-single-page .tabulator-footer .tabulator-paginator .tabulator-pages {
|
|
33
|
+
display: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* No choice in the selector would change anything either — the topic is
|
|
37
|
+
* smaller than the smallest page size it offers — so the whole strip,
|
|
38
|
+
* label and select included, is noise. */
|
|
39
|
+
.tabulator.yui-no-paginator .tabulator-footer .tabulator-paginator {
|
|
30
40
|
display: none;
|
|
31
41
|
}
|
|
32
42
|
|
|
@@ -103,6 +103,67 @@ import { TabulatorFull as Tabulator } from "tabulator-tables";
|
|
|
103
103
|
***************************************************************/
|
|
104
104
|
const GCLASS_NAME = "C_YUI_TREEDB_TOPIC_WITH_FORM";
|
|
105
105
|
|
|
106
|
+
/*
|
|
107
|
+
* Where the reader's page size is remembered.
|
|
108
|
+
*
|
|
109
|
+
* In localStorage and not in a persistent attr: how many rows somebody
|
|
110
|
+
* wants in front of them is a fact about THAT browser, not about the
|
|
111
|
+
* yuno, and a library gclass cannot assume the host app wired the
|
|
112
|
+
* persistence functions. Same reasoning as `C_YUI_GOBJ_TREE_JS` and
|
|
113
|
+
* `C_YUI_JSON`.
|
|
114
|
+
*
|
|
115
|
+
* Keyed by the gobj name, which the host builds as `<view>?<topic>`, so
|
|
116
|
+
* the size is remembered PER TOPIC. That is the useful grain: a topic of
|
|
117
|
+
* 5891 devices and one of 22 do not want the same page.
|
|
118
|
+
*/
|
|
119
|
+
const PAGE_SIZE_STORE_PREFIX = "yui_treedb_page_size:";
|
|
120
|
+
|
|
121
|
+
/************************************************************
|
|
122
|
+
* The size the reader left, or null when there is none.
|
|
123
|
+
* `true` is Tabulator's "All" and it round-trips as the boolean:
|
|
124
|
+
* JSON.parse gives it back as one, and a string "true" would be
|
|
125
|
+
* read by Tabulator as a size of NaN.
|
|
126
|
+
************************************************************/
|
|
127
|
+
function load_page_size(gobj)
|
|
128
|
+
{
|
|
129
|
+
try {
|
|
130
|
+
let raw = window.localStorage.getItem(
|
|
131
|
+
PAGE_SIZE_STORE_PREFIX + gobj_name(gobj)
|
|
132
|
+
);
|
|
133
|
+
if(raw === null) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
let size = JSON.parse(raw);
|
|
137
|
+
if(size === true) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if(typeof size === "number" && size > 0) {
|
|
141
|
+
return size;
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
} catch(e) {
|
|
145
|
+
/* localStorage unavailable (private mode) or a value somebody
|
|
146
|
+
* else wrote: the table opens at its default size, which is
|
|
147
|
+
* the same thing that happened before it was remembered. */
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/************************************************************
|
|
153
|
+
*
|
|
154
|
+
************************************************************/
|
|
155
|
+
function save_page_size(gobj, size)
|
|
156
|
+
{
|
|
157
|
+
try {
|
|
158
|
+
window.localStorage.setItem(
|
|
159
|
+
PAGE_SIZE_STORE_PREFIX + gobj_name(gobj),
|
|
160
|
+
JSON.stringify(size)
|
|
161
|
+
);
|
|
162
|
+
} catch(e) {
|
|
163
|
+
// localStorage unavailable (private mode) — non-fatal
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
106
167
|
/***************************************************************
|
|
107
168
|
* Data
|
|
108
169
|
***************************************************************/
|
|
@@ -168,6 +229,7 @@ let PRIVATE_DATA = {
|
|
|
168
229
|
_pending_pages: null, // req_id -> {resolve, reject, timer}
|
|
169
230
|
_page_seq: 0, // correlation id of a page request
|
|
170
231
|
_page_total: null, // rows the topic HAS, from the last page answer
|
|
232
|
+
_page_size: null, // rows per page in effect (remembered across visits)
|
|
171
233
|
$container: null,
|
|
172
234
|
treedb_name: "",
|
|
173
235
|
topic_name: "",
|
|
@@ -1366,6 +1428,22 @@ function create_tabulator(gobj)
|
|
|
1366
1428
|
});
|
|
1367
1429
|
}
|
|
1368
1430
|
|
|
1431
|
+
/* The size the reader picked last time, which outranks both defaults
|
|
1432
|
+
* above. Applied here, once the two paths have set theirs, so it is
|
|
1433
|
+
* written in ONE place -- and applied to `paginationSize` only: the
|
|
1434
|
+
* SELECTOR keeps offering the same sizes, and a remembered value that
|
|
1435
|
+
* is not one of them Tabulator adds to the list itself. */
|
|
1436
|
+
let remembered_size = load_page_size(gobj);
|
|
1437
|
+
if(remembered_size !== null && tabulator_settings.pagination) {
|
|
1438
|
+
tabulator_settings.paginationSize = remembered_size;
|
|
1439
|
+
}
|
|
1440
|
+
/* What the table OPENS at, remembered or default. Tabulator announces
|
|
1441
|
+
* `pageSizeChanged` at build time too, with the size it starts at, and
|
|
1442
|
+
* saving that one would freeze today's default in the reader's browser
|
|
1443
|
+
* for ever: a later change of the default would never reach anybody who
|
|
1444
|
+
* had once opened the table. Only a real change is written. */
|
|
1445
|
+
gobj.priv._page_size = tabulator_settings.paginationSize;
|
|
1446
|
+
|
|
1369
1447
|
Object.assign(tabulator_settings, {
|
|
1370
1448
|
index: pkey,
|
|
1371
1449
|
columns: columns,
|
|
@@ -1462,14 +1540,50 @@ function create_tabulator(gobj)
|
|
|
1462
1540
|
single_page = (max === false) || max <= 1;
|
|
1463
1541
|
} else {
|
|
1464
1542
|
/* Derived from the count and the page size rather than read
|
|
1465
|
-
* from getPageMax(), which is stale in the filter path.
|
|
1543
|
+
* from getPageMax(), which is stale in the filter path.
|
|
1544
|
+
* `true` is Tabulator's "All" and it is the SIZE itself, so
|
|
1545
|
+
* it has to be read as a word: compared as a number it is 1,
|
|
1546
|
+
* and a table showing every one of its 300 rows in a single
|
|
1547
|
+
* page answered that it needed 300 pages. */
|
|
1466
1548
|
let size = tabulator.getPageSize();
|
|
1467
|
-
single_page = !size || n <= size;
|
|
1549
|
+
single_page = (size === true) || !size || n <= size;
|
|
1468
1550
|
}
|
|
1469
1551
|
} catch(e) {
|
|
1470
1552
|
single_page = true;
|
|
1471
1553
|
}
|
|
1554
|
+
/* The page-size selector lives INSIDE the paginator, so hiding the
|
|
1555
|
+
* whole strip when everything fits took away the very control that
|
|
1556
|
+
* got the reader there: pick "All" on a topic of 300 rows and the
|
|
1557
|
+
* table becomes one page, the paginator goes, and 50 is
|
|
1558
|
+
* unreachable. The selector is noise only when no choice in it
|
|
1559
|
+
* would change anything -- when the topic is smaller than the
|
|
1560
|
+
* smallest size it offers. Measure that on the WHOLE topic, never
|
|
1561
|
+
* on the filtered count, or typing a filter that leaves 3 rows
|
|
1562
|
+
* takes the selector away too. */
|
|
1563
|
+
let total_rows;
|
|
1564
|
+
if(paged) {
|
|
1565
|
+
total_rows = total;
|
|
1566
|
+
} else {
|
|
1567
|
+
try {
|
|
1568
|
+
total_rows = tabulator.getDataCount();
|
|
1569
|
+
} catch(e) {
|
|
1570
|
+
total_rows = n;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
let min_size = 0;
|
|
1574
|
+
let sizes = tabulator.options? tabulator.options.paginationSizeSelector : null;
|
|
1575
|
+
if(Array.isArray(sizes)) {
|
|
1576
|
+
sizes.forEach(function(size) {
|
|
1577
|
+
if(typeof size === "number" && (!min_size || size < min_size)) {
|
|
1578
|
+
min_size = size;
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
let no_paginator = single_page &&
|
|
1583
|
+
(!min_size || typeof total_rows !== "number" || total_rows <= min_size);
|
|
1584
|
+
|
|
1472
1585
|
tabulator.element.classList.toggle("yui-single-page", single_page);
|
|
1586
|
+
tabulator.element.classList.toggle("yui-no-paginator", no_paginator);
|
|
1473
1587
|
}
|
|
1474
1588
|
|
|
1475
1589
|
tabulator._ready = false;
|
|
@@ -1493,6 +1607,13 @@ function create_tabulator(gobj)
|
|
|
1493
1607
|
* box; a filter per column made it a claim you read on every keystroke. */
|
|
1494
1608
|
tabulator.on("dataProcessed", update_rowcount);
|
|
1495
1609
|
tabulator.on("dataChanged", update_rowcount);
|
|
1610
|
+
/* The reader changed the page size. The widget has already done the
|
|
1611
|
+
* work -- it re-pages itself -- so what crosses the machine is the
|
|
1612
|
+
* DECISION, which is the half worth remembering and the half that
|
|
1613
|
+
* shows up in the trace. */
|
|
1614
|
+
tabulator.on("pageSizeChanged", function(size) {
|
|
1615
|
+
gobj_send_event(gobj, "EV_PAGE_SIZE_CHANGED", {size: size}, gobj);
|
|
1616
|
+
});
|
|
1496
1617
|
/* A cell edited in place. Announced as ONE FIELD of one record — not
|
|
1497
1618
|
* as the row — and that is the whole safety of it: the host writes it
|
|
1498
1619
|
* with a partial update and no `autolink`, so nothing but that field
|
|
@@ -3570,6 +3691,27 @@ function ac_open_columns(gobj, event, kw, src)
|
|
|
3570
3691
|
return 0;
|
|
3571
3692
|
}
|
|
3572
3693
|
|
|
3694
|
+
/************************************************************
|
|
3695
|
+
* The reader picked another page size: remember it, so coming back to
|
|
3696
|
+
* this topic opens where they left it instead of at 200.
|
|
3697
|
+
************************************************************/
|
|
3698
|
+
function ac_page_size_changed(gobj, event, kw, src)
|
|
3699
|
+
{
|
|
3700
|
+
let size = kw? kw.size : undefined;
|
|
3701
|
+
if(size !== true && !(typeof size === "number" && size > 0)) {
|
|
3702
|
+
log_error(`${gobj_short_name(gobj)}: bad page size: ${size}`);
|
|
3703
|
+
return -1;
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
if(size === gobj.priv._page_size) {
|
|
3707
|
+
return 0; /* the build-time announcement, not a decision */
|
|
3708
|
+
}
|
|
3709
|
+
gobj.priv._page_size = size;
|
|
3710
|
+
save_page_size(gobj, size);
|
|
3711
|
+
|
|
3712
|
+
return 0;
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3573
3715
|
/************************************************************
|
|
3574
3716
|
* Show / hide one column.
|
|
3575
3717
|
************************************************************/
|
|
@@ -3708,6 +3850,7 @@ function create_gclass(gclass_name)
|
|
|
3708
3850
|
["EV_PAGE_TIMEOUT", ac_page_timeout, null],
|
|
3709
3851
|
["EV_SEARCH", ac_search, null],
|
|
3710
3852
|
["EV_OPEN_COLUMNS", ac_open_columns, null],
|
|
3853
|
+
["EV_PAGE_SIZE_CHANGED", ac_page_size_changed, null],
|
|
3711
3854
|
["EV_TOGGLE_COLUMN", ac_toggle_column, null],
|
|
3712
3855
|
["EV_EXPORT_TABLE", ac_export_table, null],
|
|
3713
3856
|
["EV_SHOW", ac_show, null],
|
|
@@ -3748,6 +3891,7 @@ function create_gclass(gclass_name)
|
|
|
3748
3891
|
["EV_REQUEST_PAGE", event_flag_t.EVF_OUTPUT_EVENT],
|
|
3749
3892
|
["EV_SEARCH", 0],
|
|
3750
3893
|
["EV_OPEN_COLUMNS", 0],
|
|
3894
|
+
["EV_PAGE_SIZE_CHANGED", 0],
|
|
3751
3895
|
["EV_TOGGLE_COLUMN", 0],
|
|
3752
3896
|
["EV_EXPORT_TABLE", 0],
|
|
3753
3897
|
|
package/src/tabulator.css
CHANGED
|
@@ -304,6 +304,23 @@
|
|
|
304
304
|
color: var(--bulma-link-invert);
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
/* The paginator paints its OWN colour -- tabulator_bulma.css sets
|
|
308
|
+
* `color: hsl(0, 0%, 21%)` on `.tabulator-paginator` itself -- so the
|
|
309
|
+
* footer's colour never reaches the "Rows per page" label: near-black
|
|
310
|
+
* text on the dark footer, legible only if you knew it was there. Say
|
|
311
|
+
* it on the element that sets it, and on the native <select>, which
|
|
312
|
+
* otherwise keeps the browser's light chrome. */
|
|
313
|
+
[data-theme=dark] .tabulator .tabulator-footer .tabulator-paginator,
|
|
314
|
+
[data-theme=dark] .tabulator .tabulator-footer .tabulator-paginator label {
|
|
315
|
+
color: var(--bulma-text);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
[data-theme=dark] .tabulator .tabulator-footer .tabulator-page-size {
|
|
319
|
+
background-color: var(--bulma-background);
|
|
320
|
+
color: var(--bulma-text);
|
|
321
|
+
border-color: var(--bulma-border);
|
|
322
|
+
}
|
|
323
|
+
|
|
307
324
|
[data-theme=dark] .tabulator-row .tabulator-cell.tabulator-frozen {
|
|
308
325
|
background-color: var(--bulma-background) !important;
|
|
309
326
|
}
|
|
@@ -386,5 +403,15 @@
|
|
|
386
403
|
background-color: var(--bulma-link);
|
|
387
404
|
color: var(--bulma-link-invert);
|
|
388
405
|
}
|
|
406
|
+
/* same paginator-paints-its-own-colour rule as [data-theme=dark] */
|
|
407
|
+
[data-theme=system] .tabulator .tabulator-footer .tabulator-paginator,
|
|
408
|
+
[data-theme=system] .tabulator .tabulator-footer .tabulator-paginator label {
|
|
409
|
+
color: var(--bulma-text);
|
|
410
|
+
}
|
|
411
|
+
[data-theme=system] .tabulator .tabulator-footer .tabulator-page-size {
|
|
412
|
+
background-color: var(--bulma-background);
|
|
413
|
+
color: var(--bulma-text);
|
|
414
|
+
border-color: var(--bulma-border);
|
|
415
|
+
}
|
|
389
416
|
}
|
|
390
417
|
|