@@ -46,7 +46,10 @@ function addOrUpdateUriParameter(uri, parameter, value) {
4646                new_url =  new_url .addQuery (parameter, value); 
4747            } 
4848
49-             $ (' #remove_filters_button'  ).toggleClass (' invisible'  , ! new_url .query ()); 
49+             //  Update all remove filter buttons visibility 
50+             document .querySelectorAll (' .remove_filters_button'  ).forEach (function (button ) { 
51+                 button .classList .toggle (' invisible'  , ! new_url .query ()); 
52+             }); 
5053
5154            return  new_url .normalizeQuery ().toString (); 
5255        } 
@@ -66,18 +69,28 @@ function updateDatatablesOnFilterChange(filterName, filterValue, update_url = fa
6669            //  Get the table instance based on the tableId 
6770            let  table =  window .crud .tables [tableId] ||  window .crud .table ; 
6871             
72+             if  (! table) { 
73+                 console .error (' No table found for tableId:'  , tableId); 
74+                 return ; 
75+             } 
76+              
6977            //  behaviour for ajax tables 
70-             let  new_url =  updatePageUrl (filterName, filterValue, table .ajax .url ()); 
71-             table .ajax .url (new_url); 
78+             let  currentAjaxUrl =  table .ajax .url (); 
79+             let  new_ajax_url =  addOrUpdateUriParameter (currentAjaxUrl, filterName, filterValue); 
80+              
81+             //  Update the table's ajax URL 
82+             table .ajax .url (new_ajax_url); 
83+ 
84+             let  browser_url =  updatePageUrl (filterName, filterValue, window .location .href ); 
7285
7386            //  when we are clearing ALL filters, we would not update the table url here, because this is done PER filter 
7487            //  and we have a function that will do this update for us after all filters had been cleared. 
7588            if (update_url) { 
76-                 //  replace the datatables ajax url with new_url  and reload it 
77-                 callFunctionOnce (function () { refreshDatatablesOnFilterChange (new_url , tableId) }, debounce, ' refreshDatatablesOnFilterChange_'   +  tableId); 
89+                 //  replace the datatables ajax url with new_ajax_url  and reload it 
90+                 callFunctionOnce (function () { refreshDatatablesOnFilterChange (new_ajax_url , tableId) }, debounce, ' refreshDatatablesOnFilterChange_'   +  tableId); 
7891            } 
7992
80-             return  new_url ; 
93+             return  new_ajax_url ; 
8194        } 
8295    } 
8396
@@ -109,6 +122,11 @@ function refreshDatatablesOnFilterChange(url, tableId = 'crudTable')
109122            //  Get the table instance based on the tableId 
110123            let  table =  window .crud .tables [tableId] ||  window .crud .table ; 
111124             
125+             if  (! table) { 
126+                 console .error (' No table found for refresh, tableId:'  , tableId); 
127+                 return ; 
128+             } 
129+              
112130            //  replace the datatables ajax url with new_url and reload it 
113131            table .ajax .url (url).load (); 
114132        } 
@@ -133,23 +151,27 @@ function refreshDatatablesOnFilterChange(url, tableId = 'crudTable')
133151                return ; 
134152            } 
135153
136-             document .addEventListener (' backpack:filter:changed'  , function (event ) { 
154+             //  Add event listener only once per navbar to avoid duplication 
155+             if  (! navbar .hasAttribute (' data-filter-events-bound'  )) { 
156+                 navbar .setAttribute (' data-filter-events-bound'  , ' true'  ); 
157+                  
158+                 document .addEventListener (' backpack:filter:changed'  , function (event ) { 
159+                     //  check if any of the filters are active 
160+                     let  anyActiveFilters =  false ; 
137161
138-                 //  check if any of the filters are active 
139-                 let  anyActiveFilters =  false ; 
162+                     filters .forEach (function (filter ) { 
163+                         if  (filter .classList .contains (' active'  )) { 
164+                             anyActiveFilters =  true ; 
165+                         } 
166+                     }); 
140167
141-                 filters .forEach (function (filter ) { 
142-                     if  (filter .classList .contains (' active'  )) { 
143-                         anyActiveFilters =  true ; 
168+                     if (anyActiveFilters ===  true ) { 
169+                         navbar .querySelector (' .remove_filters_button'  ).classList .remove (' invisible'  ); 
170+                     }else { 
171+                         navbar .querySelector (' .remove_filters_button'  ).classList .add (' invisible'  ); 
144172                    } 
145173                }); 
146- 
147-                 if (anyActiveFilters ===  true ) { 
148-                     navbar .querySelector (' .remove_filters_button'  ).classList .remove (' invisible'  ); 
149-                 }else { 
150-                     navbar .querySelector (' .remove_filters_button'  ).classList .add (' invisible'  ); 
151-                 } 
152-             }); 
174+             } 
153175             
154176            filters .forEach (function (filter ) { 
155177                let  initFunction =  filter .getAttribute (' filter-init-function'  ); 
@@ -200,6 +222,26 @@ function refreshDatatablesOnFilterChange(url, tableId = 'crudTable')
200222                            } 
201223                        })); 
202224                    }); 
225+ 
226+                     //  After clearing filters, re-initialize them to ensure proper state 
227+                     setTimeout (function () { 
228+                         filters .forEach (function (filter ) { 
229+                             let  initFunction =  filter .getAttribute (' filter-init-function'  ); 
230+                             if  (window [initFunction]) { 
231+                                 window [initFunction](filter, navbar); 
232+                             } 
233+                         }); 
234+                     }, 50 ); 
235+ 
236+                     //  Force update the URL to remove all filter parameters after a short delay 
237+                     //  to ensure all filters have processed the clear event 
238+                     setTimeout (function () { 
239+                         let  currentUrl =  window .location .href ; 
240+                         let  cleanUrl =  URI (currentUrl).search (' '  ).toString (); 
241+                         if  (window .crud  &&  window .crud .updateUrl ) { 
242+                             window .crud .updateUrl (cleanUrl); 
243+                         } 
244+                     }, 100 ); 
203245                }); 
204246            } 
205247
0 commit comments