Skip to content

Commit 63385f6

Browse files
committed
fix #812
1 parent 5b86aa6 commit 63385f6

File tree

2 files changed

+79
-39
lines changed

2 files changed

+79
-39
lines changed

sqlpage/sqlpage.js

Lines changed: 78 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,29 @@ function sqlpage_card() {
2424
}
2525

2626
/** @param {HTMLElement} root_el */
27-
function table_search_sort(root_el) {
27+
function setup_table(root_el) {
2828
/** @type {HTMLInputElement | null} */
2929
const search_input = root_el.querySelector("input.search");
3030
const table_el = root_el.querySelector("table");
3131
const sort_buttons = [...table_el.querySelectorAll("button.sort[data-sort]")];
3232
const item_parent = table_el.querySelector("tbody");
33-
const number_format_locale = table_el.dataset.number_format_locale;
34-
const number_format_digits = table_el.dataset.number_format_digits;
35-
const currency = table_el.dataset.currency;
36-
const header_els = table_el.querySelectorAll("thead > tr > th");
37-
const col_types = [...header_els].map((el) => el.dataset.column_type);
38-
const col_rawnums = [...header_els].map((el) => !!el.dataset.raw_number);
39-
const col_money = [...header_els].map((el) => !!el.dataset.money);
40-
const items = [...item_parent.querySelectorAll("tr")].map((tr_el) => {
41-
const cells = tr_el.getElementsByTagName("td");
42-
return {
43-
el: tr_el,
44-
sort_keys: sort_buttons.map((btn_el, idx) => {
45-
const sort_key = cells[idx]?.textContent;
46-
const column_type = col_types[idx];
47-
const num = Number.parseFloat(sort_key);
48-
const is_raw_number = col_rawnums[idx];
49-
if (column_type === "number" && !is_raw_number) {
50-
const cell_el = cells[idx];
51-
const is_money = col_money[idx];
52-
cell_el.textContent = num.toLocaleString(number_format_locale, {
53-
maximumFractionDigits: number_format_digits,
54-
currency,
55-
style: is_money ? "currency" : undefined,
56-
});
57-
}
58-
return {
59-
num,
60-
str: sort_key,
61-
};
62-
}),
63-
};
64-
});
33+
const has_sort = sort_buttons.length > 0;
34+
35+
if (search_input || has_sort) {
36+
const items = table_parse_data(table_el, sort_buttons);
37+
if (search_input) setup_table_search_behavior(search_input, items);
38+
if (has_sort) setup_sort_behavior(sort_buttons, items, item_parent);
39+
}
40+
41+
// Change number format AFTER parsing and storing the sort keys
42+
apply_number_formatting(table_el);
43+
}
44+
45+
/**
46+
* @param {HTMLInputElement} search_input
47+
* @param {Array<{el: HTMLElement, sort_keys: Array<{num: number, str: string}>}>} items
48+
*/
49+
function setup_table_search_behavior(search_input, items) {
6550
function onSearch() {
6651
const lower_search = search_input.value
6752
.toLowerCase()
@@ -74,10 +59,66 @@ function table_search_sort(root_el) {
7459
item.el.style.display = show ? "" : "none";
7560
}
7661
}
77-
if (search_input) {
78-
search_input.addEventListener("input", onSearch);
79-
onSearch();
62+
63+
search_input.addEventListener("input", onSearch);
64+
onSearch();
65+
}
66+
67+
/**@param {HTMLElement} table_el */
68+
function apply_number_formatting(table_el) {
69+
const header_els = table_el.querySelectorAll("thead > tr > th");
70+
const col_types = [...header_els].map((el) => el.dataset.column_type);
71+
const col_rawnums = [...header_els].map((el) => !!el.dataset.raw_number);
72+
const col_money = [...header_els].map((el) => !!el.dataset.money);
73+
const number_format_locale = table_el.dataset.number_format_locale;
74+
const number_format_digits = table_el.dataset.number_format_digits;
75+
const currency = table_el.dataset.currency;
76+
77+
for (const tr_el of table_el.querySelectorAll("tbody tr")) {
78+
const cells = tr_el.getElementsByTagName("td");
79+
for (let idx = 0; idx < cells.length; idx++) {
80+
const column_type = col_types[idx];
81+
const is_raw_number = col_rawnums[idx];
82+
const cell_el = cells[idx];
83+
84+
if (column_type === "number" && !is_raw_number) {
85+
const num = Number.parseFloat(cell_el.textContent);
86+
const is_money = col_money[idx];
87+
cell_el.textContent = num.toLocaleString(number_format_locale, {
88+
maximumFractionDigits: number_format_digits,
89+
currency,
90+
style: is_money ? "currency" : undefined,
91+
});
92+
}
93+
}
8094
}
95+
}
96+
97+
/** Prepare the table rows for sorting.
98+
* @param {HTMLElement} table_el
99+
* @param {HTMLElement[]} sort_buttons
100+
*/
101+
function table_parse_data(table_el, sort_buttons) {
102+
return [...table_el.querySelectorAll("tbody tr")].map((tr_el) => {
103+
const cells = tr_el.getElementsByTagName("td");
104+
return {
105+
el: tr_el,
106+
sort_keys: sort_buttons.map((btn_el, idx) => {
107+
const str = cells[idx]?.textContent;
108+
const num = Number.parseFloat(str);
109+
return { num, str };
110+
}),
111+
};
112+
});
113+
}
114+
115+
/**
116+
* Adds event listeners to the sort buttons to sort the table rows.
117+
* @param {HTMLElement[]} sort_buttons
118+
* @param {HTMLElement[]} items
119+
* @param {HTMLElement} item_parent
120+
*/
121+
function setup_sort_behavior(sort_buttons, items, item_parent) {
81122
sort_buttons.forEach((button, button_index) => {
82123
button.addEventListener("click", function sort_items() {
83124
const sort_desc = button.classList.contains("asc");
@@ -102,10 +143,9 @@ function table_search_sort(root_el) {
102143
}
103144

104145
function sqlpage_table() {
105-
// Tables
106146
for (const r of document.querySelectorAll("[data-pre-init=table]")) {
107-
table_search_sort(r);
108147
r.removeAttribute("data-pre-init");
148+
setup_table(r);
109149
}
110150
}
111151

sqlpage/templates/table.handlebars

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="card my-2 {{class}}" {{#if overflow}}style="width: fit-content;"{{/if}} {{#if id}}id="{{id}}"{{/if}}>
2-
<div class="card-body p-0" {{#if (or sort (or search initial_search_value))}}data-pre-init="table"{{/if}}>
2+
<div class="card-body p-0" data-pre-init="table">
33
{{#if (or search initial_search_value)}}
44
<div class="p-3">
55
<input

0 commit comments

Comments
 (0)