Raccourcis : Contenu - rubriques - sous rubriques
EN FR

La version 1.1 du format décrit dans cette page est utilisable depuis Jelix 1.1.

Structure principale

Le document XML que vous écrivez dans un fichier jForms est composé d'une balise <form> comme racine.


<?xml version="1.0" encoding="utf-8"?>
<form xmlns="http://jelix.org/ns/forms/1.1">

</form>

Dans cette balise, vous indiquerez les balises correspondantes à chacun des contrôles (champs de saisies) composant le formulaire. Le traitement et l'affichage de ces contrôles se feront dans le même ordre que celui de leur apparition dans le document.

Notez que le namespace pour cette version du format est http://jelix.org/ns/forms/1.1.

Propriétés communes aux contrôles

Identifiant

Chaque contrôle doit avoir un identifiant (= un nom). Vous devez en indiquer un avec l'attribut ref. Cet identifiant correspond en fait à ce qu'on appelle une variable de formulaire et qui contiendra la valeur saisie.

Exemple:


  <input ref="nom">
  </input>

Note : quand vous voulez utiliser un formulaire avec un ou plusieurs DAO, il est judicieux d'utiliser les mêmes noms que les propriétés des DAO, afin de pouvoir utiliser les mécanismes de chargement et sauvegarde automatique de jForms avec les DAO.

Libellé

Tout champ de saisie doit contenir un libellé indiqué au moyen de la balise <label> :


  <input ref="nom">
    <label>Votre nom</label>
  </input>

On peut indiquer une locale plutôt qu'une chaine "en dur" :


  <input ref="nom">
    <label locale="mymodule~forms.input.name"/>
  </input>

Il est aussi possible d'indiquer un libellé alternatif quand la valeur du champs est vide (surtout utile quand il s'agit d'afficher uniquement les données d'un formulaire)


  <input ref="nom">
    <label>Votre nom</label>
    <emptyvaluelabel>Pas de nom<emptyvaluelabel>
  </input>

Saisie obligatoire

Pour rendre la saisie obligatoire sur un champ de saisie, il faut mettre l'attribut required avec la valeur true. Cet attribut n'est pas valable sur les éléments <submit>, <checkbox>, <group>, <choice>, <hidden> et <output>.

Lecture seule

Il est possible d'empêcher la modification d'un champ de saisie. Pour cela, il faut mettre l'attribut readonly avec la valeur true. Cet attribut n'est pas valable sur l'élément <submit> et <output>. Vous pouvez modifier cette propriété en PHP.

Messages informatifs

