Bonjour à tous,
J'ai tenté d'incruster 3 double-range-sliders par un include dans ma page d'index contenant déjà un form servant de filtre.
1er Problème :
Pour que le formulaire de filtres fonctionne je mets le script en mode defer mais à ce moment là, l'autre form contenant les sliders lui ne répond plus, je dois retirer le defer du script antérieur et le mettre sur celui des sliders pour que celui-ci fonctionne, à n'y rien comprendre !
2ème problème :
Bien que j'ai écrit une fonction par délégation sensée écouter les 3 sliders, seul le premier d'entre-eux s'active, me tromperai-je de sélecteur ?
3ème problème :
Une fois transformé en Html Twig le code css des sliders ne fonctionne pas bien : les sliders se chevauchent et ignorent le css (-webkit) alors qu'en html pur tout est bon (voir capture jointe)...
Pièce jointe 639845
Merci d'avance pour vos réponses et expertise
index.html.twig :
_sliders.html.twig :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 {% extends "base.html.twig" %} {% block title %}Liste des véhicules {% endblock %} {% block body %} <div class="main"> <h1 class="titre-principal">Liste des véhicules</h1> {% if is_granted(['ROLE_ADMIN']) %} <a href="{{path('app_vehicules_creer_vehicule')}}" class="btn btn-primary">Créer un nouveau véhicule</a> {% endif %} <p>Total véhicules dans la base = {{totalVehicules}}</p> <p>Résultats filtre actif = {{totalVehiculesFiltered}}</p> {# Sliders double range #} {{ include('_partials/_sliders.html.twig') }} <div class="wrapper"> {# Filtre multicritère : #} <div class="filtres"> <form id="filters" class="filtersForm"> {# Filtre sur type de véhicule #} <fieldset> <legend>Type :</legend> {% for type in typesVehicules %} <input type="checkbox" name="types[]" id="types{{type.id}}" value="{{type.id}}" class="filtreTypes"> <label for="types{{type.id}}">{{type.nomtype}}</label> {% endfor %} </fieldset> {# Filtre sur marques de véhicules #} <fieldset> <legend>Marque :</legend> {% for marque in marquesVehicules %} <input type="checkbox" name="marques[]" id="marques{{marque.id}}" value="{{marque.id}}" class="filtreMarques"> <label for="marques{{marque.id}}">{{marque.marque}}</label> {% endfor %} </fieldset> <input type="hidden" name="page" value="{{page}}"> </form> </div> <div class="cards-container" id="content"> {# Contenu généré en Ajax #} {{ include('vehicules/_content.html.twig') }} </div> </div> </div> {% endblock %} {% block javascripts %} <script src="{{asset('assets/js/filters.js')}}" type="text/javascript"></script> {% endblock %}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 <div class="wrapper-sliders"> <form id="slidersForm"> <div class="range_container"> <p>Intervalle de prix en </p> <div class="sliders_control"> <input id="fromSlider" type="range" value="10" min="0" max="100"/> <input id="toSlider" type="range" value="30" min="0" max="100"/> </div> <div class="form_control"> <div class="form_control_container"> <div class="form_control_container__time">Min</div> <input class="form_control_container__time__input" type="number" id="fromInput" value="10" min="0" max="100"/> </div> <div class="form_control_container"> <div class="form_control_container__time">Max</div> <input class="form_control_container__time__input" type="number" id="toInput" value="30" min="0" max="100"/> </div> </div> </div> <div class="range_container"> <p>Ancienneté</p> <div class="sliders_control"> <input id="fromSlider" type="range" value="10" min="0" max="100"/> <input id="toSlider" type="range" value="30" min="0" max="100"/> </div> <div class="form_control"> <div class="form_control_container"> <div class="form_control_container__time">Min</div> <input class="form_control_container__time__input" type="number" id="fromInput" value="10" min="0" max="100"/> </div> <div class="form_control_container"> <div class="form_control_container__time">Max</div> <input class="form_control_container__time__input" type="number" id="toInput" value="30" min="0" max="100"/> </div> </div> </div> <div class="range_container"> <p>Kilométrage</p> <div class="sliders_control"> <input id="fromSlider" type="range" value="10" min="0" max="100"/> <input id="toSlider" type="range" value="30" min="0" max="100"/> </div> <div class="form_control"> <div class="form_control_container"> <div class="form_control_container__time">Min</div> <input class="form_control_container__time__input" type="number" id="fromInput" value="10" min="0" max="100"/> </div> <div class="form_control_container"> <div class="form_control_container__time">Max</div> <input class="form_control_container__time__input" type="number" id="toInput" value="30" min="0" max="100"/> </div> </div> </div> </form> </div> {% block javascripts %} <script src="{{asset('assets/js/sliders.js')}}" type="text/javascript" defer></script> {% endblock %}
sliders.js :
filters.js :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 window.onload = () => { const container = document.querySelectorAll(".range_container input"); container.forEach(input => { input.addEventListener("change", () => { function controlFromInput(fromSlider, fromInput, toInput, controlSlider) { const [from, to] = getParsed(fromInput, toInput); fillSlider(fromInput, toInput, "#C6C6C6", "#25daa5", controlSlider); if (from > to) { fromSlider.value = to; fromInput.value = to; } else { fromSlider.value = from; } } function controlToInput(toSlider, fromInput, toInput, controlSlider) { const [from, to] = getParsed(fromInput, toInput); fillSlider(fromInput, toInput, "#C6C6C6", "#25daa5", controlSlider); setToggleAccessible(toInput); if (from <= to) { toSlider.value = to; toInput.value = to; } else { toInput.value = from; } } function controlFromSlider(fromSlider, toSlider, fromInput) { const [from, to] = getParsed(fromSlider, toSlider); fillSlider(fromSlider, toSlider, "#C6C6C6", "#25daa5", toSlider); if (from > to) { fromSlider.value = to; fromInput.value = to; } else { fromInput.value = from; } } function controlToSlider(fromSlider, toSlider, toInput) { const [from, to] = getParsed(fromSlider, toSlider); fillSlider(fromSlider, toSlider, "#C6C6C6", "#25daa5", toSlider); setToggleAccessible(toSlider); if (from <= to) { toSlider.value = to; toInput.value = to; } else { toInput.value = from; toSlider.value = from; } } function getParsed(currentFrom, currentTo) { const from = parseInt(currentFrom.value, 10); const to = parseInt(currentTo.value, 10); return [from, to]; } function fillSlider(from, to, sliderColor, rangeColor, controlSlider) { const rangeDistance = to.max - to.min; const fromPosition = from.value - to.min; const toPosition = to.value - to.min; controlSlider.style.background = `linear-gradient( to right, ${sliderColor} 0%, ${sliderColor} ${(fromPosition / rangeDistance) * 100}%, ${rangeColor} ${(fromPosition / rangeDistance) * 100}%, ${rangeColor} ${(toPosition / rangeDistance) * 100}%, ${sliderColor} ${(toPosition / rangeDistance) * 100}%, ${sliderColor} 100%)`; } function setToggleAccessible(currentTarget) { const toSlider = document.querySelector("#toSlider"); if (Number(currentTarget.value) <= 0) { toSlider.style.zIndex = 2; } else { toSlider.style.zIndex = 0; } } const fromSlider = document.querySelector("#fromSlider"); const toSlider = document.querySelector("#toSlider"); const fromInput = document.querySelector("#fromInput"); const toInput = document.querySelector("#toInput"); fillSlider(fromSlider, toSlider, "#C6C6C6", "#25daa5", toSlider); setToggleAccessible(toSlider); fromSlider.oninput = () => controlFromSlider(fromSlider, toSlider, fromInput); toSlider.oninput = () => controlToSlider(fromSlider, toSlider, toInput); fromInput.oninput = () => controlFromInput(fromSlider, fromInput, toInput, toSlider); toInput.oninput = () => controlToInput(toSlider, fromInput, toInput, toSlider); }); }); };
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 window.onload = () => { const filtersForm = document.querySelector("#filters"); document.querySelectorAll("#filters input").forEach((input) => { input.addEventListener("change", () => { //Récupération des données du formulaire const Form = new FormData(filtersForm); console.log(Form); //Création de la queryString const Params = new URLSearchParams(); Form.forEach((value, key) => { Params.append(key, value); }); //Récupération de l'url active const Url = new URL(window.location.href); //Lancement requête Ajax fetch(Url.pathname + "?" + Params.toString() + "&ajax=1", { headers: { "X-Requested-With": "XMLHttpRequest", }, }) .then((response) => response.json()) .then((data) => { //Recherche de la zone de contenu const content = document.querySelector("#content"); //Remplacement du contenu content.innerHTML = data.content; //Mise à jour de l'url history.pushState({}, null, Url.pathname + "?" + Params.toString()); }) .catch((e) => alert(e)); }); }); };
sliders.css :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 .wrapper-sliders { display: flex; width: 100%; } #slidersForm { background-color: #fff; width: auto; height: auto; display: flex; flex-wrap: wrap; flex-direction: row; padding: 5px; } .range_container { display: flex; flex-direction: column; width: 200px; margin: 10px 40px; padding: 5px; } .sliders_control { position: relative; min-height: 35px; } .form_control { position: relative; display: flex; justify-content: space-between; font-size: 12px; color: #635a5a; } input[type="range"]::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; -moz-appearance: none; pointer-events: all; width: 24px; height: 24px; background-color: #fff; border-radius: 50%; box-shadow: 0 0 0 1px #c6c6c6; cursor: pointer; } input[type="range"]::-moz-range-thumb { appearance: none; -webkit-appearance: none; pointer-events: all; width: 24px; height: 24px; background-color: #fff; border-radius: 50%; box-shadow: 0 0 0 1px #c6c6c6; cursor: pointer; } input[type="range"]::-webkit-slider-thumb:hover { background: #f7f7f7; } input[type="range"]::-webkit-slider-thumb:active { box-shadow: inset 0 0 3px #387bbe, 0 0 9px #387bbe; -webkit-box-shadow: inset 0 0 3px #387bbe, 0 0 9px #387bbe; } input[type="number"] { color: #8a8383; width: 50px; height: 30px; font-size: 20px; border: none; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { font-size: 12px; opacity: 1; } input[type="range"] { -webkit-appearance: none; appearance: none; height: 2px; width: 100%; position: absolute; background-color: #c6c6c6; pointer-events: none; } #fromSlider { height: 0; z-index: 1; } .form_control_container__time__input { font-size: 12px; }