@@ -107,26 +107,36 @@ function initTableFilter(): void {
107107 // Create a regex pattern from the input search text to match against.
108108 const filter = new RegExp ( target . value . toLowerCase ( ) . trim ( ) ) ;
109109
110+ // List of which rows which match the query
111+ const matchedRows : Array < HTMLTableRowElement > = [ ] ;
112+
110113 for ( const row of rows ) {
111114 // Find the row's checkbox and deselect it, so that it is not accidentally included in form
112115 // submissions.
113116 const checkBox = row . querySelector < HTMLInputElement > ( 'input[type="checkbox"][name="pk"]' ) ;
114117 if ( checkBox !== null ) {
115118 checkBox . checked = false ;
116119 }
120+
117121 // Iterate through each row's cell values
118122 for ( const value of getRowValues ( row ) ) {
119123 if ( filter . test ( value . toLowerCase ( ) ) ) {
120- // If this row matches the search pattern, but is already hidden, unhide it and stop
121- // iterating through the rest of the cells.
122- row . classList . remove ( 'd-none' ) ;
124+ // If this row matches the search pattern, add it to the list.
125+ matchedRows . push ( row ) ;
123126 break ;
124- } else {
125- // If none of the cells in this row match the search pattern, hide the row.
126- row . classList . add ( 'd-none' ) ;
127127 }
128128 }
129129 }
130+
131+ // Iterate the rows again to set visibility.
132+ // This results in a single reflow instead of one for each row.
133+ for ( const row of rows ) {
134+ if ( matchedRows . indexOf ( row ) >= 0 ) {
135+ row . classList . remove ( 'd-none' ) ;
136+ } else {
137+ row . classList . add ( 'd-none' ) ;
138+ }
139+ }
130140 }
131141 input . addEventListener ( 'keyup' , debounce ( handleInput , 300 ) ) ;
132142 }
0 commit comments