Un message d'aide (optionnel) peut être affiché en même temps que le contrôle de saisie, grâce à la balise <help> : vous y inscrivez soit le message d'aide, soit la locale (via l'attribut locale).


  <input ref="datenaissance" type="date">
    <label locale="mymodule~forms.input.naissance"/>
    <help>Indiquez votre date de naissance, en respectant le format aaaa-mm-jj</help>
  </input>

ou

  <input ref="datenaissance" type="date">
    <label locale="mymodule~forms.input.naissance"/>
    <help locale="mymodule~forms.input.naissance.help"/>
  </input>

Dans les formulaires en HTML, un point d'interrogation s'affichera à côté du champ de saisie et le message d'aide s'affichera lors d'un clic sur ce point d'interrogation. (Ce comportement peut être modifié en fournissant votre propre générateur).

Un autre type de message informatif peut être affiché sous forme de tooltip. Il faut pour cela utiliser la balise <hint>, qui s'utilise comme la balise <help>.

Messages d'erreurs

Quand le contenu du champ de saisie est invalide (il n'est pas du type attendu par exemple), ou que la saisie est manquante lorsqu'elle est requise (attribut required), jForms affiche des messages d'erreurs prédéfinis.

Cependant vous pouvez fournir vous-mêmes ces messages au moyen de la balise <alert>. Un attribut type permet de définir soit le message pour l'erreur d'invalidité, soit le message pour la saisie obligatoire. Et comme les balises précédentes, vous pouvez indiquer le message complet, ou indiquer une locale au moyen de l'attribut locale.


  <input ref="datenaissance" type="date">
    <label locale="mymodule~forms.input.naissance"/>
    <alert type="required" locale="mymodule~forms.input.naissance.error.required"/>
    <alert type="invalid">Le format de la date à respecter pour la saisie est aaaa-mm-jj</alert>
  </input>

Classe de contrôle

À chaque element, correspond une classe jFormsControl*. Il peut arriver que cette classe, qui se charge d'initialiser et vérifier les données, ne fasse pas exactement ce que l'on veut.

Il est possible alors d'écrire une classe héritant de jFormsControl, et d'indiquer son nom dans un attribut controlclass.

Champs de saisie

Saisie de texte simple

Pour afficher un simple champ de saisie, il faut utiliser la balise <input>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required. Vous pouvez indiquer aussi ces attributs supplémentaires : type, defaultvalue, size, minlength, maxlength et pattern.

defaultvalue permet d'indiquer une valeur par défaut qui sera affichée quand le formulaire est vide. Vous pouvez mettre la valeur "now" pour les champs de saisie de dates. La valeur par défaut sera alors la date de maintenant.

size permet d'indiquer la largeur de la boîte de saisie en nombre de caractères.

maxlength et minlength permet d'ajouter une contrainte sur la valeur saisie : la longueur minimale et maximale de la chaine de caractère saisie. Ces deux attributs ne sont utilisables que pour le type="string".

minvalue et maxvalue permet d'ajouter une contrainte sur la valeur saisie : la valeur minimale et maximale du nombre saisie. Ces deux attributs ne sont utilisables que pour type="integer" et type="decimal".

pattern: Il doit contenir une expression rationnelle compatible avec PHP et JS. Il n'est utilisable que pour type="string".

type permet d'indiquer le format de données que l'utilisateur doit respecter. Au moment de l'envoi du formulaire, il y aura une vérification en javascript du contenu saisi, mais aussi une vérification côté serveur (au cas où le javascript est désactivé notamment) lors de l'appel à la méthode check() sur l'objet formulaire.

Voici les valeurs possibles pour l'attribut type et ce que doit taper l'utilisateur :

  • "string" : chaîne contenant n'importe quel caractère. (c'est le type par défaut)
  • "boolean" : la valeur du champ doit être obligatoirement "true" ou "false"
  • "decimal" : un nombre avec ou sans virgule
  • "integer" : un nombre entier
  • "hexadecimal" : un nombre hexadecimal (chiffres de 0 à 9 et lettres de a à f)
  • "datetime", "date", "time" : une date et heure, une date ou une heure. Le format précis est respectivement "aaaa-mm-jj hh:mm:ss", "aaaa-mm-jj", "hh:mm:ss".
  • "localedatetime", "localedate", "localetime" : une date et heure, une date ou une heure, mais dans le format de la langue de l'utilisateur. Par exemple, pour un site en français, le format de la date devra être "jj/mm/aaaa", et pour un site en anglais "mm/jj/aaaa".
  • "url" : la chaîne doit être une URL valide
  • "email" : un email
  • "ipv4" : une adresse IP v4
  • "ipv6" : une adresse IP v6
  • "html" : du code HTML. Le contenu HTML sera "purifié" coté serveur, pour éviter les problèmes de sécurité comme CSS, XSS...

Un exemple de champ de saisie simple :


  <input ref="email" type="email">
     <label locale="monmodule~monform.email.label" />
     <hint>L'email doit être valide</hint>
  </input>

Un exemple de champ de saisie ave un pattern :


  <input ref="url" type="string" pattern="/^[a-z0-9\-]+$/">
      <label>Url</label>
  </input>

Saisie de texte multiligne

Pour permettre la saisie d'un texte de plusieurs lignes, il faut utiliser la balise <textarea>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly, required et type="html". Il y a plusieurs attributs spécifiques à cette balise : defaultvalue, rows, cols, minlength et maxlength.

defaultvalue permet d'indiquer une valeur à afficher automatiquement pour un nouveau formulaire, tandis que rows et cols permettent de fixer la taille du champs de saisie en hauteur et largeur (comme le textarea en HTML).

Un exemple :


  <textarea ref="message">
     <label locale="monmodule~monform.message.label" />
     <hint>Saisissez ici le message</hint>
  </textarea>

maxlength et minlength permettent d'ajouter une contrainte sur la valeur saisie : la longueur minimale et maximale de la chaine de caractères saisie.

Si vous voulez que l'utilisateur puisse saisir du HTML et qu'il y ait une vérification du contenu coté serveur pour éviter les problèmes de sécurité, mettez l'attribut type="html".

Saisie de texte en HTML wysiwyg

Pour utiliser un éditeur HTML wysiwyg dans votre formulaire, il faut utiliser la balise <htmleditor>.


  <htmleditor ref="description">
	<label>Description du produit</label>
  </htmleditor>

Par défaut, l'éditeur utilisé est CKEditor (pour le générateur "html" et "htmllight"). On peut spécifier une configuration spécifique pour l'éditeur ainsi que l'editeur, via l'attribut config, mais aussi une feuille de style pour la décoration de l'éditeur, via l'attribut skin.

Vous pouvez changer d'éditeur (tinymce, wymeditor...), en l'indiquant dans la configuration de l'editeur.

Pour savoir utiliser ces attributs et configurer un éditeur comme vous le souhaitez, voir la page sur htmleditor.

Éditeur de contenu wiki

Vous pouvez utiliser un textarea pour éditer du contenu wiki. Cependant il y a l'element <wikieditor> qui permet de specifier que c'est du contenu wiki, et les générateurs peuvent afficher une barre d'outils pour faciliter l'édition. Il utiliseront automatiquement WikiRenderer (jWiki) pour transformer le contenu en HTML et l'afficher.


  <wikieditor ref="description">
	<label>Description du produit</label>
  </wikieditor>

Vous pouvez indiquer une configuration pour la barre d'outil, avec l'attribut config. Pour en savoir plus, voir la page sur wikieditor.

Saisie de date (datepicker)

La balise <date> et <datetime> facilitent la saisie d'une date par rapport à un simple <input>.


  <date ref="naissance">
	<label>Date de naissance</label>
  </date>

L'attribut ref est obligatoire, et vous pouvez utiliser les attributs defaultvalue, readonly, et required, ainsi que les balises <label>, <hint>, <alert>, et <help>.

Il y aussi les attributs spécifiques mindate, maxdate et datepicker. Pour savoir comment utiliser datepicker, voir la page dediée.

Pour les attributs mindate et maxdate, vous pouvez utiliser soit une date absolue au format DB comme '2017-01-01', soit une chaine qui contient une valeur qui sera analysée par la fonction PHP strtotime. Cette dernière solution reste la plus pratique. Par exemple pour une date de naissance si l'on veut que des dates de naissance des personnes de 18 à 70 ans :


  <date ref="naissance" mindate="-70 years" maxdate="-18 years">
	<label>Date de naissance</label>
  </date>

On peut aussi faire la même chose si l'on veut une date de début au minimum égale à aujourd'hui et une date maximum à 2 mois 1 jour


  <date ref="date_debut" mindate="now" maxdate="+2 months 1 day">
	<label>Début de l'évènement</label>
  </date>

Saisie d'heure

Pour permettre la saisie d'une heure, utiliser <time>.

`

<time ref="meetingtime">
    <label>Meeting Time</label>
</time>

`

L'attribute seconds="true" permet de saisir les secondes.

Vous pouvez utiliser mintime et maxtime pour ajouter des contraintes sur l'heure saisie.

Mot de passe

Pour la saisie d'un mot de passe ou tout autre renseignement qui doit être caché lors de la saisie, vous utiliserez la balise <secret>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required.


  <secret ref="password">
     <label>Votre mot de passe</label>
     <hint>Indiquez le mot de passe que l'on vous a donné à l'inscription</hint>
  </secret>

Vous pouvez utiliser l'attribut size pour indiquer la largeur du champ de saisie.

Il est souvent utile de demander à l'utilisateur de saisir une deuxième fois un nouveau mot de passe, lors d'une inscription par exemple. jForms gère cela automatiquement. Il suffit d'indiquer la balise <confirm> dans la balise <secret>, et le formulaire HTML généré contiendra deux champs de saisie. La balise <confirm> doit contenir soit l'intitulé du libellé pour la confirmation, soit un attribut locale contenant le sélecteur de la locale pour le libellé de la confirmation.


  <secret ref="newpassword">
     <label>Mot de passe</label>
     <hint>Indiquez un nouveau mot de passe</hint>
     <confirm>Retapez ce mot de passe</confirm>
  </secret>

Cela génèrera en gros, pour un formulaire html :


   <label for="newpassword">Mot de passe</label>
        <input type="password" id="newpassword" name="newpassword" title="Indiquez un nouveau mot de passe"/>

   <label for="newpassword_confirm">Retapez ce mot de passe</label>
        <input type="password" id="newpassword_confirm" name="newpassword_confirm"/>

Case à cocher seule

Pour afficher une case à cocher, utiliser la balise <checkbox>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que l'attribut readonly et required.


  <checkbox ref="souvenir">
     <label>Se souvenir de moi</label>
     <help>Cochez cette case si vous voulez être identifié automatiquement la prochaine fois</help>
  </checkbox>

Par défaut, la valeur de la case à cocher, que vous récupèrerez une fois le contenu du formulaire reçu, vaudra 0 si la case n'a pas été cochée, ou 1 si elle l'a été.

Vous pouvez décider d'autres valeurs pour chacun de ces deux états. Il suffit d'indiquer les attributs valueoncheck et valueonuncheck (qui valent donc par défaut, respectivement 1 et 0). Exemple :


  <checkbox ref="souvenir" valueoncheck="O" valueonuncheck="N">
     <label>Se souvenir de moi</label>
     <help>Cochez cette case si vous voulez être identifier automatiquement la prochaine fois</help>
  </checkbox>

Notez que lorsque vous afficherez un formulaire pré-rempli, la case sera cochée ou non en fonction de la valeur initiale, selon que celle-ci corresponde à la valeur de valueoncheck ou de valueonuncheck.

Pour afficher la valeur d'une case à cocher lors de l'affichage des données seules d'un formulaire, il est souvent préférable d'afficher un libellé correspondant. Utilisez alors les elements <oncheckvalue> et <onuncheckvalue>.


  <checkbox ref="souvenir" valueoncheck="O" valueonuncheck="N">
     <label>Se souvenir de moi</label>
     <help>Cochez cette case si vous voulez être identifier automatiquement la prochaine fois</help>
     <oncheckvalue label="Oui" />
     <onuncheckvalue label="Non" />
  </checkbox>

<oncheckvalue> et <onuncheckvalue> supportent également l'attribut locale au lieu de label, ainsi que l'attribut value (à utiliser à la place de valueoncheck et valueonuncheck).

Liste de cases à cocher

On peut avoir à afficher une série de cases à cocher qui correspondent à des choix multiples, par exemple afficher une liste de choses à acheter, et l'utilisateur coche les articles qu'il veut acheter. Pour cela on utilisera la balise <checkboxes> (avec un S à la fin).

Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required.

Il vous faut aussi indiquer la liste des valeurs possibles et leurs libellés. Voir la section "sources de données" plus bas.

Exemple :


   <checkboxes ref="articles">
      <label>Sélectionnez les articles que vous voulez acheter :</label>
      <item value="54">sucre</item>
      <item value="27">steack</item>
      <item value="32">jus d'orange</item>
  </checkboxes>

Ceci affichera une série de trois cases à cocher, ayant pour intitulé "sucre", "steack" et "jus d'orange". Quand le formulaire sera envoyé au serveur, la valeur que vous recevrez pour la variable de formulaire "articles", sera un tableau PHP contenant les valeurs des cases qui ont été cochées. Par exemple, si l'utilisateur a coché "steack", coté serveur vous recevrez array(27). Si en plus "sucre" est coché, vous recevrez array(54, 27).

(voir la page sur la gestion du contenu d'un formulaire coté serveur).

Boutons radios

Les boutons radios vont toujours par groupe, d'au moins 2. Pour déclarer un groupe de boutons radio, vous utiliserez la balise <radiobuttons>.

Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required. Comme pour les autres contrôles de type liste, vous devez indiquer la liste des valeurs possibles et leurs libellés. Voir la section "sources de données" plus bas.

Exemple :


   <radiobuttons ref="couleur">
      <label>Couleur de votre voiture:</label>
      <item value="r">Rouge</item>
      <item value="b">Bleue</item>
      <item value="v">Verte</item>
      <item value="j">Jaune</item>
  </radiobuttons>

Ceci affichera une série de 4 boutons radio, et la valeur choisie sera stockée dans la variable de formulaire "couleur".

Liste déroulante

La balise <menulist> affiche une liste déroulante (<select size="1"> en HTML), et de par sa nature, un seul choix est possible. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required. Comme pour les autres contrôles de type liste, vous devez indiquer la liste des valeurs possibles et leurs libellés. Voir la section "sources de données" plus bas.

Exemple :


   <menulist ref="ville">
      <label>votre ville :</label>
      <item value="75000">Paris</item>
      <item value="37000">Tours</item>
      <item value="44000">Nantes</item>
      <item value="69000">Lyon</item>
  </menulist>

La variable de formulaire contiendra la valeur de l'item sélectionné.

Par défaut, si il n'y a pas l'attribut required="true", il n'est pas obligatoire de faire un choix dans la liste. Vous avez donc automatiquement un premier choix "vide" qui est pré-selectionné. Si vous voulez indiquer le libellé de ce choix vide, vous devez utiliser l'élement <emptyitem>.


   <menulist ref="ville">
      <label>votre ville :</label>
      <emptyitem>faites votre choix</emptyitem>
      <item value="75000">Paris</item>
      <item value="37000">Tours</item>
      <item value="44000">Nantes</item>
      <item value="69000">Lyon</item>
  </menulist>

Vous pouvez bien sûr utiliser une locale :


      <emptyitem locale="module~foo.bar"/>

Liste non déroulante

Les listes déroulantes, ou encore listbox (Équivalent de la balise <select> en HTML), sont déclarées au moyen de balise <listbox>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required. Comme pour les autres contrôles de type liste, vous devez indiquer la liste des valeurs possibles et leurs libellés. Voir la section "sources de données" plus bas.


   <listbox ref="rubrique">
      <label>Rubrique préférée :</label>
      <item value="1">Tutoriels</item>
      <item value="2">Manuels</item>
      <item value="3">Forums</item>
  </listbox>

Vous pouvez indiquer un attribut size qui permet d'indiquer le nombre d'items affichables en même temps (donc la hauteur de la liste). Par défaut, elle vaut 4.

Par défaut, un seul choix est possible. Cependant en ajoutant l'attribut multiple="true", l'utilisateur pourra sélectionner plusieurs éléments de la liste (dans une page HTML, il faut que l'utilisateur appuie sur la touche CTRL en même temps qu'il clique sur un item). Dans ce cas, dans la variable de formulaire "rubrique", au lieu d'avoir une simple valeur correspondant à l'item sélectionné, vous aurez un tableau PHP avec toutes les valeurs des items choisis.

Téléchargement de fichier

Pour permettre à l'utilisateur de télécharger un fichier vers le serveur, vous pouvez utiliser la balise <upload> (équivalent de <input type="file"> en HTML). Comme pour les autres contrôles, vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required.

Deux attributs supplémentaires sont à votre disposition, pour contrôler la nature et la taille des fichiers, qui sont respectivement mimetype (devant contenir un ou plusieurs type mime) et maxsize (taille en octets).


  <upload ref="photo" mimetype="image/jpeg;image/png" maxsize="20000">
    <label>Votre photo</label>
  </upload>

À la réception du fichier, jForms vérifie s'il correspond au type et à la taille indiqués, et l'on peut ensuite lui indiquer où stocker le fichier téléchargé. La variable de formulaire contiendra le nom du fichier.

Autres attributs supportés :

  • accept : valeur de l'attribut HTML accept pour la balise input.
  • capture : valeur de l'attribut HTML capture pour la balise input.

Téléchargement amélioré de fichier

Le téléchargement simple comme indiqué précédemment, manque de fonctionnalités sur les fichiers existants, quand le formulaire édite des données à modifier. Ainsi, il faut soit-même supprimer l'ancien fichier si un nouveau est téléchargé. De plus à l'affichage, il n'est pas possible de voir quel est l'ancien fichier, de le supprimer etc..

Une amélioration de <upload>, fournissant une gestion amélioré du fichier, est disponible avec l'element <upload2> depuis Jelix 1.7. Il a les mêmes attributs et elements fils que <upload>.

Mais le widget associé améliore l'affichage, en permettant de voir le nom du fichier pré-selectionné ou choisi, de remplacer le fichier, ou de le supprimer quand la saisie n'est pas obligatoire.

La classe du control en PHP offre une meilleur API pour manipuler les fichiers :



    /** le nom du fichier indiqué lors de l'initialisation du formulaire */
    public function getOriginalFile();

    /** le nom du fichier uploadé lors de la validation du formulaire */
    public function getNewFile();

    /** change le nom du nouveau fichier. Si il y a un fichier qui vient d'être uploadé, il est supprimé */
    public function setNewFile($fileName);

    /**
     * retourne un nom de fichier sous lequel le fichier peut être sauvegardé sans écraser de fichier existants
     *
     * le nom de base du fichier est le nom du fichier uploadé, ou alors le nom donnée dans le paramètre
     * $alternateName
     */
    public function getUniqueFileName($directoryPath, $alternateName = '');

    /**
     * Sauvegarde le fichier uploadé dans le répertoire indiqué, sous le nom original du fichier, ou
     * sous le nom indiqué dans $alternateName.
     *
     * Si il existe un fichier sous le nom indiqué, il sera écrasé. Si vous ne voulez pas d'écrasement,
     * utilisez getUniqueFileName pour avoir un nom à donner dans $alternateName
     */
    public function saveFile($directoryPath, $alternateName = '');

    /** efface le fichier */
    public function deleteFile($directoryPath);

Pour les images, il permet d'afficher une vignette de l'image sélectionnée, y compris quand le formulaire est affichée en mode "vue uniquement". Cependant, pour qu'une image présélectionnée s'affiche, il faut indiquer comment construire l'url, via des paramètres à donner au widget (via {ctrl_control} ou via l'option widgetAttributes donnée à {form*}.

  • soit à partir d'un sélecteur d'action. On indique le sélecteur dans uriAction et les paramètres dans uriActionParameters. Si l'un des paramètres doit contenir le nom du fichier de l'image, il faut indiquer le nom du paramètre dans uriActionFileParameter. La valeur existante du paramètre sera remplacée par le nom de l'image. Si elle contient %s, seul ce %s sera remplacée par le nom de l'image.
  • soit à partir d'une URL de base, auquel sera ajoutée le nom du fichier de l'image. On indique cette URL de base dans baseURI.

Pour les images, on peut aussi indiquer les attributs de widget imgMaxHeight et imgMaxWidth, qui indique la taille de l'image affichée. Cela ne modifie pas le fichier de l'image.

Exemple :


  <upload2 ref="photo" mimetype="image/jpeg;image/png" maxsize="20000">
    <label>Votre photo</label>
  </upload>

{form $form, 'module~action', array(), 'html', array(
      'widgetsAttributes'=> array(
          'photo' => array(
                'uriAction' => 'photomanager~edit:show',
                'uriActionParameters' => array('filename' => ''),
                'uriActionFileParameter' => 'filename'
                'imgMaxWidth' => 100,
                'imgMaxHeight' => 100
          ))
       )}

{form $form, 'module~action', array(), 'html', array(
      'widgetsAttributes'=> array(
          'photo' => array(
                'baseURI' => $j_basepath.'photos/',
                'imgMaxWidth' => 100,
                'imgMaxHeight' => 100
          ))
       )}

Téléchargement d'images

Depuis Jelix 1.7.11, il y a un nouveau type de control, <image>, qui est une évolution de <upload2>. Le widget qui gère ce control permet non seulement d'afficher l'image sélectionnée, mais aussi de l'éditer pour changer sa taille, la découper, etc, avant la validation du formulaire. Il permet de limite automatiquement la taille de l'image. Cela évite le téléchargement d'images trop grosses, qui pourraient provoquer des problèmes de mémoire si il y a un traitement coté PHP.

L'element <image> accepte l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required.

D'autres attributs sont pris en charge :

  • maxWidth et maxHeight : taille maximale accepté. Le code javascript du widget retaillera l'image si elle dépasse les dimensions indiquées.
  • mimetype : pour indiquer le type-mime des images que vous acceptez
  • maxsize : taille maximal du fichier
  • accept : valeur de l'attribut HTML accept pour la balise input.
  • capture : valeur de l'attribut HTML capture pour la balise input.

Exemple :


  <image ref="image" mimetype="image/jpg;image/png;" maxWidth="1024" maxHeight="860">
     <label>A photo</label>
  </image>

Le widget associé accepte les même attributs que celui pour upload2 : uriAction, uriActionParameters, uriActionFileParameter, imgMaxHeight et imgMaxWidth.

Il accepte également les attributs suivants :

  • newImgMaxWidth et newImgMaxHeight : la taille maximale de l'image. Équivalent aux attributs maxWidth et maxHeight sur <image>. Tout dépend si vous voulez indiquer ces valeurs statiquement dans le fichier xml, ou dynamiquement lors de l'affichage du formulaire.
  • dialogWidth et dialogHeight : la taille de la boite de dialogue HTML qui permet d'éditer l'image avant la validation du formulaire. Taille en pixel, ou alors "auto", la taille sera calculée en fonction de la fenêtre du navigateur.

Groupement de champs de saisie

Il peut être utile de regrouper plusieurs contrôles dans un groupe, que ce soit pour l'aspect visuel, ou pour les manipuler ensemble. Pour ce faire, il faut placer les contrôles dans une balise <group>. Cette balise doit avoir un attribut ref, mais peut avoir aussi un attribut readonly, ce qui met en lecture seule tous les contrôles qui s'y trouvent. D'ailleurs, certaines opérations faites sur l'objet PHP correspondant à <group>, impactent sur les contrôles.

Un groupe doit aussi posséder un label.

Exemple de groupe :


  <group ref="un_groupe">
     <label>identité</label>
     <input ref="nom"><label>nom</label></input>
     <input ref="prenom"><label>prénom</label></input>
  </group>

Il est possible d'avoir une case à cocher qui sera affichée au niveau du label, pour permettre à l'utilisateur d'activer ou désactiver tout les champs de saisie du groupe. Utilisez l'attribut withcheckbox.


  <group ref="un_groupe" withcheckbox="true">
     <label>identité</label>
     <input ref="nom"><label>nom</label></input>
     <input ref="prenom"><label>prénom</label></input>
  </group>

Il peut être alors nécessaire, comme pour une <checkbox> de :

  1. spécifier la valeur du contrôle quand la case est cochée ou décochée
  2. spécifier la valeur par défaut

  <group ref="identity" withcheckbox="true" defaultvalue="ok">
     <oncheckvalue label="" value="ok"/>
     <onuncheckvalue label="Pas d'identité" value="no" />
     <label>identité</label>
     <input ref="nom"><label>nom</label></input>
     <input ref="prenom"><label>prénom</label></input>
  </group>

<oncheckvalue> et <onuncheckvalue> supportent également l'attribut locale au lieu de label.

Choix amélioré

Il arrive que l'on veuille proposer à l'utilisateur de faire un choix entre plusieurs cas, et que pour certains choix, on doive donner des renseignements complémentaires. jForms propose pour cela la balise <choice>. Elle contient des balises <item> pour chacun des choix, et dans chacune de ces balises <item>, on indique un <label>, et 0,1 ou plusieurs champs de saisie.


   <choice ref="status">
     <label>Status du bug</label>
     <item value="new"> <label>Nouveau</label> </item>
     <item value="res"> 
         <label>resolu</label>
         <menulist ref="resolution">
            <label>Résolution du bug</label>
            <item value="0">Corrigé</item>
            <item value="1">invalide</item>
            <item value="2">Ne sera pas corrigé</item>
         </menulist>
     </item>
     <item value="dup">
         <label>duplicata</label>
         <input ref="dup_bug"><label>Numéro du bug</label></input>
     </item>
   </choice>

Quand l'utilisateur choisit un des items, les champs des autres items sont désactivés.

La balise <choice> accepte les balises <help>, <hint>, <alert> ainsi que les attributs readonly, required et selectedvalue. Cet attribut peut comporter la valeur de l'item sélectionné par défaut. Une autre façon de sélectionner par défaut un item est de mettre un attribut selected="true" sur la balise <item> correspondant.

Captcha

Dans certain contexte, il est nécessaire d'empêcher la saisie automatique des formulaire (par des robots spammeurs par exemple).

JForms fourni la balise <captcha> pour inclure automatiquement un champs de saisie qui permettra de vérifier que le formulaire est bien saisie par un humain.


 <captcha ref="antispam">
    <label>Vérification anti-spam</label>
 </captcha>

La balise accepte les attributs communs et les balises d'aide.

Pour en savoir plus sur cette fonctionnalité, et pouvoir choisir le type de captcha, voir la section sur les captchas.

Sélecteur de couleur

Pour que l'utilisateur puisse choisir une couleur sur une palette de couleur, vous utiliserez la balise <color>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> ainsi que les attributs readonly et required.


  <color ref="background">
     <label>Couleur de fond</label>
     <hint>Sélectionner la couleur du fond de texte</hint>
  </color>

La valeur est un code html RVB comme #F5468D.

Boutons de validation

Dans un formulaire, il faut bien sûr au moins un bouton qui permette à l'utilisateur de valider la saisie et envoyer les données au serveur. Vous déclarez un bouton de ce type avec la balise <submit>. Comme pour les autres contrôles, vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> (mais pas les attributs readonly ni required).


  <submit ref="submit">
    <label>Ok</label>
  </submit>

La variable de formulaire correspondante ne contiendra rien d'intéressant. À moins que vous ayez besoin de plusieurs boutons de soumission, représentant par exemple l'action à effectuer après l'envoi du formulaire comme un bouton "prévisualiser" et un autre "sauvegarder". Dans ce cas, vous utiliserez comme pour les autres contrôles de type liste, un dao ou les balises <item> :


  <submit ref="valider">
    <label>Veuillez valider</label>
    <item value="preview">Prévisualiser</item>
    <item value="svg">Sauvegarder</item>
  </submit>

Dans la variable de formulaire "valider", vous aurez alors la valeur "preview" ou "svg", et vous pourrez agir en fonction de ces valeurs dans le contrôleur. Au niveau du formulaire HTML, cela affichera deux boutons avec leurs libellés respectifs "Prévisualiser" et "Sauvegarder".

A noter : le code généré n'est pas compatible avec IE (voir https://jelix.org/forums/forum/5-jelix-u(..)).

Bouton reset

Pour afficher un bouton reset avec jForms, il faut utiliser la balise <reset> :


  <reset ref="reinit">
    <label>Réinitialiser</label>
  </reset>

Bouton simple

Vous pouvez afficher un bouton tout simple, avec la balise <button> :


  <button ref="calc">
    <label>Calculer</label>
  </button>

Ce sera à vous d'integrer le javascript qu'il faut dans votre page pour lancer une action sur le click du bouton.

Affichage de valeurs

La balise <output> ne sert qu'à afficher une valeur. Cette dernière ne sera donc pas éditable. Cela peut être utile pour afficher un formulaire de tout un enregistrement sans pour autant éditer tous les champs. Vous devez y mettre l'attribut ref, et vous pouvez utiliser les balises <label>, <hint>, <alert>, <help> (mais pas les attributs readonly ni required).


  <output ref="categorie">
    <label>Catégorie</label>
  </output>

Champs cachés

Si vous voulez inclure des champs cachés dans votre formulaire, utilisez la balise <hidden>. Vous devez y mettre l'attribut ref, et vous pouvez utiliser l'attribut defaultvalue. Tout autre balise ou attribut ne sera pas pris en compte.


   <hidden ref="product_id" />

Source de données

Les contrôles tels que menulist, listbox et radiobuttons, checkboxes contiennent plusieurs choix de valeurs pour l'utilisateur. Il convient donc d'indiquer dans ces contrôles la manière dont jForms va récupérer les valeurs et libellés de ces choix.

Il y a pour le moment trois façons de faire :

  1. indiquer ces choix en dur dans le fichier jForms (données statiques)
  2. indiquer un DAO qui permettra de les récupérer.
  3. indiquer une classe qui fournit ces données.

Données statiques

Elles doivent être indiquées au moyen d'une ou plusieurs balises <item>. La valeur du choix doit être mis dans un attribut value. Le libellé du choix doit être mis en tant que contenu de la balise <item>, ou dans un fichier de locale et alors vous indiquez la locale au moyen de l'attribut locale. Si aucun label est indiqué, le label sera la valeur. Exemple :


   <checkboxes ref="objets">
      <label>Vous avez </label>
      <item value="maison">Une maison</item>
      <item value="voiture" locale="mymodule~myform.item.car.label" />
      <item value="bateau"/>
  </checkboxes>

Données dynamiques avec un DAO

Le contenu d'une liste peut être rempli grâce à un DAO. Vous devez alors mettre une balise <datasource> qui doit avoir au moins 3 attributs :

  1. dao, indiquant le sélecteur de la DAO à utiliser
  2. method, indiquant la méthode de la DAO qui génère la liste des choix
  3. labelproperty, indiquant quelle est la propriété de la DAO qui contient le libellé du choix.

Vous pouvez indiquer un profil jDb (optionnel) à travers l'attribut profile.

La valeur de chaque choix sera la valeur de la clé primaire de la DAO. Cependant, si vous voulez indiquer une autre propriété de la DAO, vous pouvez l'indiquer dans l'attribut valueproperty.

Exemple :


  <menulist ref="conf">
      <label>Sélectionnez l'élément de configuration à éditer</label>
      <datasource dao="testapp~config" method="findAll"
                  labelproperty="cvalue" valueproperty="ckey"/>
  </menulist>

Indiquer une méthode dao qui attend un argument

Si la méthode que vous indiquez demande un paramètre en argument, vous devez indiquer celui-ci.

Si ce paramètre est une valeur statique, ajoutez l'attribut criteria :


      <datasource dao="testapp~config" method="findByCat" criteria="admin"
                  labelproperty="cvalue" valueproperty="ckey"/>

La méthode findByCat() sera appelée avec la valeur "admin" en paramètre.

Pour l'affichage des valeurs

Lorsque le formulaire est affiché via les plugins {formdata} et {formdatafull}, où seules donc sont affichés les valeurs sélectionnées (ou plutôt les libellés correspondants), jForms ne fait pas appel à la méthode indiquée dans method puisqu'elle est censée renvoyer une liste. Par défaut, c'est la méthode get de la factory dao qui est appelée, avec la valeur sélectionnée. Si il y a des critères (statique ou dynamique), ces valeurs seront aussi passées. Ce qui signifie que //la valeur sélectionnée et les éventuels critères doivent correspondre à la clé primaire// de l'enregistrement correspondant à ce qui a été sélectionné.

Or ce n'est pas toujours le cas. La valeur sélectionnée ou les critères peuvent correspondre à d'autres champs que la clé primaire. Il faut donc indiquer une autre méthode du dao, qui permettra de récupérer l'enregistrement correspondant, et qui devra prendre en paramètre à la fois la clé et tous les critères indiqués. Pour ce faire, indiquez dans l'attribut labelmethod la méthode du dao à utiliser (de type selectfirst).

attributs et valeurs multiples

Les attributs suivants supportent la présence de valeurs multiples séparées par des virgules. Ainsi, il est possible de spécifier plusieurs valeurs pour:

  1. labelproperty
  2. criteria
  3. criteriaFrom

labelproperty définissant les propriétés daos utilisées pour l'affichage, il est nécessaire de pouvoir utiliser un séparateur dans le cas de valeurs multiples. Pour cela, il suffit d'ajouter l'attribut labelseparator à l'élément datasource.

Pour reprendre l'exemple précédent, si vous voulez afficher une liste d'éléments de configuration selon une catégorie et une date, et l'afficher sous la forme de couples "nom = valeur":


  <input ref="date">
     ...
  </input>
  <menulist ref="catlist">
     ...
  </menulist>

  <menulist ref="conf">
      <datasource dao="testapp~config" method="findByCatAndDate" criteriafrom="catlist,date"
                  labelproperty="cname,cvalue"  labelseparator=" = " valueproperty="ckey"/>
  </menulist>

Données dynamiques avec une classe

Si vous voulez fournir les données dynamiquement d'une autre manière que par un dao, vous pouvez créer une classe, qui devra implémenter l'interface jIFormsDatasource. Elle sera stockée dans un répertoire classes/ d'un module, et vous l'indiquerez via l'élément <datasource> avec un attribut class.

Exemple de classe :


require_once (JELIX_LIB_PATH.'forms/jFormsDatasource.class.php');

class listData implements jIFormsDatasource
{
  protected $formId = 0;

  protected $data = array();

  function __construct($id)
  {
    $this->formId = $id;
    $this->data = array(0 => 'test',
                         1 => 'test 2',
                         2 => 'Id = '. $id);
  }

  public function getData($form)
  {
    return ($this->data);
  }

  public function getLabel($key)
  {
    if(isset($this->data[$key]))
      return $this->data[$key];
    else
      return null;
  }

}

Et dans le fichier jforms :


  <menulist ref="icone">
        <label locale="elements.crud.label.icone" />
        <datasource class="monmodule~listData" />
  </menulist>

Dépendance d'une liste avec un autre champs de saisie

Pour un champs qui a une source de donnée dynamique, on veut bien souvent faire en sorte que les valeurs de cette source de donnée soient selectionnées en fonction de la valeur d'un autre champs de saisie. Un exemple : une liste de ville qui dépend du choix dans une liste de département.

Vous utiliserez l'attribut criteriafrom (à la place de criteria pour un DAO), où vous indiquerez l'identifiant (attribut ref) de ce champ de saisie pour lequel il faut récupérer la valeur :


  <menulist ref="catlist">
     ...
  </menulist>

  <menulist ref="conf">
      <datasource dao="testapp~config" method="findByCat" criteriafrom="catlist"
                  labelproperty="cvalue" valueproperty="ckey"/>
  </menulist>

Dans cet exemple, on a une liste dont les valeurs sont en fonction d'une autre liste.

Dans la page web, la liste est mise à jour automatiquement quand l'utilisateur change la valeur du contrôle dont dépend la liste.

L'attribut criteriafrom est utilisable aussi bien sur une source de donnée de type dao que sur une source de donnée de type "class".

Il faut alors que la classe implémente l'interface jIFormsDynamicDatasource qui hérite de l'interface jIFormsDatasource2. Elle ajoute deux méthodes setCriteriaControls($list), qui accepte en paramètre une liste d'identifiant de controles, et getCriteriaControls() qui retourne cette liste.

Pour faciliter l'implémentation, il y a une classe jFormsDynamicDatasource qui implémente l'interface jIFormsDynamicDatasource, dont vous pouvez hériter pour votre classe.

Autre source de données

Si l'utilisation d'un DAO, d'une classe ou de données statiques n'est pas suffisante pour vous, regardez la section "Définir les choix d'un champ à multiple choix" dans la page Utilisation de jforms.

Dans ce cas là, vous ne devez pas indiquer de balises <item> ou de balises <datasource>, mais définir l'objet sur la propriété datasource de l'objet du contrôle.

Données groupées

Pour les éléments <menulist> ou <listbox>, vous pouvez grouper les valeurs. Cela générera des éléments optgroup en HTML.

Pour les sources de données statiques, utiliser l'élément <itemsgroup> avec un attribut label ou locale.


   <menulist ref="country">
      <label>Countries </label>
      <itemsgroup label="Europe">
        <item value="fr">France</item>
        <item value="gb">Great Britain</item>
      </itemsgroup>
      <itemsgroup label="Asia">
        <item value="zh">China</item>
        <item value="in">India</item>
      </itemsgroup> 
  </menulist>

Pour les sources de données de type dao ou class, vous devez utiliser l'attribut groupby sur la balise <datasource>. Pour une source de donnée dao, groupby indique la propriété du dao qui contient le libellé du groupe auquel appartient l'enregistrement. Pour une source de donnée de type class, la signification de groupby dépend de l'implémentation de la source de donnée.

Présélection de valeurs

Dans une liste de choix, il est possible d'indiquer des valeurs par défaut qui seront sélectionnées. Vous avez trois façons de le faire :

  1. soit indiquer un attribut selected="true" sur chaque balise item voulue si vous utilisez celles-ci. Plusieurs items peuvent avoir un attribut selected seulement sur les listes de case à cocher (checkboxes), soit sur une listbox "multiple". Dans les autres cas, un seul item doit avoir l'attribut selected.
  2. soit indiquer un attribut selectedvalue sur la balise du contrôle, en y stockant la valeur sélectionnée. Cependant vous ne pouvez indiquer qu'une valeur, donc un seul choix ne sera sélectionné par défaut
  3. soit indiquer un élément <selectedvalues> contenant des éléments <value>. Cette manière de faire est toute indiquée pour checkboxes et listbox en multiple, et quand la source de données est une dao.

Exemples :


  <radiobuttons ref="home">
      <label>Vous habitez</label>
      <item value="pa" selected="true">Paris</item>
      <item value="ma">Marseille</item>
      <item value="ly">Lyon</item>
      <item value="br">Brest</item>
      <item value="li">Lille</item>
      <item value="bo">Bordeaux</item>
  </radiobuttons>

  <menulist ref="conf" selectedvalue="foo.bar">
      <label>Sélectionnez l'élément de configuration à éditer</label>
      <datasource dao="testapp~config" method="findAll"
                  labelproperty="cvalue" valueproperty="ckey">
  </menulist>

  <listbox ref="objets" required="true" multiple="true">
      <label>Vous avez </label>
      <item value="maison">Une maison</item>
      <item value="voiture">Une voiture</item>
      <item value="bateau">Un bateau</item>
      <item value="assiette">Une assiette</item>
      <selectedvalues>
           <value>maison</value>
           <value>bateau</value>
      </selectedvalues>
  </listbox>