Browse Source

Nouvelle option pour la description .yaml d'une saisie : hériter d'une

autre saisie.

Possibilité d'avoir des héritages en cascade.
Possibilité de régler précisement les options héritées ou pas, via des
entrées dans le .yaml.

Pour la documentation, voir
https://contrib.spip.net/ecrire/?exec=article&id_article=5272

Pour des exemples :
- dans ce dossier, les tests (tests/saisies + tests/saisies_heriter)
- la saisie nombre :
https://git.spip.net/spip-contrib-extensions/saisie_nombre
- la saisie calcul : https://git.spip.net/spip-contrib-extensions/saisie_calcul

En bonus :
- Ajout d'une fonction saisies_supprimer_identifiants() qui supprime récursivement les identifiants d'une saisie. À utiliser sur les tests unitaires pour éviter d'avoir un identifiant qui change à chaque test.
- saisies_modifier(), une option 'fusion', suite à la demande de @Rastapopoulos. en spip-contrib-extensions/formidable#25

git-svn-id: svn://svn.spip.net/spip-zone/_plugins_/saisies@124667 ac52e18a-acf5-0310-9fe8-c4428f23b10a
old_history/pre_trunk
Maïeul Rouquette 3 years ago
parent
commit
bedb588e9d
  1. 49
      shelves/master/action/deplacer_saisie.php
  2. 5
      shelves/master/aide/saisies.html
  3. 43
      shelves/master/balise/configurer_saisie.php
  4. 55
      shelves/master/balise/generer_saisies.php
  5. 273
      shelves/master/balise/saisie.php
  6. 52
      shelves/master/balise/voir_saisie.php
  7. 57
      shelves/master/balise/voir_saisies.php
  8. 126
      shelves/master/css/formulaires_constructeur.css
  9. 51
      shelves/master/demo/configurer_saisie.html
  10. 106
      shelves/master/demo/formulaire-afficher_si_test.yaml
  11. 152
      shelves/master/demo/generer_saisies.html
  12. 17
      shelves/master/demo/page-saisies_cvt.html
  13. 11
      shelves/master/demo/saisie.html
  14. 10
      shelves/master/demo/voir_saisie.html
  15. 147
      shelves/master/demo/voir_saisies.html
  16. 264
      shelves/master/formulaires/construire_formulaire.html
  17. 712
      shelves/master/formulaires/construire_formulaire.php
  18. 27
      shelves/master/formulaires/inc-construire_formulaire-actions.html
  19. 9
      shelves/master/formulaires/inc-generer_saisies_configurables.html
  20. 13
      shelves/master/formulaires/inc-saisies-cvt-etapes.html
  21. 42
      shelves/master/formulaires/inc-saisies-cvt.html
  22. 0
      shelves/master/formulaires/saisies_cvt.html
  23. 106
      shelves/master/formulaires/saisies_cvt.php
  24. BIN
      shelves/master/images/formulaire-annuler-16.png
  25. BIN
      shelves/master/images/formulaire-configurer-16.png
  26. BIN
      shelves/master/images/formulaire-deplacer-16.png
  27. BIN
      shelves/master/images/formulaire-dupliquer-16.png
  28. BIN
      shelves/master/images/formulaire-enregistrer-16.png
  29. BIN
      shelves/master/images/formulaire-reinitialiser-24.png
  30. BIN
      shelves/master/images/formulaire-saisie-defaut.png
  31. BIN
      shelves/master/images/formulaire-supprimer-16.png
  32. BIN
      shelves/master/images/logo_saisie_48.png
  33. BIN
      shelves/master/images/saisies-16.png
  34. BIN
      shelves/master/images/saisies-24.png
  35. BIN
      shelves/master/images/saisies-32.png
  36. BIN
      shelves/master/images/saisies_auteurs.png
  37. BIN
      shelves/master/images/saisies_case.png
  38. BIN
      shelves/master/images/saisies_checkbox.png
  39. BIN
      shelves/master/images/saisies_date.png
  40. BIN
      shelves/master/images/saisies_email.png
  41. BIN
      shelves/master/images/saisies_explication.png
  42. BIN
      shelves/master/images/saisies_fieldset.png
  43. BIN
      shelves/master/images/saisies_hidden.png
  44. BIN
      shelves/master/images/saisies_input.png
  45. BIN
      shelves/master/images/saisies_oui_non.png
  46. BIN
      shelves/master/images/saisies_radio.png
  47. BIN
      shelves/master/images/saisies_selecteur_article.png
  48. BIN
      shelves/master/images/saisies_selecteur_rubrique.png
  49. BIN
      shelves/master/images/saisies_selecteur_rubrique_article.png
  50. BIN
      shelves/master/images/saisies_selection.png
  51. BIN
      shelves/master/images/saisies_selection_multiple.png
  52. BIN
      shelves/master/images/saisies_textarea.png
  53. 699
      shelves/master/inc/saisies.php
  54. 312
      shelves/master/inc/saisies_afficher.php
  55. 215
      shelves/master/inc/saisies_afficher_si_commun.php
  56. 215
      shelves/master/inc/saisies_afficher_si_js.php
  57. 214
      shelves/master/inc/saisies_afficher_si_php.php
  58. 627
      shelves/master/inc/saisies_lister.php
  59. 335
      shelves/master/inc/saisies_manipuler.php
  60. 52
      shelves/master/inc/saisies_migrer_afficher_si_remplissage.php
  61. 19
      shelves/master/inclure/configurer_saisie.html
  62. 39
      shelves/master/inclure/configurer_saisie_fonctions.php
  63. 8
      shelves/master/inclure/fieldset_legend.html
  64. 55
      shelves/master/inclure/generer_saisies.html
  65. 12
      shelves/master/inclure/generer_saisies_fonctions.php
  66. 65
      shelves/master/inclure/saisies_aide.html
  67. 12
      shelves/master/inclure/voir_saisies.html
  68. 34
      shelves/master/javascript/afficher_si.js
  69. 62
      shelves/master/javascript/saisies.js
  70. 34
      shelves/master/lang/paquet-saisies.xml
  71. 18
      shelves/master/lang/paquet-saisies_ar.php
  72. 17
      shelves/master/lang/paquet-saisies_de.php
  73. 19
      shelves/master/lang/paquet-saisies_en.php
  74. 17
      shelves/master/lang/paquet-saisies_es.php
  75. 17
      shelves/master/lang/paquet-saisies_fr.php
  76. 19
      shelves/master/lang/paquet-saisies_fr_tu.php
  77. 17
      shelves/master/lang/paquet-saisies_nl.php
  78. 17
      shelves/master/lang/paquet-saisies_pt_br.php
  79. 17
      shelves/master/lang/paquet-saisies_ru.php
  80. 17
      shelves/master/lang/paquet-saisies_sk.php
  81. 54
      shelves/master/lang/saisies.xml
  82. 119
      shelves/master/lang/saisies_ca.php
  83. 213
      shelves/master/lang/saisies_de.php
  84. 255
      shelves/master/lang/saisies_en.php
  85. 198
      shelves/master/lang/saisies_es.php
  86. 135
      shelves/master/lang/saisies_fa.php
  87. 253
      shelves/master/lang/saisies_fr.php
  88. 250
      shelves/master/lang/saisies_fr_tu.php
  89. 173
      shelves/master/lang/saisies_it.php
  90. 254
      shelves/master/lang/saisies_nl.php
  91. 216
      shelves/master/lang/saisies_pt_br.php
  92. 187
      shelves/master/lang/saisies_ru.php
  93. 195
      shelves/master/lang/saisies_sk.php
  94. 39
      shelves/master/paquet.xml
  95. 3
      shelves/master/prive/exec/construire_formulaire.html
  96. 14
      shelves/master/prive/listes/articles_originaux_recursifs.html
  97. 8
      shelves/master/prive/listes/rubriques_recursives.html
  98. 34
      shelves/master/prive/squelettes/contenu/saisies_doc.html
  99. 9
      shelves/master/prive/squelettes/navigation/saisies_doc.html
  100. 23
      shelves/master/prive/style_prive_plugin_saisies.html
  101. Some files were not shown because too many files have changed in this diff Show More

