Skip to content

Commit caae70e

Browse files
committed
fix controls index
1 parent c4a7e64 commit caae70e

File tree

1 file changed

+132
-81
lines changed

1 file changed

+132
-81
lines changed

resources/views/controls/index.blade.php

Lines changed: 132 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class="table data-table striped row-hover cell-border"
9090
data-rownum="false"
9191
data-check="false"
9292
data-check-style="1"
93+
data-search="true"
9394
>
9495
<thead>
9596
<tr>
@@ -180,92 +181,142 @@ class="table data-table striped row-hover cell-border"
180181
</tbody>
181182
</table>
182183
</div>
183-
<script>
184-
document.addEventListener("DOMContentLoaded", function () {
185-
// Récupère le paramètre search
186-
let params = new URLSearchParams(window.location.search);
187-
const searchValue = params.get('search');
188-
if (searchValue) {
189-
// get serach filter
190-
let searchInput = document.querySelector('.table-search-block input');
191-
searchInput.value = searchValue;
192-
// Trouve la table et applique la recherche
193-
let tableElement = document.querySelector('.data-table');
194-
let table = Metro.getPlugin(tableElement, "table");
195-
if (table)
196-
table.search(searchValue);
184+
<script>
185+
document.addEventListener("DOMContentLoaded", () => {
186+
const $ = (sel, root=document) => root.querySelector(sel);
187+
const getParam = (k) => new URLSearchParams(location.search).get(k) ?? '';
197188
198-
}
199-
// Auto submits
200-
var select = document.getElementById('domain');
201-
select.addEventListener('change', function(){
202-
let url = new URL(window.location.href);
203-
url.pathname = '/bob/index';
204-
url.searchParams.set('domain', this.value);
205-
let searchInput = document.querySelector('.table-search-block input');
206-
url.searchParams.set('search', searchInput.value);
207-
window.location = url.toString();
208-
}, false);
189+
// --- Attendre que Metro ait fini d'initialiser ses selects
190+
let ready = false;
191+
window.addEventListener('load', () => {
192+
// 2 rAF pour laisser Metro construire le DOM
193+
requestAnimationFrame(() => requestAnimationFrame(() => { ready = true; }));
194+
});
209195
210-
var select = document.getElementById('scope');
211-
select.addEventListener('change', function(){
212-
let url = new URL(window.location.href);
213-
url.pathname = '/bob/index';
214-
url.searchParams.set('scope', this.value);
215-
let searchInput = document.querySelector('.table-search-block input');
216-
url.searchParams.set('search', searchInput.value);
217-
window.location = url.toString();
218-
}, false);
196+
// --- Snapshot de tous les filtres (UI -> fallback URL)
197+
function snapshotFilters() {
198+
const searchInput = $('.table-search-block input');
199+
return {
200+
domain : document.getElementById('domain')?.value ?? getParam('domain'),
201+
clause : (document.getElementById('clause')?.value ?? getParam('clause')).trim(),
202+
scope : (document.getElementById('scope')?.value ?? getParam('scope')).trim(),
203+
period : document.getElementById('cur_period')?.value ?? getParam('period'),
204+
status : (document.getElementById('status0')?.checked ? '0' :
205+
document.getElementById('status1')?.checked ? '1' :
206+
document.getElementById('status2')?.checked ? '2' : getParam('status')),
207+
search : (searchInput && searchInput.value !== '') ? searchInput.value : getParam('search')
208+
};
209+
}
219210
220-
var select = document.getElementById('clause');
221-
select.addEventListener('change', function(){
222-
let url = new URL(window.location.href);
223-
url.pathname = '/bob/index';
224-
url.searchParams.set('clause', this.value);
225-
let searchInput = document.querySelector('.table-search-block input');
226-
url.searchParams.set('search', searchInput.value);
227-
window.location = url.toString();
228-
}, false);
211+
// --- Navigation: toujours poster TOUTES les valeurs
212+
function navigateWithAll(patch={}) {
213+
const cur = new URL(location.href);
214+
const next = new URL(location.href);
215+
next.pathname = '/bob/index';
229216
230-
select = document.getElementById('cur_period');
231-
select.addEventListener('change', function(){
232-
let url = new URL(window.location.href);
233-
url.pathname = '/bob/index';
234-
url.searchParams.set('period', this.value);
235-
let searchInput = document.querySelector('.table-search-block input');
236-
url.searchParams.set('search', searchInput.value);
237-
window.location = url.toString();
238-
}, false);
217+
const all = { ...snapshotFilters(), ...patch };
218+
for (const [k,v] of Object.entries(all)) {
219+
if (v == null || String(v) === '') next.searchParams.delete(k);
220+
else next.searchParams.set(k, String(v));
221+
}
222+
if (next.toString() !== location.href) location.assign(next.toString());
223+
}
239224
240-
select = document.getElementById('status0');
241-
select.addEventListener('change', function() {
242-
let url = new URL(window.location.href);
243-
url.pathname = '/bob/index';
244-
url.searchParams.set('status', 0);
245-
let searchInput = document.querySelector('.table-search-block input');
246-
url.searchParams.set('search', searchInput.value);
247-
window.location = url.toString();
248-
}, false);
225+
// ==================================================================
249226
250-
select = document.getElementById('status1');
251-
select.addEventListener('change', function(){
252-
let url = new URL(window.location.href);
253-
url.pathname = '/bob/index';
254-
url.searchParams.set('status', 1);
255-
let searchInput = document.querySelector('.table-search-block input');
256-
url.searchParams.set('search', searchInput.value);
257-
window.location = url.toString();
258-
}, false);
227+
// --- 1) assure-toi que la table génère bien la barre de recherche
228+
// (dans ton HTML de la table) :
229+
// data-search="true"
259230
260-
select = document.getElementById('status2');
261-
select.addEventListener('change', function(){
262-
let url = new URL(window.location.href);
263-
url.pathname = '/bob/index';
264-
url.searchParams.set('status', 2);
265-
let searchInput = document.querySelector('.table-search-block input');
266-
url.searchParams.set('search', searchInput.value);
267-
window.location = url.toString();
268-
}, false);
269-
}, false);
270-
</script>
231+
// --- 2) lit la valeur dans l'URL
232+
const params = new URLSearchParams(location.search);
233+
const searchValue = params.get('search') || '';
234+
235+
// --- 3) applique à l'API table (filtrage effectif)
236+
const applyToAPI = (val) => {
237+
const tableEl = document.getElementById('controls');
238+
const api = tableEl ? Metro.getPlugin(tableEl, 'table') : null;
239+
if (api && typeof api.search === 'function') {
240+
api.search(val);
241+
return true;
242+
}
243+
return false;
244+
};
245+
246+
// --- 4) pose la valeur dans l'input quand il existe (et quand il est recréé)
247+
function setSearchInputWhenReady(val, timeoutMs = 3000) {
248+
if (!val) return;
249+
250+
const trySet = () => {
251+
const input = $('.table-search-block input');
252+
if (!input) return false;
253+
if (input.value !== val) {
254+
input.value = val;
255+
input.dispatchEvent(new Event('input', { bubbles: true }));
256+
input.dispatchEvent(new Event('change', { bubbles: true }));
257+
}
258+
return true;
259+
};
260+
261+
if (trySet()) return;
262+
263+
// a) quelques frames
264+
let tries = 0, maxTries = 20;
265+
const raf = () => {
266+
if (trySet()) return;
267+
if (++tries >= maxTries) return;
268+
requestAnimationFrame(raf);
269+
};
270+
requestAnimationFrame(raf);
271+
272+
// b) garde-fou si l’input apparaît plus tard (reconstruction Metro)
273+
const mo = new MutationObserver(() => {
274+
if (trySet()) mo.disconnect();
275+
});
276+
mo.observe(document.body, { childList: true, subtree: true });
277+
setTimeout(() => mo.disconnect(), timeoutMs);
278+
}
279+
280+
// --- 5) exécution au chargement
281+
if (searchValue) {
282+
// filtre la table côté API (immédiat ou dès que prêt)
283+
if (!applyToAPI(searchValue)) {
284+
requestAnimationFrame(() => applyToAPI(searchValue));
285+
}
286+
// force l’affichage dans l’input dès qu’il existe
287+
setSearchInputWhenReady(searchValue);
288+
}
289+
290+
291+
// ==================================================================
292+
// --- Bind: ne PAS utiliser e.isTrusted (Metro déclenche un change programmatique)
293+
const bindChange = (id, key, coerce = v => v) => {
294+
const el = document.getElementById(id);
295+
if (!el) return;
296+
el.addEventListener('change', () => {
297+
if (!ready) return; // on ignore les changements pendant l'init
298+
const newVal = coerce(el.value);
299+
navigateWithAll({ [key]: newVal });
300+
}, false);
301+
};
302+
303+
bindChange('domain', 'domain', v => String(v));
304+
bindChange('clause', 'clause', v => String(v).trim());
305+
bindChange('scope', 'scope', v => String(v).trim());
306+
bindChange('cur_period', 'period', v => String(v));
307+
308+
// Radios status (OK de garder le flag ready)
309+
const bindStatus = (id, value) => {
310+
const el = document.getElementById(id);
311+
if (!el) return;
312+
el.addEventListener('change', () => {
313+
if (!ready) return;
314+
navigateWithAll({ status: String(value) });
315+
}, false);
316+
};
317+
bindStatus('status0', 0);
318+
bindStatus('status1', 1);
319+
bindStatus('status2', 2);
320+
}, false);
321+
</script>
271322
@endsection

0 commit comments

Comments
 (0)