@@ -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
104145function 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
0 commit comments