49
shelves/master/action/deplacer_saisie.php

@ -0,0 +1,49 @@
<?php
/**
* Gestion de l'action déplacer saisie.
*
* @package SPIP\Saisies\Action
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Action de déplacement de saisies dans le constructeur de formulaires
*
* @return void
**/
function action_deplacer_saisie_dist() {
include_spip('inc/session');
$session = _request('session');
$identifiant = _request('saisie');
$ou = _request('ou');
// On récupère le formulaire à son état actuel
$formulaire_actuel = session_get($session);
if (!$formulaire_actuel) {
return '';
}
include_spip('inc/saisies');
$saisies_actuelles = saisies_lister_par_identifiant($formulaire_actuel);
if (!isset($saisies_actuelles[$identifiant])) {
return '';
}
// tester @id et [@id] (fieldset)
if ($ou and !isset($saisies_actuelles[$ou]) and !isset($saisies_actuelles[ substr($ou, 1, -1) ])) {
return '';
}
// on deplace ou c'est demande...
$formulaire_actuel = saisies_deplacer($formulaire_actuel, $identifiant, $ou);
// On sauve tout ca
$formulaire_actuel = session_set($session, $formulaire_actuel);
}

5
shelves/master/aide/saisies.html

@ -0,0 +1,5 @@
<h1>Références complètes des saisies</h1>
[(#ENV{format}|=={brut}|oui)<textarea style="width:100%; height:100%;">]
[(#VAL|saisies_generer_aide)]
[(#ENV{format}|=={brut}|oui)</textarea>]

43
shelves/master/balise/configurer_saisie.php

@ -0,0 +1,43 @@
<?php
/**
* Déclaration de la balise `#CONFIGURER_SAISIE`
*
* @package SPIP\Saisies\Balises
*/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Compile la balise `#CONFIGURER_SAISIE`
*
* @uses Pile::recuperer_et_supprimer_argument_balise()
* @uses Pile::creer_et_ajouter_argument_balise()
* @see balise_INCLURE_dist()
*
* @param Champ $p
* @return Champ
**/
function balise_CONFIGURER_SAISIE_dist($p) {
// On recupere le premier argument : le nom de la saisie
$saisie = Pile::recuperer_et_supprimer_argument_balise(1, $p);
// On ajoute le squelette a inclure dans les parametres
$p = Pile::creer_et_ajouter_argument_balise($p, 'fond', 'inclure/configurer_saisie');
// On ajoute l'environnement
$p = Pile::creer_et_ajouter_argument_balise($p, 'env');
// On ajoute le nom recupere
$p = Pile::creer_et_ajouter_argument_balise($p, 'saisie', $saisie);
// On redirige vers la balise INCLURE
if (function_exists('balise_INCLURE')) {
return balise_INCLURE($p);
} else {
return balise_INCLURE_dist($p);
}
}

55
shelves/master/balise/generer_saisies.php

@ -0,0 +1,55 @@
<?php
/**
* Gestion de la balise `#GENERER_SAISIES`
*
* @package SPIP\Saisies\Balises
*/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Compile la balise `#GENERER_SAISIES` qui retourne le code HTML des saisies de formulaire,
* à partir du tableau des saisies transmises
*
* La balise accepte 1 paramètre qui est une liste de descriptions de saisies
* dont on veut générer le HTML affichant les champs du formulaires
*
* Cette balise est un raccourcis :
* - `#GENERER_SAISIES{#TABLEAU_DE_SAISIES}` est équivalent à
* - `#INCLURE{fond=inclure/generer_saisies,env,saisies=#TABLEAU_DE_SAISIES}`
*
* @syntaxe `#GENERER_SAISIE{#TABLEAU_DE_SAISIES}`
* @uses Pile::recuperer_et_supprimer_argument_balise()
* @uses Pile::creer_et_ajouter_argument_balise()
* @see balise_INCLURE_dist()
*
* @param Champ $p
* Pile au niveau de la balise
* @return Champ
* Pile complété du code à générer
**/
function balise_GENERER_SAISIES_dist($p) {
// On recupere le premier (et seul) argument : le tableau decrivant ce qu'on veut generer
$config = Pile::recuperer_et_supprimer_argument_balise(1, $p);
// On ajoute le squelette a inclure dans les parametres
$p = Pile::creer_et_ajouter_argument_balise($p, 'fond', 'inclure/generer_saisies');
// On ajoute l'environnement
$p = Pile::creer_et_ajouter_argument_balise($p, 'env');
// On ajoute le tableau recupere
$p = Pile::creer_et_ajouter_argument_balise($p, 'saisies', $config);
// On redirige vers la balise INCLURE
if (function_exists('balise_INCLURE')) {
return balise_INCLURE($p);
} else {
return balise_INCLURE_dist($p);
}
}

273
shelves/master/balise/saisie.php

@ -0,0 +1,273 @@
<?php
/**
* Déclaration de la classe `Pile` et de la balise `#SAISIE`
*
* @package SPIP\Saisies\Balises
**/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
// pour ne pas interferer avec d'eventuelles futures fonctions du core
// on met le tout dans une classe ; les fonctions sont autonomes.
/**
* Conteneur pour modifier les arguments d'une balise SPIP (de classe Champ) à compiler
*
* @note
* Ces fonctions visent à modifier l'AST (Arbre de Syntaxe Abstraite) issues
* de l'analyse du squelette. Très utile pour créer des balises qui
* transmettent des arguments supplémentaires automatiquement, à des balises
* déjà existantes.
* Voir un exemple d'utilisation dans `balise_SAISIE_dist()`.
*
* @note
* Les arguments sont stockés sont dans l'entree 0 de la propriété `param`
* dans l'objet Champ (représenté par `$p`), donc dans `$p->param[0]`.
*
* `param[0][0]` vaut toujours '' (ou presque ?)
*
* @see balise_SAISIE_dist() Pour un exemple d'utilisation
**/
class Pile {
/**
* Récupère un argument de balise
*
* @param int $pos
* @param Champ $p
* @return mixed|null Élément de l'AST représentant l'argument s'il existe
**/
static function recuperer_argument_balise($pos, $p) {
if (!isset($p->param[0])) {
return null;
}
if (!isset($p->param[0][$pos])) {
return null;
}
return $p->param[0][$pos];
}
/**
* Supprime un argument de balise
*
* @param int $pos
* @param Champ $p
* @return Champ
**/
static function supprimer_argument_balise($pos, $p) {
if (!isset($p->param[0])) {
return null;
}
if (!isset($p->param[0][$pos])) {
return null;
}
if ($pos == 0) {
array_shift($p->param[0]);
} else {
$debut = array_slice($p->param[0], 0, $pos);
$fin = array_slice($p->param[0], $pos+1);
$p->param[0] = array_merge($debut, $fin);
}
return $p;
}
/**
* Retourne un argument de balise, et le supprime de la liste des arguments
*
* @uses Pile::recuperer_argument_balise()
* @uses Pile::supprimer_argument_balise()
*
* @param int $pos
* @param Champ $p
* @return mixed|null Élément de l'AST représentant l'argument s'il existe
**/
static function recuperer_et_supprimer_argument_balise($pos, &$p) {
$arg = Pile::recuperer_argument_balise($pos, $p);
$p = Pile::supprimer_argument_balise($pos, $p);
return $arg;
}
/**
* Ajoute un argument de balise
*
* Empile l'argument à la suite des arguments déjà existants pour la balise
*
* @param mixed $element Élément de l'AST représentant l'argument à ajouter
* @param Champ $p
* @return Champ
**/
static function ajouter_argument_balise($element, $p) {
// Toujours un parametre 0 vide s'il n'existe pas.
if (!isset($p->param[0][0])) {
if (!isset($p->param[0])) {
$p->param[0] = array();
}
$p->param[0][0] = '';
}
$zero = array_shift($p->param[0]);
array_unshift($p->param[0], $element);
array_unshift($p->param[0], $zero);
return $p;
}
/**
* Crée l'élément de l'AST représentant un argument de balise.
*
* @example
* ```
* $nom = Pile::creer_argument_balise(nom); // {nom}
* $nom = Pile::creer_argument_balise(nom, 'coucou'); // {nom=coucou}
*
* $balise = Pile::creer_balise('BALISE');
* $nom = Pile::creer_argument_balise(nom, $balise); // {nom=#BALISE}
* ```
*
* @param string $nom
* Nom de l'argument
* @param string|object $valeur
* Valeur de l'argument. Peut être une chaîne de caractère ou un autre élément d'AST
* @return array
**/
static function creer_argument_balise($nom, $valeur = null) {
include_spip('public/interfaces');
$s = new Texte;
$s->texte = $nom;
$s->ligne=0;
// si #BALISE cree avec Pile::creer_balise(), le mettre en array, comme les autres
if (is_object($valeur)) {
$valeur = array($valeur);
}
$res = null;
// {nom}
if (is_null($valeur)) {
$res = array($s);
} elseif (is_string($valeur)) {
// {nom=coucou}
$s->texte .= "=$valeur";
$res = array($s);
} elseif (is_array($valeur)) {
// {nom=#BALISE}
$s->texte .= '='; // /!\ sans cette toute petite chose, ça ne fait pas d'egalite :)
$res = array_merge(array($s), $valeur);
}
return $res;
}
/**
* Crée et ajoute un argument à une balise
*
* @uses Pile::creer_argument_balise()
* @uses Pile::ajouter_argument_balise()
*
* @param Champ $p
* @param string $nom
* Nom de l'argument
* @param string|object $valeur
* Valeur de l'argument. Peut être une chaîne de caractère ou un autre élément d'AST
* @return Champ
**/
static function creer_et_ajouter_argument_balise($p, $nom, $valeur = null) {
$new = Pile::creer_argument_balise($nom, $valeur);
return Pile::ajouter_argument_balise($new, $p);
}
/**
* Crée l'AST d'une balise
*
* @example
* ```
* // Crée : #ENV*{titre}
* $titre = Pile::recuperer_argument_balise(1, $p); // $titre, 1er argument de la balise actuelle
* $env = Pile::creer_balise('ENV', array('param' => array($titre), 'etoile' => '*'));
* ```
*
* @param string $nom
* Nom de la balise
* @param array $opt
* Options (remplira les propriétés correspondantes de l'objet Champ)
* @return Champ
**/
static function creer_balise($nom, $opt = array()) {
include_spip('public/interfaces');
$b = new Champ;
$b->nom_champ = strtoupper($nom);
foreach ($opt as $o => $val) {
if (property_exists($b, $o)) {
if ($o == 'param') {
array_unshift($val, '');
$b->$o = array($val);
} else {
$b->$o = $val;
}
}
}
return $b;
}
}
/**
* Compile la balise `#SAISIE` qui retourne le code HTML de la saisie de formulaire indiquée.
*
* Cette balise incluera le squelette `saisies/_base.html` et lui-même `saisies/{type}.html`
*
* La balise `#SAISIE` est un raccourci pour une écriture plus compliquée de la balise `#INCLURE`.
* La balise calcule une série de paramètre récupérer et à transmettre à `#INCLURE`,
* en fonction des valeurs des 2 premiers paramètres transmis.
*
* Les autres arguments sont transmis tels quels à la balise `#INCLURE`.
*
* Ainsi `#SAISIE{input,nom,label=Nom,...}` exécutera l'équivalent de
* `#INCLURE{nom=nom,valeur=#ENV{nom},type_saisie=input,erreurs,fond=saisies/_base,label=Nom,...}`
*
* @syntaxe `#SAISIE{type,nom[,option=xx,...]}`
*
* @uses Pile::recuperer_et_supprimer_argument_balise()
* @uses Pile::creer_balise()
* @uses Pile::creer_et_ajouter_argument_balise()
* @see balise_INCLURE_dist()
*
* @param Champ $p
* @return Champ
*/
function balise_SAISIE_dist($p) {
// on recupere les parametres sans les traduire en code d'execution php
$type_saisie = Pile::recuperer_et_supprimer_argument_balise(1, $p); // $type
$titre = Pile::recuperer_et_supprimer_argument_balise(1, $p); // $titre
// creer #ENV*{$titre} (* pour les cas de tableau serialises par exemple, que l'on veut reutiliser)
$env_titre = Pile::creer_balise('ENV', array('param' => array($titre), 'etoile' => '*')); // #ENV*{titre}
// on modifie $p pour ajouter des arguments
// {nom=$titre, valeur=#ENV{$titre}, erreurs, type_saisie=$type, fond=saisies/_base}
$p = Pile::creer_et_ajouter_argument_balise($p, 'nom', $titre);
$p = Pile::creer_et_ajouter_argument_balise($p, 'valeur', $env_titre);
$p = Pile::creer_et_ajouter_argument_balise($p, 'type_saisie', $type_saisie);
$p = Pile::creer_et_ajouter_argument_balise($p, 'erreurs');
$p = Pile::creer_et_ajouter_argument_balise($p, 'fond', 'saisies/_base');
// on appelle la balise #INCLURE
// avec les arguments ajoutes
if (function_exists('balise_INCLURE')) {
return balise_INCLURE($p);
} else {
return balise_INCLURE_dist($p);
}
}

52
shelves/master/balise/voir_saisie.php

@ -0,0 +1,52 @@
<?php
/**
* Déclaration de la balise `#VOIR_SAISIE`
*
* @package SPIP\Saisies\Balises
**/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Compile la balise `#VOIR_SAISIE` qui retourne le code HTML de la vue d'une saisie indiquée
*
* Cette balise incluera le squelette `saisies-vues/_base.html` et lui-même `saisies-vues/{type}.html`
*
* @syntaxe `#VOIR_SAISIE{type,nom[,option=valeur,...]}`
* @uses Pile::recuperer_et_supprimer_argument_balise()
* @uses Pile::creer_et_ajouter_argument_balise()
* @uses Pile::creer_balise()
* @see balise_INCLURE_dist()
*
* @param Champ $p
* @return Champ
*/
function balise_VOIR_SAISIE_dist($p) {
// on recupere les parametres sans les traduire en code d'execution php
$type_saisie = Pile::recuperer_et_supprimer_argument_balise(1, $p);
$nom = Pile::recuperer_et_supprimer_argument_balise(1, $p);
// creer #ENV*{$titre} (* pour les cas de tableau serialises par exemple, que l'on veut reutiliser)
$env_nom = Pile::creer_balise('ENV', array('param' => array($nom), 'etoile' => '*')); // #ENV*{nom}
// on modifie $p pour ajouter des arguments
// {nom=$nom, valeur=#ENV{$nom}, type_saisie=$type, fond=saisies/_base}
$p = Pile::creer_et_ajouter_argument_balise($p, 'nom', $nom);
$p = Pile::creer_et_ajouter_argument_balise($p, 'valeur', $env_nom);
$p = Pile::creer_et_ajouter_argument_balise($p, 'type_saisie', $type_saisie);
$p = Pile::creer_et_ajouter_argument_balise($p, 'fond', 'saisies-vues/_base');
// on appelle la balise #INCLURE
// avec les arguments ajoutes
if (function_exists('balise_INCLURE')) {
return balise_INCLURE($p);
} else {
return balise_INCLURE_dist($p);
}
}

57
shelves/master/balise/voir_saisies.php

@ -0,0 +1,57 @@
<?php
/**
* Déclaration de la balise `#VOIR_SAISIES`
*
* @package SPIP\Saisies\Balises
**/
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Compile la balise `#VOIR_SAISIES` qui retourne le code HTML des vues de formulaire,
* à partir du tableau des saisies transmises
*
* La balise accepte 2 paramètre :
* - une liste de descriptions de saisies
* dont on veut générer le HTML affichant les vues du formulaires
* - un liste des valeurs
* Cette balise est un raccourcis :
* - `#VOIR_SAISIES{#TABLEAU_DE_SAISIES}` est équivalent à
* - `#INCLURE{fond=inclure/voir_saisies,env,saisies=#TABLEAU_DE_SAISIES,valeurs=#TABLEAU_DE_VALEURS}`
*
* @syntaxe `#VOIR_SAISIES{#TABLEAU_DE_SAISIES}`
* @uses Pile::recuperer_et_supprimer_argument_balise()
* @uses Pile::creer_et_ajouter_argument_balise()
* @see balise_INCLURE_dist()
*
* @param Champ $p
* Pile au niveau de la balise
* @return Champ
* Pile complété du code à générer
**/
function balise_VOIR_SAISIES_dist($p) {
// On recupere les arguments : les tableaux decrivant ce qu'on veut generer + les reponses
$saisies = Pile::recuperer_et_supprimer_argument_balise(1, $p);
$valeurs = Pile::recuperer_et_supprimer_argument_balise(1, $p);
// On ajoute le squelette a inclure dans les parametres
$p = Pile::creer_et_ajouter_argument_balise($p, 'fond', 'inclure/voir_saisies');
// On ajoute l'environnement
$p = Pile::creer_et_ajouter_argument_balise($p, 'env');
// On ajoute les tableaux recuperes
$p = Pile::creer_et_ajouter_argument_balise($p, 'saisies', $saisies);
$p = Pile::creer_et_ajouter_argument_balise($p, 'valeurs', $valeurs);
// On redirige vers la balise INCLURE
if (function_exists('balise_INCLURE')) {
return balise_INCLURE($p);
} else {
return balise_INCLURE_dist($p);
}
}

126
shelves/master/css/formulaires_constructeur.css

@ -0,0 +1,126 @@
.formulaire_spip .formulaire_spip{
border:none;
background:transparent;
}
#deplacable .ui-state-highlight { height: 5em; line-height: 1.2em; }
#deplacable .ui-sortable {min-height:3em;}
.formulaire_construire_formulaire .actions_formulaire{
margin:0;
padding:1em;
text-align:center;
border:0;
}
.formulaire_construire_formulaire .actions_formulaire img{
vertical-align:middle;
}
.formulaire_construire_formulaire .en_configuration{
border:5px solid #999;
border-radius:5px;
margin:.5em;
}
.formulaire_construire_formulaire .fieldset.configurable>fieldset>.editer-groupe {margin-left:30px;}
.formulaire_construire_formulaire .formulaire_configurer{
border-top:3px dashed #999;
margin: 1em -8px 0 -138px;
padding: 1em .5em .5em .5em;
background:white;
}
.formulaire_construire_formulaire .fieldset > .formulaire_configurer{
margin: 1em -8px 0;
}
.formulaire_construire_formulaire .formulaire_configurer .formulaire_configurer-onglets {
overflow:auto;
}
.formulaire_construire_formulaire .formulaire_configurer .formulaire_configurer-onglets li{
float:left;
width:auto;
clear:none;
padding:0;
background:#eee;
border:1px solid #ddd;
margin-right:1px;
-moz-border-radius:5px 5px 0 0;
-webkit-border-radius:5px 5px 0 0;
-o-border-radius:5px 5px 0 0;
border-radius:5px 5px 0 0;
}
.formulaire_construire_formulaire .formulaire_configurer .formulaire_configurer-onglets li.actif{
background:white;
border-bottom:1px solid white;
}
.formulaire_construire_formulaire .formulaire_configurer .formulaire_configurer-onglets li.erreur a{
color:#CC3300;
}
.formulaire_construire_formulaire .formulaire_configurer .formulaire_configurer-onglets li a{
display:block;
padding:.5em;
}
.formulaire_construire_formulaire .formulaire_configurer .boutons { margin-bottom: -20px; }
.formulaire_construire_formulaire .editer.obligatoire .formulaire_configurer label {
color: #666;
font-weight: normal;
}
.formulaire_construire_formulaire .editer.obligatoire .formulaire_configurer .obligatoire label {
color: black;
font-weight: bold;
}
.formulaire_configurer-contenus > .fieldset > fieldset:first-child {border-top:0;}
.formulaire_configurer-contenus > .fieldset > fieldset {padding: 0}
.formulaire_construire_formulaire .editer-groupe>.configurable {padding-top:30px; position:relative;}
.formulaire_construire_formulaire .editer.saisie_explication > .explication { position:initial; }
.formulaire_construire_formulaire .editer.pleine_largeur .formulaire_configurer { margin-left: 0px; }
.formulaire_construire_formulaire li.editer.pleine_largeur .formulaire_configurer > .formulaire_configurer-contenus { margin-left: -138px; } /*uniquement pour Spip < 3.1, d'où le li */
.formulaire_construire_formulaire .formulaire_configurer .fieldset {padding-top:0px;}
.formulaire_construire_formulaire .formulaire_configurer fieldset fieldset>.editer-groupe>.editer:first-child {padding-top:0px;}
/* SPIP 3.0 compat avec li.selecteur_item */
.formulaire_construire_formulaire ul.editer-groupe > li.selecteur_item { background:transparent; padding-left:140px; }
.formulaire_construire_formulaire ul.editer-groupe > li.selecteur_item label { margin-left:-130px; }
.formulaire_construire_formulaire ul.editer-groupe > li.selecteur_item .choix label { margin-left:5px; }
.formulaire_construire_formulaire .editer.hover {background-color:transparent;}
.formulaire_construire_formulaire .actions{
position:absolute;
right:5px;
top:5px;
}
.formulaire_construire_formulaire .actions button{
cursor:pointer;
background:none;
border:none;
opacity:0.7;
}
.formulaire_construire_formulaire .actions button:hover{
opacity:1;
}
.formulaire_construire_formulaire .actions .move {
cursor:move;
}
.formulaire_construire_formulaire .ajouter_saisie{
width:45%;
margin:5px;
padding:0.5em 8px 0.5em 36px;
font-size:1em;
text-align:left;
color:black;
cursor:pointer;
background:white url() 8px center no-repeat;
border:1px solid #ccc;
}
.formulaire_construire_formulaire .ajouter_saisie img{
vertical-align:middle;
}

51
shelves/master/demo/configurer_saisie.html

@ -0,0 +1,51 @@
<html>
<head>
<title>Test de configuration de saisie</title>
[<link rel="stylesheet" href="(#CHEMIN{spip_formulaires.css})" type="text/css" media="all" title="formulaires" charset="utf-8" />]
<style type="text/css">
.formulaire_spip{
width:40%;
border:1px solid black;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
}
.formulaire_spip ul li{
padding:0.5em;
}
.formulaire_spip li.fieldset{
padding:0;
}
.formulaire_spip li.obligatoire{
background:#ffcfcf;
}
.formulaire_spip .fieldset .legend{
margin:0;
font-style:italic;
}
</style>
</head>
<body>
<h1>Test pour générer le formulaire de configuration d'une saisie</h1>
<h2>Par defaut, sans configuration du nom du champ</h2>
<form class="formulaire_spip" action="#SELF" method="post">
<ul>
#CONFIGURER_SAISIE{#ENV{saisie, input}}
<li class="boutons">
<input type="submit" class="submit" />
</li>
</ul>
</form>
<h2>En forçant la configuration du nom</h2>
<form class="formulaire_spip" action="#SELF" method="post">
<ul>
#CONFIGURER_SAISIE{#ENV{saisie, input}, avec_nom=oui}
<li class="boutons">
<input type="submit" class="submit" />
</li>
</ul>
</form>
</body>
</html>

106
shelves/master/demo/formulaire-afficher_si_test.yaml

@ -0,0 +1,106 @@
id_formulaire: '41'
identifiant: afficher_si_test
titre: afficher_si_test
descriptif: 'Ce formulaire donne des exemples d''utilisation d''afficher_si, pour faire des tests en cas de modif du code. '
css: ''
message_retour: ''
saisies:
-
options: { label: 'La saisie qui fait basculer les autres', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", obligatoire: on, nom: radio_1 }
identifiant: '@5cc85dbf55e2b'
verifier: { }
saisie: radio
-
options: { label: Date, heure_pas: '30', afficher_si: '@radio_1@=="choix1"', obligatoire: on, nom: date_2 }
verifier: { type: date, options: { normaliser: datetime } }
identifiant: '@5cc85f44233f5'
saisie: date
-
options: { label: 'Date (copie)', heure_pas: '30', afficher_si: '@radio_1@=="choix1"', nom: date_3 }
verifier: { type: date, options: { normaliser: datetime } }
identifiant: '@5cc8602f80ab6'
saisie: date
-
options: { label: 'Cases à cocher', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", choix_alternatif_label: 'Autre choix', afficher_si: '@radio_1@=="choix1"', obligatoire: on, nom: checkbox_2 }
identifiant: '@5cc85f44233f7'
verifier: { }
saisie: checkbox
-
options: { label: 'Cases à cocher (copie)', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", choix_alternatif_label: 'Autre choix', afficher_si: '@radio_1@=="choix1"', nom: checkbox_3 }
identifiant: '@5cc86038d0079'
verifier: { }
saisie: checkbox
-
options: { label: 'Case unique', label_case: 'Case unique', valeur_oui: on, afficher_si: '@radio_1@=="choix1"', obligatoire: on, nom: case_2 }
identifiant: '@5cc85f44233f9'
verifier: { }
saisie: case
-
options: { label: 'Case unique (copie)', label_case: 'Case unique', valeur_oui: on, afficher_si: '@radio_1@=="choix1"', nom: case_3 }
identifiant: '@5cc860403d408'
verifier: { }
saisie: case
-
options: { label: 'Bloc de texte', afficher_si: '@radio_1@=="choix1"', rows: '5', cols: '40', obligatoire: on, nom: textarea_2 }
identifiant: '@5cc85f44233fa'
verifier: { }
saisie: textarea
-
options: { label: 'Bloc de texte (copie)', afficher_si: '@radio_1@=="choix1"', rows: '5', cols: '40', nom: textarea_3 }
identifiant: '@5cc860477aa9b'
verifier: { }
saisie: textarea
-
options: { label: 'Boutons radios', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", afficher_si: '@radio_1@=="choix1"', obligatoire: on, nom: radio_3 }
identifiant: '@5cc85f44233fc'
verifier: { }
saisie: radio
-
options: { label: 'Boutons radios (copie)', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", afficher_si: '@radio_1@=="choix1"', nom: radio_4 }
identifiant: '@5cc8605aa7cf2'
verifier: { }
saisie: radio
-
options: { label: 'Ligne de texte', type: text, afficher_si: '@radio_1@=="choix1"', size: '40', autocomplete: defaut, obligatoire: on, nom: input_2 }
identifiant: '@5cc85f44233fd'
verifier: { }
saisie: input
-
options: { label: 'Ligne de texte (copie)', type: text, afficher_si: '@radio_1@=="choix1"', size: '40', autocomplete: defaut, nom: input_3 }
identifiant: '@5cc86061d2285'
verifier: { }
saisie: input
-
options: { label: 'Groupe de champs', explication: 'Maintenant on test les input qui sont dans des champs', afficher_si: '@radio_1@=="choix1"', nom: fieldset_1 }
identifiant: '@5cc85e4c9482f'
verifier: { }
saisie: fieldset
saisies: [{ options: { label: Date, heure_pas: '30', obligatoire: on, nom: date_1 }, verifier: { type: date, options: { normaliser: datetime } }, identifiant: '@5cc85e34de92f', saisie: date }, { options: { label: 'Cases à cocher', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", choix_alternatif_label: 'Autre choix', obligatoire: on, nom: checkbox_1 }, identifiant: '@5cc85e451728f', verifier: { }, saisie: checkbox }, { options: { label: 'Case unique', label_case: 'Case unique', valeur_oui: on, afficher_si: '@radio_1@=="choix1"', obligatoire: on, nom: case_1 }, identifiant: '@5cc85e4697f41', verifier: { }, saisie: case }, { options: { label: 'Bloc de texte', rows: '5', cols: '40', obligatoire: on, nom: textarea_1 }, identifiant: '@5cc85f11bbfb3', verifier: { }, saisie: textarea }, { options: { label: 'Boutons radios', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", obligatoire: on, nom: radio_2 }, identifiant: '@5cc85f37f1a79', verifier: { }, saisie: radio }, { options: { label: 'Ligne de texte', type: text, afficher_si: '@radio_1@=="choix1"', size: '40', autocomplete: defaut, obligatoire: on, nom: input_1 }, identifiant: '@5cc85e42775e3', verifier: { }, saisie: input }]
-
options: { label: 'Groupe de champs (copie)', explication: 'Maintenant on test les input qui sont dans des champs', afficher_si: '@radio_1@=="choix1"', nom: fieldset_2 }
identifiant: '@5cc8606c00a44'
verifier: { }
saisie: fieldset
saisies: [{ options: { label: Date, heure_pas: '30', nom: date_4 }, verifier: { type: date, options: { normaliser: datetime } }, identifiant: '@5cc8606c00a49', saisie: date }, { options: { label: 'Cases à cocher', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", choix_alternatif_label: 'Autre choix', nom: checkbox_4 }, identifiant: '@5cc8606c00a4a', verifier: { }, saisie: checkbox }, { options: { label: 'Case unique', label_case: 'Case unique', valeur_oui: on, afficher_si: '@radio_1@=="choix1"', nom: case_4 }, identifiant: '@5cc8606c00a4c', verifier: { }, saisie: case }, { options: { label: 'Bloc de texte', rows: '5', cols: '40', nom: textarea_4 }, identifiant: '@5cc8606c00a4d', verifier: { }, saisie: textarea }, { options: { label: 'Boutons radios', datas: "choix1|Un\r\nchoix2|Deux\r\nchoix3|Trois", nom: radio_5 }, identifiant: '@5cc8606c00a4e', verifier: { }, saisie: radio }, { options: { label: 'Ligne de texte', type: text, afficher_si: '@radio_1@=="choix1"', size: '40', autocomplete: defaut, nom: input_4 }, identifiant: '@5cc8606c00a50', verifier: { }, saisie: input }]
traitements:
enregistrement:
moderation: posteriori
multiple: on
modifiable: ''
effacement: ''
effacement_delai: ''
identification: cookie
variable_php: ''
unicite: ''
message_erreur_unicite: ''
anonymiser: ''
ip: ''
invalider: ''
resume_reponse: ''
analyse_exclure_champs: ''
public: non
statut: prop
date_creation: '2019-04-30 16:37:09'
maj: '2019-04-30 16:51:51'
apres: formulaire
url_redirect: ''

152
shelves/master/demo/generer_saisies.html

@ -0,0 +1,152 @@
<html>
<head>
<title>Test de génération de saisies</title>
[<link rel="stylesheet" href="(#CHEMIN{spip_formulaires.css})" type="text/css" media="all" title="formulaires" charset="utf-8" />]
<style type="text/css">
.formulaire_spip{
width:40%;
border:1px solid black;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
}
.formulaire_spip ul li{
padding:0.5em;
}
.formulaire_spip li.fieldset{
padding:0;
}
.formulaire_spip li.obligatoire{
background:#ffcfcf;
}
.formulaire_spip .fieldset .legend{
margin:0;
font-style:italic;
}
</style>
</head>
<body>
<h1>Test pour générer des saisies à partir d'une description</h1>
<h2>Génération d'une seule saisie</h2>
#SET{champ,
#ARRAY{
saisie, input,
options, #ARRAY{
nom, test,
label, Une sorte de titre,
explication, Un sorte d'explication,
obligatoire, oui
}
}
}
<form class="formulaire_spip" action="#SELF" method="post">
<ul>
[(#GET{champ}|saisies_generer_html{#ENV**|unserialize})]
<li class="boutons">
<input type="submit" class="submit" />
</li>
</ul>
</form>
<h2>Génération complète du contenu (l'intérieur) d'un formulaire</h2>
#SET{saisies,
#ARRAY{
0,#ARRAY{
saisie, destinataires,
options, #ARRAY{
nom, destinataires,
label, Destinataires,
choix_destinataires, #ARRAY{0,1,1,2},
type_choix, plusieurs,
obligatoire, oui
}
},
1,#ARRAY{
saisie, input,
options, #ARRAY{
nom, prenom,
label, Prénom,
}
},
2,#ARRAY{
saisie, input,
options, #ARRAY{
nom, nom,
label, Nom,
obligatoire, oui
}
},
3,#ARRAY{
saisie, input,
options, #ARRAY{
nom, courriel,
label, Courriel,
obligatoire, oui
},
verifier, #ARRAY{
type, email
}
},
4,#ARRAY{
saisie, case,
options, #ARRAY{
nom, case,
label, Une sorte de case à cocher,
label_case, Check la vibes
}
},
5,#ARRAY{
saisie, fieldset,
options, #ARRAY{
nom, adresse,
label, Adresse
},
saisies, #ARRAY{
1,#ARRAY{
saisie, textarea,
options, #ARRAY{
nom, voie,
label, Voie,
obligatoire, non,
}
},
2,#ARRAY{
saisie, input,
options, #ARRAY{
nom, code_postal,
label, Code postal,
obligatoire, oui
}
},
3,#ARRAY{
saisie, input,
options, #ARRAY{
nom, ville,
label, Ville,
obligatoire, oui
}
}
}
},
6,#ARRAY{
saisie, oui_non,
options, #ARRAY{
nom, peutetre,
label, Tu veux ou tu veux pas ?,
obligatoire, oui,
info_obligatoire, " / obligatoire"
}
},
}
}
<form class="formulaire_spip" action="#SELF" method="post">
<ul>
#GENERER_SAISIES{#GET{saisies}}
<li class="boutons">
<input type="submit" class="submit" />
</li>
</ul>
</form>
</body>
</html>

