PageSourceSearch

https://www.berreletang.fr/plugins/auto/saisies/v6.3.8/javascript/saisies_afficher_si.js?1790330871

js berreletang.fr collected 2026-10-02 17:37:11 UTC 12,550 bytes, 379 lines download raw bytes

1$(function(){
2	afficher_si_init();
3	onAjaxLoad(afficher_si_init);
4});
5afficher_si_current_data = '';
6function afficher_si_init() {
7	$('form:not([data-afficher_si-init])').each(function(){
8		form = $(this);
9		// Seulement si au moins un afficher_si dedans !
10		if (this.hasAttribute('data-resume_etapes_futures')) {
11			var resume_etapes_futures = this.getAttribute('data-resume_etapes_futures');
12		} else {
13			var resume_etapes_futures = '';
14		}
15		let conteneur_extra = '';
16		let react = [form];
17		if (this.hasAttribute('data-afficher_si_conteneur_extra')) {
18			conteneur_extra = this.getAttribute('data-afficher_si_conteneur_extra');
19			react.push($(conteneur_extra));
20		}
21
22		if ($(this).find('[data-afficher_si]').length !== 0 || resume_etapes_futures || conteneur_extra) {
23			form.find('.formulaire_spip__etapes').each(function() {
24				$(this).css('min-height', $(this).height());
25			});
26			afficher_si_init_chemin_etapes(form);
27
28			afficher_si_set_current_data(form);
29
30			react.forEach(function (r) {
31				r.find('[data-afficher_si]').each(function() {
32					condition = verifier_afficher_si($(this), true);
33					animer_afficher_si($(this), condition, true);
34				});
35			});
36			afficher_si_set_etapes_presentation_courante(form);
37			afficher_si_set_etape_suivante(form);
38
39			// Un écouteur sur les champs qui conditionnent d'autres champs
40			$(this).find('textarea, input, select').each(function () {
41				var name = $(this).attr('name');
42				if (name) {
43					name = afficher_si_normaliser_name(name);
44					if (
45						form.find('[data-afficher_si*=\''+name+'\']').length
46						|| resume_etapes_futures.includes(name)
47						|| $(conteneur_extra).find('[data-afficher_si*=\''+name+'\']').length
48					) {
49						$(this).on('input change', function() {
50							afficher_si_onchange($(this));
51						});
52					}
53				}
54			}
55			);
56			$(this).attr('data-afficher_si-init', true);
57		}
58	})
59}
60
61/**
62 * Normaliser les names
63 * @param string name
64 * @return return name
65**/
66function afficher_si_normaliser_name(name) {
67	var name = name.replace('[]', '');
68	var name = name.replace('_choix_alternatif', '');
69	return name;
70}
71/**
72 * Ecouteur sur les champ
73 * @param jQuery Object $champ
74**/
75function afficher_si_onchange($champ) {
76	// Seulement si ce champ a un name
77	if (name = $champ.attr('name')) {
78		var form = $champ.parents('form');
79
80		let react = [form];
81		if (form.attr('data-afficher_si_conteneur_extra')) {
82			conteneur_extra = form.attr('data-afficher_si_conteneur_extra');
83			react.push($(conteneur_extra));
84		}
85
86		var name = afficher_si_normaliser_name(name);
87		afficher_si_set_current_data(form);
88
89		// Si un autre champ (ou pas) utilise celui-ci dans une condition
90		react.forEach(function (r) {
91			r.find('[data-afficher_si*=\''+name+'\']').each(function(){
92			condition = verifier_afficher_si($(this));
93			animer_afficher_si($(this), condition);
94			})
95		});
96		afficher_si_set_etapes_presentation_courante(form, name);
97		afficher_si_set_etape_suivante(form, name);
98	}
99}
100function afficher_si_set_current_data(form) {
101	current_data = form.serializeArray();//Le format de retour n'est pas simple, on transforme en tableau associatif
102	afficher_si_current_data = [];
103	$(current_data).each(function() {
104		if (this.name.includes('[]')) {
105			this.name	= this.name.replace('[]', '');
106			if (Array.isArray(afficher_si_current_data[this.name])) {
107				afficher_si_current_data[this.name].push(this.value)
108			} else {
109				afficher_si_current_data[this.name] = [this.value];
110			}
111		} else {
112			afficher_si_current_data[this.name] = this.value;
113		}
114	 if (afficher_si_current_data[this.name] === '@choix_alternatif') {
115		 afficher_si_current_data[this.name] = form.find('[name = "' + this.name + '_choix_alternatif' + '"]').val();
116		 afficher_si_current_data[this.name + ':choix_alternatif'] = true;// Usage interne, pas de stabilité de l'API
117	 } else {
118		 afficher_si_current_data[this.name + ':choix_alternatif'] = false;// Usage interne, pas de stabilité de l'API
119	 }
120	});
121}
122function verifier_afficher_si(saisie, chargement = false) {
123	let condition = saisie.attr('data-afficher_si');
124	condition = eval(condition);
125	if (
126		chargement
127		&& !condition
128		&& (saisie.hasClass('erreur') || $('.erreur', saisie).length)
129		&& !saisie.hasClass('saisies-menu-onglets__item')
130		&& !saisie.hasClass('saisies-contenu-onglet')
131	) {//Tjr afficher au chargement s'il y  une erreur. Si cela arrive c'est qu'il y a quelque part une incohérence entre l'évaluation JS et l'évaluation PHP des afficher si. Attention ! Ne pas appliquer aux onglets qui ont des classes erreurs, ca c'est volontaire
132		console.log('Attention : saisies masquée par afficher_si avec une erreur...' + saisie.attr('data-id'));
133		return true;
134	}
135	return condition
136}
137function animer_afficher_si(saisie, condition, chargement){
138	if (condition) {
139		if (!saisie.hasClass('afficher_si_visible')) {
140			saisie.trigger('afficher_si_visible_pre');
141			saisie.removeClass('afficher_si_masque_chargement').removeClass('afficher_si_masque').addClass('afficher_si_visible').removeAttr('aria-hiden');
142			if (!saisie.hasClass('afficher_si_sans_visuel')) {
143				afficher_si_show(saisie);
144			}
145			afficher_si_restaure_validation(saisie);
146			saisie.trigger('afficher_si_visible_post');
147		}
148	} else {
149		if (!saisie.hasClass('afficher_si_masque')) {
150			saisie.trigger('afficher_si_masque_pre');
151			if (!saisie.hasClass('afficher_si_sans_visuel')) {
152				afficher_si_hide(saisie);
153			}
154			if (chargement) {
155				saisie.addClass('afficher_si_masque_chargement');
156			}
157			saisie.addClass('afficher_si_masque').removeClass('afficher_si_visible').attr('aria-hiden', true);
158			afficher_si_disable_validation(saisie);
159			saisie.trigger('afficher_si_masque_post');
160		}
161	}
162}
163/**
164 * Prend les attribut de validation au sein d'une saisie et les supprime
165 * tout en stockant en mémoire dans des data-truc
166 * @param $saisie la saisie (conteneur)
167**/
168function afficher_si_disable_validation($saisie) {
169	for (attribut of afficher_si_validation_attributs) {
170		if (attribut in afficher_si_validation_attributs_valeurs) {
171			var selecteur = afficher_si_validation_attributs_valeurs[attribut].map((x) => '[' + attribut + '=' + x + ']').join(', ');
172		} else {
173			var selecteur = '[' + attribut + ']';
174		}
175		var enfants = $saisie.find(selecteur);
176		enfants.each(function() {
177			$(this).attr('data-afficher_si-' + attribut, $(this).attr(attribut)).attr(attribut, null);
178		});
179	}
180}
181
182/**
183 * Rétabli si besoin les attribut de validation au sein d'une saisie
184 * @param $saisie la saisie (conteneur)
185**/
186function afficher_si_restaure_validation($saisie) {
187	for (attribut of afficher_si_validation_attributs) {
188		var enfants = $saisie.find('[data-afficher_si-' + attribut + ']');
189		enfants.each(function() {
190			if ($(this).parents('.afficher_si_masque').length == 0) {
191				$(this).attr(attribut, $(this).attr('data-afficher_si-' + attribut)).attr('data-afficher_si-' + attribut, null);
192			}
193		});
194	}
195}
196
197
198var afficher_si_validation_attributs = [
199	'required',
200	'minlength',
201	'maxlength',
202	'min',
203	'max',
204	'type',
205	'step',
206	'pattern'
207];
208var afficher_si_validation_attributs_valeurs = {'type': ['email', 'url']};
209// Ref https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#validation-related_attributes
210
211
212function afficher_si(args) {
213	if (afficher_si_current_data.hasOwnProperty(args['champ'])) {
214		valeur_champ = afficher_si_current_data[args['champ']];
215	} else {
216		valeur_champ = '';
217	}
218	valeur = args['valeur'];
219	if (!('modificateur' in args)) {
220		args['modificateur'] = {'fonction' : ''};
221	}
222
223	// Compat historique == > IN pour données tabulaires !
224	if (
225		Array.isArray(valeur_champ)
226		&& (args['modificateur']['fonction'] !== 'total')
227	) {
228		if (args['operateur'] == '==') {
229			args['operateur'] = 'IN';
230		} else if(args['operateur'] == '!=') {
231			args['operateur'] = '!IN';
232		}
233	}
234
235	// Si on vérifie un modificateur 'total' est à appliquer sur la valeur du champ de saisie
236	if (args['modificateur']['fonction'] === 'total') {
237		if (Array.isArray(valeur_champ)) {
238			valeur_champ = valeur_champ.length;
239		} else {
240			valeur_champ = 0;
241		}
242	}
243
244	// Si on vérifie un modificateur 'substr' est à appliquer sur la valeur du champ de saisie
245	if (args['modificateur']['fonction'] === 'substr') {
246		// A priori inutile de tester le type car c'est déjà fait dans la fonction PHP
247		if (args['modificateur']['arguments'][1]) {
248			valeur_champ = valeur_champ.substr(args['modificateur']['arguments'][0], args['modificateur']['arguments'][1]);
249		} else {
250			valeur_champ = valeur_champ.substr(args['modificateur']['arguments'][0]);
251		}
252	}
253
254	// Transformation en tableau des valeurs et valeur_champ, si IN/!IN
255	if (args['operateur'] == 'IN' || args['operateur'] == '!IN') {
256		valeur = valeur.split(',');
257		if (!Array.isArray(valeur_champ)) {
258			if (valeur_champ) {
259				valeur_champ = [valeur_champ];
260			} else {
261				valeur_champ = [];
262			}
263		}
264	}
265
266	// Transformation en entier des valeurs et valeur_champ, si opérateur de comparaison
267	if (['<', '<=', '>=', '>'].includes(args['operateur'])) {
268		valeur = Number(valeur);
269		valeur_champ = Number(valeur_champ);
270	}
271
272	// Et maintenant les test
273	switch (args['operateur']) {
274		case '==':
275			return valeur_champ == valeur;
276		case '!=':
277			return valeur_champ != valeur;
278		case '>':
279			return valeur_champ > valeur;
280		case '>=':
281			return valeur_champ >= valeur;
282		case '<':
283			return valeur_champ < valeur;
284		case '<=':
285			return valeur_champ <= valeur;
286		case 'MATCH':
287			return RegExp(valeur, args.regexp_modif).test(valeur_champ);
288		case '!MATCH':
289			return !RegExp(valeur, args.regexp_modif).test(valeur_champ);
290		case 'IN':
291			return $(valeur).filter(valeur_champ).length ? true : false;
292		case '!IN':
293			return $(valeur).filter(valeur_champ).length ? false : true;
294		default:
295			return valeur_champ ? true : false;
296	}
297}
298
299
300//Pour l'affichage des étapes selon la présentation "étape courante" seulement
301//@param form, le formulaire
302//@param name le nom de la saisie dont la valeur vient juste de changer
303function afficher_si_set_etapes_presentation_courante(form, name='') {
304	var etapes = afficher_si_parse_data_etapes_futures(form);
305	if (!etapes) {
306		return;
307	}
308	form.find('[data-etapes_max]').each(function() {
309		var etape_total = $(this).attr('data-etapes_max');
310		for (etape in etapes) {
311			var condition = etapes[etape]['afficher_si'] ?? 'true';
312			if (!name || condition.includes(name)) {
313				$(this).attr('data-' + etape, eval(condition));
314			}
315			if (condition && !eval($(this).attr('data-' + etape))) {
316				etape_total--;
317			}
318		}
319		$(this).find('.formulaire_spip_etape__total').text(etape_total);
320	});
321}
322
323// Pour le libellé de l'étape suivante
324//@param form, le formulaire
325//@param name le nom de la saisie dont la valeur vient juste de changer
326function afficher_si_set_etape_suivante(form, name) {
327	var etapes = afficher_si_parse_data_etapes_futures(form);
328	if (!etapes) {
329		return;
330	}
331
332	var label_enregistrer = form.find('button.submit_suivant').attr('data-label_enregistrer');
333	var titre_retenu = label_enregistrer;
334	// Chercher la première future étape
335	for (etape in etapes) {
336		var afficher_si_etape = etapes[etape]['afficher_si'] ?? 'true';
337		if (eval(afficher_si_etape)) {
338			titre_retenu = etapes[etape]['label'];
339			break;
340		}
341	}
342	form.find('button.submit_suivant').each(function() {
343		var $span = $(this).find('.btn__label');
344		// Stocker le modèle pour suivant, si pas deja fait
345		if (!$(this).attr('data-modele')) {
346			$(this).attr('data-modele', $span.html());
347		}
348		// Puis ajuster le titre, le modèle variant selon que nous passons directement à la validation ou pas
349		if (titre_retenu == label_enregistrer) {
350			$span.html(titre_retenu);
351		} else {
352			$span.html($(this).attr('data-modele'));
353			$span.find('.titre-etape').html(titre_retenu);
354		}
355	});
356}
357// Recopier les info d'afficher_si présente dans [data-resume_etapes_futures] au sein de chaque etapes futures
358// Le but est de simplifier ainsi le code principal, en se contentant du code de animer_afficher_si()
359// @param jquery obcet form
360function afficher_si_init_chemin_etapes(form) {
361	var etapes = afficher_si_parse_data_etapes_futures(form);
362	if (!etapes) {
363		return;
364	}
365	for (etape in etapes) {
366		var afficher_si_etape = etapes[etape]['afficher_si'] ?? '';
367		if (afficher_si_etape) {
368			form.find('.etapes__item.' + etape).attr('data-afficher_si', afficher_si_etape).addClass('afficher_si_sans_visuel');
369		}
370	}
371}
372function afficher_si_parse_data_etapes_futures(form) {
373	var data = form.attr('data-resume_etapes_futures');
374	if (!data) {
375		return;
376	}
377	var etapes = JSON.parse(data);
378	return etapes;
379}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.