Skip to content

Commit 8fa9ae6

Browse files
author
jcrombez
committed
realtime filtering using turbo frame
1 parent 7765a43 commit 8fa9ae6

4 files changed

Lines changed: 83 additions & 1 deletion

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Controller } from '@hotwired/stimulus';
2+
import {debounce} from "lodash/function";
3+
4+
export default class extends Controller {
5+
static values = {
6+
events: { type: Array, default: ['change', 'input'] },
7+
turboFrameIds: { type: Array, default: [] },
8+
};
9+
10+
lastUsedUrl = null;
11+
12+
connect() {
13+
this.handleChange = this.handleChange.bind(this);
14+
this.handleChangeThrottled = debounce(this.handleChange, 250);
15+
16+
this.eventsValue.forEach(event => {
17+
this.element.addEventListener(event, this.handleChangeThrottled);
18+
});
19+
}
20+
21+
disconnect() {
22+
this.eventsValue.forEach(event => {
23+
this.element.removeEventListener(event, this.handleChangeThrottled);
24+
});
25+
}
26+
27+
handleChange() {
28+
if (this.element.tagName !== 'FORM' || this.element.method.toLowerCase() !== 'get') {
29+
return
30+
}
31+
32+
const url = new URL(this.element.action);
33+
url.search = new URLSearchParams(new FormData(this.element)).toString();
34+
35+
const urlString = url.toString();
36+
37+
if (urlString === this.lastUsedUrl) {
38+
return
39+
}
40+
41+
this.lastUsedUrl = urlString;
42+
43+
this.turboFrameIdsValue.forEach((id, index) => {
44+
const frame = document.querySelector(id);
45+
46+
if (frame) {
47+
const urlWithCacheBuster = new URL(urlString);
48+
urlWithCacheBuster.searchParams.set('_v', index + Date.now());
49+
const finalUrl = urlWithCacheBuster.toString();
50+
51+
console.log('[auto-submit-form] Updating frame : ' + id + ' with URL: ' + finalUrl + '')
52+
frame.setAttribute('src', finalUrl);
53+
} else {
54+
console.log('[auto-submit-form] Frame not found : "' + id +'".');
55+
}
56+
});
57+
}
58+
}

assets/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
"webpackMode": "eager",
1313
"fetch": "eager",
1414
"enabled": true
15+
},
16+
"form-turbo-frame-updater": {
17+
"main": "dist/form_turbo_frame_updater_controller.js",
18+
"name": "form-turbo-frame-updater",
19+
"webpackMode": "eager",
20+
"fetch": "eager",
21+
"enabled": true
1522
}
1623
},
1724
"importmap": {

src/Resources/views/theme/bootstrap5/datagrid-filters.html.twig

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
{{ form_start(form) }}
1+
{% set relatedTurboFrames = this.relatedTurboFrames ?? false %}
2+
{% set form_options = {} %}
3+
4+
{% if relatedTurboFrames %}
5+
{% set form_options = form_options|merge({
6+
'attr': {
7+
'data-controller': 'form-turbo-frame-updater',
8+
'data-form-turbo-frame-updater-turbo-frame-ids-value': this.relatedTurboFrames|json_encode
9+
}
10+
}) %}
11+
{% endif %}
12+
13+
{{ form_start(form, form_options) }}
214

315
{% set layoutFieldNames = [] %}
416
{% for row in grid.filterLayout %}
@@ -22,6 +34,7 @@
2234
{% endif %}
2335
{% endfor %}
2436

37+
{% if not relatedTurboFrames %}
2538
<div class="row">
2639
<div class="col text-end">
2740
<ul class="list-inline">
@@ -47,4 +60,6 @@
4760
</ul>
4861
</div>
4962
</div>
63+
{% endif %}
64+
5065
{{ form_end(form) }}

src/Twig/Components/DatagridFiltersComponent.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ final class DatagridFiltersComponent
1010
{
1111
public FormView $form;
1212
public Grid $grid;
13+
14+
public array $relatedTurboFrames = [];
1315
}

0 commit comments

Comments
 (0)