17
shelves/master/demo/page-saisies_cvt.html

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR">
<head>
<title>Demo Saisies CVT</title>
<INCLURE{fond=inclure/head} />
</head>
<body>
<div class="page">
<h1>CVT automatique avec Saisies</h1>
<p>Démonstration d'un formulaire CVT généré uniquement à partir d'une déclaration de Saisies</p>
<div class="ajax">
#FORMULAIRE_SAISIES_CVT
</div>
</div>
</body>
</html>

11
shelves/master/demo/saisie.html

@ -0,0 +1,11 @@
Version PHP : <?php echo phpversion(); ?>
<h1>Input</h1>
[(#SAISIE{input,titre})]
<h1>Textarea</h1>
[(#SAISIE{textarea,texte})]
<h1>Input obligatoire et label</h1>
[(#SAISIE{input,titre,obligatoire=oui,label=Un vrai titre})]

10
shelves/master/demo/voir_saisie.html

@ -0,0 +1,10 @@
<h1>Input et label</h1>
[(#VOIR_SAISIE{input,titre,label=Un vrai titre,valeur=TRUC})]
<h1>Textarea</h1>
[(#VOIR_SAISIE{textarea,texte,valeur=Un super long texte<br/>sur plusieurs ligne})]
<h1>Destinataires</h1>
[(#VOIR_SAISIE{destinataires,destinataires, label=Destinataires,valeur=#ARRAY{0,1,1,2}})]

147
shelves/master/demo/voir_saisies.html

@ -0,0 +1,147 @@
<html>
<head>
<title>Test de génération des vues de saisies</title>
[<link rel="stylesheet" href="(#CHEMIN{spip_formulaires.css})" type="text/css" media="all" title="formulaires" charset="utf-8" />]
<style type="text/css">
.formulaire_spip{
width:40%;
border:1px solid black;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
}
.formulaire_spip ul li{
padding:0.5em;
}
.formulaire_spip li.fieldset{
padding:0;
}
.formulaire_spip li.obligatoire{
background:#ffcfcf;
}
.formulaire_spip .fieldset .legend{
margin:0;
font-style:italic;
}
</style>
</head>
<body>
<h1>Générer des vues de saisie</h1>
#SET{saisies,
#ARRAY{
0,#ARRAY{
saisie, destinataires,
options, #ARRAY{
nom, destinataires,
label, Destinataires,
choix_destinataires, #ARRAY{0,1,1,2},
type_choix, plusieurs,
obligatoire, oui
}
},
1,#ARRAY{
saisie, input,
options, #ARRAY{
nom, prenom,
label, Prénom,
}
},
2,#ARRAY{
saisie, input,
options, #ARRAY{
nom, nom,
label, Nom,
obligatoire, oui
}
},
3,#ARRAY{
saisie, input,
options, #ARRAY{
nom, courriel,
label, Courriel,
obligatoire, oui
},
verifier, #ARRAY{
type, email
}
},
4,#ARRAY{
saisie, case,
options, #ARRAY{
nom, case,
label, Une sorte de case à cocher,
label_case, Check la vibes
}
},
5,#ARRAY{
saisie, fieldset,
options, #ARRAY{
nom, adresse,
label, Adresse
},
saisies, #ARRAY{
1,#ARRAY{
saisie, textarea,
options, #ARRAY{
nom, voie,
label, Voie,
obligatoire, non,
}
},
2,#ARRAY{
saisie, input,
options, #ARRAY{
nom, code_postal,
label, Code postal,
obligatoire, oui
}
},
3,#ARRAY{
saisie, input,
options, #ARRAY{
nom, ville,
label, Ville,
obligatoire, oui
}
}
}
},
6,#ARRAY{
saisie, oui_non,
options, #ARRAY{
nom, peutetre,
label, Tu veux ou tu veux pas ?,
obligatoire, oui,
info_obligatoire, " / obligatoire"
}
},
}
}
<h2>Formulaire auquel on doit répondre</h2>
<div class="formulaire_spip">
<ul>
#GENERER_SAISIES{#GET{saisies}}
</ul>
</div>
#SET{valeurs,
#ARRAY{
case, on,
peutetre, '',
prenom, Jean-Paul,
code_postal, 22222,
nom, Fitousi,
ville, Deuville,
courriel, robert@menard.com,
destinataires, #ARRAY{1,1},
voie, 2 rue du Deux,
}
}
<h2>Réponse à ce formulaire</h2>
#VOIR_SAISIES{#GET{saisies}, #GET{valeurs}}
</body>
</html>

