@@ -24,44 +24,29 @@ function sqlpage_card() {
24
24
}
25
25
26
26
/** @param {HTMLElement } root_el */
27
- function table_search_sort ( root_el ) {
27
+ function setup_table ( root_el ) {
28
28
/** @type {HTMLInputElement | null } */
29
29
const search_input = root_el . querySelector ( "input.search" ) ;
30
30
const table_el = root_el . querySelector ( "table" ) ;
31
31
const sort_buttons = [ ...table_el . querySelectorAll ( "button.sort[data-sort]" ) ] ;
32
32
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 ) {
65
50
function onSearch ( ) {
66
51
const lower_search = search_input . value
67
52
. toLowerCase ( )
@@ -74,10 +59,66 @@ function table_search_sort(root_el) {
74
59
item . el . style . display = show ? "" : "none" ;
75
60
}
76
61
}
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
+ }
80
94
}
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 ) {
81
122
sort_buttons . forEach ( ( button , button_index ) => {
82
123
button . addEventListener ( "click" , function sort_items ( ) {
83
124
const sort_desc = button . classList . contains ( "asc" ) ;
@@ -102,10 +143,9 @@ function table_search_sort(root_el) {
102
143
}
103
144
104
145
function sqlpage_table ( ) {
105
- // Tables
106
146
for ( const r of document . querySelectorAll ( "[data-pre-init=table]" ) ) {
107
- table_search_sort ( r ) ;
108
147
r . removeAttribute ( "data-pre-init" ) ;
148
+ setup_table ( r ) ;
109
149
}
110
150
}
111
151
0 commit comments