Javascript functions¶
Some function may be useful to manipulate elements on the page.
Show-hide elements according to a form state¶
The module ShowHide
will allow you to show/hide part of your page using a specific test.
This must be use inside a javascript module.
Usage¶
In this module, the module will listen to all input given in the container_from
div, and will show or hide the content of the container_target
according to the result of the test
function.
<div id="container_from">
{{ form_row(form.accompagnementRQTHDate) }}
</div>
<div id="container_target">
{{ form_row(form.accompagnementComment) }}
</div>
import { ShowHide } from 'ShowHide/show_hide.js';
var
from = document.getElementById("container_from"),
target = document.getElementById("container_target")
;
new ShowHide({
froms: [from], // the value of from should be an iterable
container: [target], // the value of container should be an iterable
test: function(froms, event) {
// iterate over each element of froms
for (let f of froms.values()) {
// get all input inside froms
for (let input of f.querySelectorAll('input').values()) {
if (input.value === 'autre') {
return input.checked;
}
}
}
return false;
}
});
Once instantiated, the class ShowHide
will:
- get all input from each element inside the
froms
values - attach an event listener (by default,
change
) to each input inside each entry infroms
- each time the event is fired, launch the function
test
- show the element in the container given in
container
, if the result oftest
is true, or hide them otherwise.
The test is also launched when the page is loaded.
Show/hide while the user enter data: using the input
event¶
One can force to use another event on the input elements, instead of the default 'change'
event.
For achieving this, use the event_name option.
new ShowHide({
froms: froms,
test: test_function,
container: containers ,
// using this option, we use the event `input` instead of `change`
event_name: 'input'
});
Examples¶
import { ShowHide } from "ShowHide/show_hide.js";
var div_accompagnement = document.getElementById("form_accompagnement"),
div_accompagnement_comment = document.getElementById(
"form_accompagnement_comment",
),
div_caf_id = document.getElementById("cafId"),
div_caf_inscription_date = document.getElementById("cafInscriptionDate");
// let show/hide the div_accompagnement_comment if the input with value `'autre'` is checked
new ShowHide({
froms: [div_accompagnement],
test: function (froms, event) {
for (let el of froms.values()) {
for (let input of el.querySelectorAll("input").values()) {
if (input.value === "autre") {
return input.checked;
}
}
}
return false;
},
container: [div_accompagnement_comment],
});
// let show the date input only if the the id is filled
new ShowHide({
froms: [div_caf_id],
test: function (froms, event) {
for (let el of froms.values()) {
return el.querySelector("input").value !== "";
}
},
container: [div_caf_inscription_date],
// using this option, we use the event `input` instead of `change`
event_name: "input",
});
Using Show/Hide in collections forms¶
Using show / hide in collection forms implies:
- to launch show/hide manually for each entry when the page is loaded ;
- to catch when an entry is added to the form ;
As the show/hide is started manually and not on page load, we add the option load_event: null
to the options:
new ShowHide({
load_event: null,
froms: [ from ],
container: [ container ],
test: my_test_function
});
Note
When using load_event: null
inside the options, the value of event will be null
as second argument for the test function.
my_test_function(froms, event) {
// event will be null on first launch
}
Example usage: here, we would like to catch for element inside a CV form, where the user may add multiple formation entries.
import { ShowHide } from 'ShowHide/show_hide.js';
// we factorize the creation of show hide element in this function.
var make_show_hide = function(entry) {
let
obtained = entry.querySelector('[data-diploma-obtained]'),
reconnue = entry.querySelector('[data-diploma-reconnue]')
;
new ShowHide({
load_event: null,
froms: [ obtained ],
container: [ reconnue ],
test: my_test_function
});
};
// this code is fired when an entry is added on the page
window.addEventListener('collection-add-entry', function(e) {
// if the form contains multiple collection, we filter them here:
if (e.detail.collection.dataset.collectionName === 'formations') {
make_show_hide(e.detail.entry);
}
});
// on page load, we create a show/hide
window.addEventListener('load', function(_e) {
let
formations = document.querySelectorAll('[data-formation-entry]')
;
for (let f of formations.values()) {
make_show_hide(f);
}
});
Handling encapsulated show/hide elements¶
This module allow to handle encapsulated show/hide elements. For instance :
- in a first checkbox list, a second checkbox list is shown if some element is checked ;
- in this second checkbox list, a third input is shown if some element is checked inside the second checkbox list.
As a consequence, if the given element in the first checkbox list is unchecked, the third input must also be hidden.
Example: when a situation professionnelle is en activite
, the second element type contrat
must be shown if en_activite
is checked. Inside type_contrat
, type_contrat_aide
should be shown when contrat_aide
is checked.
<div id="situation_prof">
<input type="radio" name="situationProfessionnelle" value="" checked="checked" />
<input type="radio" name="situationProfessionnelle" value="sans_emploi" />
<input type="radio" name="situationProfessionnelle" value="en_activite" />
</div>
<div id="type_contrat">
<input type="checkbox" name="typeContrat[]" value="cdd" />
<input type="checkbox" name="typeContrat[]" value="cdi" />
<input type="checkbox" name="typeContrat[]" value="contrat_aide" />
</div>
<div id="type_contrat_aide">
<input type="text" name="typeContratAide" />
</div>
The JS code will be:
import { ShowHide } from 'ShowHide/show_hide.js';
// we search for the element within the DOM
// NOTE: all the elements should be searched before instanciating the showHides.
// if not, the elements **may** have disappeared from the DOM
var
situation_prof = document.getElementById('situation_prof'),
type_contrat = document.getElementById('type_contrat'),
type_contrat_aide = document.getElementById('type_contrat_aide'),
;
// the first show/hide will apply on situation_prof
new ShowHide({
// the id will help us to keep a track of the element
id: 'situation_prof_type_contrat',
froms: [situation_prof],
container: [type_contrat],
test: function(froms) {
for (let f of froms.values()) {
for (let input of f.querySelectorAll('input').values()) {
if (input.value === 'en_activite') {
return input.checked;
}
}
}
return false;
}
});
// the show/hide will apply on "contrat aide"
var show_hide_contrat_aide = new ShowHide({
froms: [type_contrat],
container: [type_contrat_aide],
test: function(froms) {
for (let f of froms.values()) {
for (let input of f.querySelectorAll('input').values()) {
if (input.value === 'contrat_aide') {
return input.checked;
}
}
}
return false;
}
});
// we handle here the case when the first show-hide is changed: the third input must also disappears
window.addEventListener('show-hide-hide', function (e) {
if (e.detail.id = 'situation_prof_type_contrat') {
// we force the 3rd element to disappears
show_hide_contrat_aide.forceHide();
}
});
// when the first show-hide is changed, it makes appears the second one.
// we check here that the second show-hide is processed.
window.addEventListener('show-hide-show', function (e) {
if (e.detail.id = 'situation_prof_type_contrat') {
show_hide_contrat_aide.forceCompute();
}
});