264
shelves/master/formulaires/construire_formulaire.html

@ -0,0 +1,264 @@
<div class="formulaire_spip formulaire_editer formulaire_#ENV{form}[ (#ENV{formulaire_modifie}|oui) modifie]">
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
<p id="message_attention" class="message_reinitialiser reponse_formulaire reponse_formulaire_ok">#ENV*{_message_attention}</p>
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
<BOUCLE_editable(CONDITION){si #ENV{editable}|oui}>
<form method='post' action='#ENV{action}' enctype='multipart/form-data'><div>
[(#REM) declarer les hidden qui declencheront le service du formulaire
parametre : url d'action ]
#ACTION_FORMULAIRE{#ENV{action}}
<input type="submit" class="submit noscroll invisible" name="enregistrer" value="<:bouton_enregistrer:>" />
[(#ENV{_activer_options_globales}|oui)
[(#ENV{erreurs/configurer_globales}|non)
<div class="actions">
<button type="submit" class="submit" name="configurer_globales" value="oui">
<:saisies:construire_configurer_globales_label:>
</button>
</div>
]
[(#ENV{erreurs/configurer_globales}|oui)
<[(#DIV|sinon{ul})] class="editer-groupe en_configuration">
#GENERER_SAISIES{#ENV{erreurs/configurer_globales}}
<[(#DIV|sinon{li})] class="boutons">
<input type="hidden" name="enregistrer_globales" value="oui" />
<button type="submit" class="submit link noscroll" name="enregistrer_globales" value=""><:bouton_annuler:></button>
<input type="submit" class="submit noscroll" name="enregistrer" value="<:bouton_valider:>" />
</[(#DIV|sinon{li})]>
</[(#DIV|sinon{ul})]>
]
]
<[(#DIV|sinon{ul})] class="editer-groupe" id="deplacable">
<[(#DIV|sinon{li})] id="reinitialiser" class="actions_formulaire">
<button type="submit" class="submit" name="reinitialiser" value="oui" onclick="return confirm('<:saisies:construire_reinitialiser_confirmer:>')">
<img src="#CHEMIN{images/formulaire-reinitialiser-24.png}" alt="" />
<:saisies:construire_reinitialiser:>
</button>
</[(#DIV|sinon{li})]>
[(#REM)<!-- les choix de saisies -->]
<BOUCLE_contenu(DATA){source tableau, #ENV{_contenu}}>
[(#VAL{saisie}|array_key_exists{#VALEUR}|oui)
[(#VALEUR**|construire_formulaire_generer_saisie_configurable{#ENV**|unserialize})]
]
</BOUCLE_contenu>
<[(#DIV|sinon{li})] class="aucun"><em class="attention"><:saisies:construire_aucun_champs:></em></[(#DIV|sinon{li})]>
<//B_contenu>
<B_saisies_disponibles>
<[(#DIV|sinon{li})] class="editer haut saisies_disponibles" id="attrapable">
<label><:saisies:construire_ajouter_champ:></label>
<BOUCLE_saisies_disponibles(DATA){source tableau, #ENV{_saisies_disponibles}}{par titre}>
<button type="submit" name="ajouter_saisie" value="#CLE" class="submit noscroll ajouter_saisie"[ title="(#DESCRIPTION)"] [style="background-image:url((#ICONE|sinon{#CHEMIN{images/formulaire-saisie-defaut.png}}))"]>
<span>#TITRE</span>
</button>
</BOUCLE_saisies_disponibles>
</[(#DIV|sinon{li})]>
</B_saisies_disponibles>
<B_saisies_groupes_disponibles>
<[(#DIV|sinon{li})] class="editer haut saisies_groupes_disponibles" id="attrapable_bis">
<label><:saisies:construire_ajouter_groupe:></label>
<BOUCLE_saisies_groupes_disponibles(DATA){source tableau, #ENV{_saisies_groupes_disponibles}}{par titre}>
<button type="submit" name="ajouter_groupe_saisie" value="#CLE" class="submit noscroll ajouter_saisie"[ title="(#DESCRIPTION)"] [style="background-image:url((#ICONE|sinon{#CHEMIN{images/formulaire-saisie-defaut.png}}))"]>
<span>#TITRE</span>
</button>
</BOUCLE_saisies_groupes_disponibles>
</[(#DIV|sinon{li})]>
</B_saisies_groupes_disponibles>
</[(#DIV|sinon{ul})]>
[(#REM) ajouter les saisies supplementaires : extra et autre, a cet endroit ]
<!--extra-->
<span class='image_loading'></span>
</div></form>
<style>
.message_reinitialiser,#reinitialiser {display: none}
.modifie .message_reinitialiser,.modifie #reinitialiser {display: block}
</style>
<script type="text/javascript">
(function($){
function formulaire_configurer_onglets() {
var $formulaire_configurer = $('.formulaire_configurer');
var $onglets = $('<ul class="formulaire_configurer-onglets"></ul>');
var $contenus = $formulaire_configurer.find('> .editer-groupe > .fieldset');
// On ajoute le conteneur des onglets
$formulaire_configurer.prepend($onglets);
// On parcourt les contenus pour générer les onglets
$contenus.each(function(i){
// On ajoute un identifiant et une classe
$(this)
.attr('id', 'formulaire_configurer-contenu-'+i)
.addClass('formulaire_configurer-contenu');
// On récupère le titre (en le cachant au passage)
var titre = $(this).find('legend').eq(0).hide().text();
// On crée un onglet
var $onglet = $('<li><a href="#formulaire_configurer-contenu-'+i+'">'+titre+'</a></li>');
$onglet
.click(function(){
$contenus.hide();
$(
$(this)
.siblings()
.removeClass('actif')
.end()
.addClass('actif')
.find('a')
.attr('href')
).show();
return false;
});
// On active le premier onglet au démarrage
if (i == 0) {
$onglet.addClass('actif');
}
// S'il y a des erreurs dans cette partie du contenu, on met une classe "erreurs" à l'onglet aussi
if ($(this).find('.editer.erreur').length > 0) {
$onglet.addClass('erreur');
}
// On ajoute l'onglet
$onglets.append($onglet);
})
.hide()
.eq(0)
.show();
}
/* enlever les required */
$('.formulaire_#FORM .editer.obligatoire').find('input, textarea, select').each(function(){
if ($(this).prop('required')) {
$(this).prop('required', false);
}
});
$('.formulaire_#FORM .configurable')
.hover(
function(){
$(this)
.addClass('hover')
.find('> .actions')
.show()
.end()
.parents('li.configurable:not(.en_configuration)')
.mouseout();
},
function(){
if (!$(this).is('.en_configuration'))
$(this)
.removeClass('hover')
.find('> .actions')
.hide()
.end()
.parents('.configurable').eq('0')
.mouseover();
}
)
.filter(':not(.en_configuration)')
.find('> .actions')
.hide()
.end()
.end();
// On lance la création des onglets
formulaire_configurer_onglets();
// Gérer la liste des vérifications
$('.liste_verifications').each(function(){
var $options = $(this).siblings('.options_verifier').hide();
var $select = $(this).find('select');
$select
.change(function(){
var montrer = $(this).val() ? $(this).val() : 'soigfeg';
$options.hide().filter('.'+montrer).show();
})
.change();
});
// On déplie toujours les fieldsets plés par défaut
$('.fieldset.plie').each(function(){
$(this)
.removeClass('plie')
.find('> fieldset > .editer-groupe').show();
});
[(#ENV{erreurs}|non|et{#ENV{_jquery_ui_all}|ou{#ENV{_chemin_ui}}})
var saisies_sortable = function() {
$( "#deplacable, #deplacable .editer-groupe" ).sortable({
revert: true,
containment: '#deplacable',
connectWith: "#deplacable, #deplacable .editer-groupe",
placeholder: "ui-state-highlight",
handle: '>.actions .deplacer_saisie',
start: function(event, ui) {
$('.ui-state-highlight')
.css('height', ui.item.css('height'))
.css('height', '+=20px');
},
update: function(event, ui) {
id = ui.item.data('id');
ou = ui.item.next().data('id');
// avant le suivant
if (!ou) {
// sinon dans le parent
ou = ui.item.closest('.fieldset').data('id');
// Si jamais match lui-même, ca veut dire qu'on déplace un fieldest
if (ou == id) {
ou = ui.item.parents('.fieldset').first().data("id");
}
if (ou) {
ou = '\[' + ou + '\]';
}
}
url = "#URL_ECRIRE";
$.get(url, {
session: '#ENV{_identifiant_session}',
action: 'deplacer_saisie',
saisie: id,
ou: ou
}, function() {
//$('input.vide').submit();
$('.formulaire_#ENV{form}').addClass('modifie').trigger('modifsaisies');
});
}
});
}
if (!$.fn.sortable) {
[
$.getScript("(#ENV{_jquery_ui_all})", function(){
]
[(#ENV{_chemin_ui}|oui)
$.getScript("#CHEMIN{#ENV{_chemin_ui}core.js}", function(){
$.getScript("#CHEMIN{#ENV{_chemin_ui}widget.js}", function(){
$.getScript("#CHEMIN{#ENV{_chemin_ui}mouse.js}", function(){
$.getScript("#CHEMIN{#ENV{_chemin_ui}sortable.js}", function(){
]
if ($.fn.sortable) {
saisies_sortable();
}
});
[(#ENV{_chemin_ui}|oui)
});});});
]
} else {
saisies_sortable();
}
]
})(jQuery);
</script>
</BOUCLE_editable>
</div>

712
shelves/master/formulaires/construire_formulaire.php

@ -0,0 +1,712 @@
<?php
// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Formulaire permettant de construire un formulaire ! En agençant des champs
* Chargement.
* @param string $identifiant identifiant unique du formulaire
* @param array $formulaires_initial, formulaire initial (par exemple si on modifie un formulaire déjà construit)
* @param array $options tableau d'options
* - array options_globales : proposer des options globales pour le formulaire, liste de ces options
* - array saisies_exclues : liste des saisies à ne pas proposer (= à exclure du choix)
* - bool uniquement_sql : ne proposer que les saisies qui permettent de remplir un champ sql
* @return array $contexte
**/
function formulaires_construire_formulaire_charger($identifiant, $formulaire_initial = array(), $options = array()) {
include_spip('inc/saisies');
$contexte = array();
// On ajoute un préfixe devant l'identifiant, pour être sûr
$identifiant = 'constructeur_formulaire_'.$identifiant;
$contexte['_identifiant_session'] = $identifiant;
// On vérifie ce qui a été passé en paramètre
if (!is_array($formulaire_initial)) {
$formulaire_initial = array();
}
// On s'assure que toutes les saisies ont un identifiant (en cas de bug lors de la création, par ex.)
$formulaire_initial = saisies_identifier($formulaire_initial);
// Construire le md5 du paramètre $formulaire_initial, et trouver celui qu'on avait stocké
$md5_formulaire_initial = md5(serialize($formulaire_initial));
$md5_precedent_formulaire_initial = session_get($identifiant.'_md5_formulaire_initial');
// Si pas de session, on prend le formulaire initial comme formulaire actuel,
// ou bien si la session est trop trop veille, on prend le formulaire initial comme formulaire
if (
is_null($formulaire_actuel = session_get($identifiant))
or
($md5_precedent_formulaire_initial
and
$md5_formulaire_initial != $md5_precedent_formulaire_initial and $_SERVER['REQUEST_METHOD'] === 'GET')
) {
session_set($identifiant, $formulaire_initial);
session_set($identifiant.'_md5_formulaire_initial', $md5_formulaire_initial);
$formulaire_actuel = $formulaire_initial;
}
// Si le formulaire actuel est différent du formulaire initial on agite un drapeau pour le dire
if ($formulaire_actuel != $formulaire_initial) {
$contexte['formulaire_modifie'] = true;
}
$contexte['_message_attention'] = _T('saisies:construire_attention_modifie');
// On passe ça pour l'affichage
$contexte['_contenu'] = $formulaire_actuel;
// On passe ça pour la récup plus facile des champs
$contexte['_saisies_par_nom'] = saisies_lister_par_nom($formulaire_actuel);
// Pour déclarer les champs modifiables à CVT
foreach (array_keys($contexte['_saisies_par_nom']) as $nom) {
$contexte["saisie_modifiee_$nom"] = array();
}
// La liste des options globales qu'on peut configurer, si elles existent