mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 22:53:49 +00:00
prepare for merging doc into mono-repository
This commit is contained in:
261
docs/source/development/user-interface/js-functions.rst
Normal file
261
docs/source/development/user-interface/js-functions.rst
Normal file
@@ -0,0 +1,261 @@
|
||||
.. Copyright (C) 2016 Champs Libres Cooperative SCRLFS
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
A copy of the license is included in the section entitled "GNU
|
||||
Free Documentation License".
|
||||
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: html+twig
|
||||
|
||||
<div id="container_from">
|
||||
{{ form_row(form.accompagnementRQTHDate) }}
|
||||
</div>
|
||||
|
||||
<div id="container_target">
|
||||
{{ form_row(form.accompagnementComment) }}
|
||||
</div>
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
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:
|
||||
|
||||
1. get all input from each element inside the ``froms`` values
|
||||
2. attach an event listener (by default, ``change``) to each input inside each entry in ``froms``
|
||||
3. each time the event is fired, launch the function ``test``
|
||||
4. show the element in the container given in ``container``, if the result of ``test`` 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.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
new ShowHide({
|
||||
froms: froms,
|
||||
test: test_function,
|
||||
container: containers ,
|
||||
// using this option, we use the event `input` instead of `change`
|
||||
event_name: 'input'
|
||||
});
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. literalinclude:: js-functions/show_hide.js
|
||||
:language: javascript
|
||||
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<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:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user