Raccourcis : Contenu - rubriques - sous rubriques
EN FR

Comme il est indiqué dans le chapitre sur l'affichage des formulaires jforms, il est possible de choisir un plugin qui s'occupera de générer le code du formulaire (en HTML, javascript etc..) renvoyé au navigateur.

Vous avez deux types de plugins :

  • ceux qui permettent de générer un formulaire entier, les builders ou générateurs, et donc qui "pilotent" la génération d'un formulaire.
  • les plugins des widgets, qui sont utilisés par les builders, en particulier le générateur HTML par défaut. Un plugin de widget génére le code d'un seul contrôle de formulaire.

Plugin générateur

Il faut d'abord donner un nom à votre générateur. Prenons "monhtml" par exemple. Ensuite :

  • Créez un répertoire formbuilder/monhtml dans le dépôt de plugins de votre application.
  • Créez un fichier monhtml.formbuilder.php dedans.
  • Dans ce fichier, créez une classe monhtmlFormBuilder qui hérite de \jelix\forms\Builder\BuilderBase ou de \jelix\forms\Builder\HtmlBuilder si vous faites un formulaire HTML similaire à ce que génère le générateur HTML par défaut de Jelix.

Dans cette classe, vous devez implémenter les méthodes qui suivent. Ces méthodes doivent afficher les différentes parties du formulaire (en clair, faire des echos), et ne renvoient pas de valeurs. Ces méthodes sont appelées par les différents plugins de templates de jforms.

Après chaque modification de votre générateur de jforms, pensez à vider le cache de votre application (par exemple en utilisant la commande php console.php app:cleartemp), ceci afin de prendre en compte vos modifications.



    /**
     * called during the meta content processing in templates
     * This method should set things on the response, like adding
     * css styles, javascript links etc.
     * @param \jTpl $tpl the template object
     */
    abstract public function outputMetaContent($tpl);

    /**
     * output the header content of the form
     */
    abstract public function outputHeader();

    /**
     * output the footer content of the form
     */
    abstract public function outputFooter();


    /**
     * displays all the form. outputMetaContent, outputHeader and outputFooters are also called 
     */
    abstract public function outputAllControls();

    /**
     * displays the content corresponding of the given control
     * @param jFormsControl $ctrl the control to display
     * @param array $attributes  attribute to add on the generated code (html attributes for example)
     */
    abstract public function outputControl($ctrl, $attributes=array());

    /**
     * displays the label corresponding of the given control
     * @param jFormsControl $ctrl the control to display
     */
    abstract public function outputControlLabel($ctrl, $format = '', $editMode = true);

    /**
     * displays the value of the control (without the control)
     * @param \jFormsControl $ctrl the control to display
     * @param array $attributes  attribute to add on the generated code (html attributes for example)
     */
    abstract public function outputControlValue($ctrl, $attributes=array());

outputMetaContent

Cette méthode doit récupérer l'objet réponse utilisée par le contrôleur, et y spécifier les feuilles de styles, les fichiers javascript à inclure dans la page finale. Exemple :


   public function outputMetaContent($t) {

        $resp= jApp::coord()->response;
        if ($resp === null) {
            return;
        }
        // si les fichiers sont dans le répertoire jelix
        $www = jApp::urlJelixWWWPath();
        // ou si les fichiers sont dans un répertoire à vous dans www
        $www = jApp::urlBasePath();

        $resp->addJSLink($www.'js/fichier.js');
        $resp->addCSSLink($www.'design/fichier.css');

        $resp->addAssets('my_web_assets');

        //we loop on root control has they fill call the outputMetaContent recursively
        foreach( $this->_form->getRootControls() as $ctrlref=>$ctrl) {
            if($ctrl->type == 'hidden') continue;
            if(!$this->_form->isActivated($ctrlref)) continue;

            $widget = $this->getWidget($ctrl, $this->rootWidget);
            $widget->outputMetaContent($resp);
        }
   }

Cette méthode est appelée avant toutes les autres.

outputHeader()

Cette méthode doit générer les balises qui constituent la déclaration du formulaire, ainsi que d'autres informations qui ne sont pas propres à chaque contrôle. Par exemple, la méthode outputHeader du générateur "html" affiche la balise <form>, la liste des erreurs présentes dans le formulaire, les champs cachés, ainsi que quelques lignes de javascript.

outputFooter()

C'est la dernière méthode appelée par les plugins de templates. C'est dans celle-là donc que vous afficherez les dernières informations et balises. Par exemple, la méthode outputFooter du générateur "html" affiche la balise fermante de <form>, ainsi que d'autres lignes javascript.

outputAllControls()

Cette méthode est appelée uniquement par le plugin {formfull}. Elle doit afficher tous les contrôles (en dehors des éléments affichés par outputHeader() et outputFooter()).

outputControlLabel()

Appelé par les plugins de template de jforms utilisés dans un plugin {form}, pour chaque label de champs de saisie. Cette méthode est donc chargée d'afficher le libellé d'un champ de saisie.

Elle reçoit en argument un objet PHP jFormsControl qui contient les informations du champ de saisie dont il faut afficher le label.

Dans le générateur HTML, cette méthode fait appel à un plugin de widget pour afficher la valeur.

outputControl()

Appelé par les plugins de template de jforms utilisés dans un plugin {form}, pour chaque champ de saisie. Cette méthode est donc chargée d'afficher un champ de saisie.

Elle reçoit en argument un objet PHP jFormsControl qui contient les informations du champ de saisie à afficher, et un tableau contenant la liste des attributs à rajouter à la balise créé ou d'autres informations.

Dans le générateur HTML, cette méthode fait appel à un plugin de widget pour afficher un champs de saisie.

outputControlValue()

Appelé par les plugins de template de jforms utilisés dans un plugin {formdata}, pour chaque valeur de champs de saisie. Cette méthode est donc chargée d'afficher uniquement une valeur, quand on veut afficher uniquement les valeurs d'un formulaire, et non ses champs de saisie.

Dans le générateur HTML, cette méthode fait appel à un plugin de widget pour afficher la valeur.

Utiliser un générateur

Si vous voulez utiliser le même générateur dans l'ensemble de l'application, il vous suffit de modifier cette variable dans le fichier de configuration :


[tplplugins]
defaultJformsBuilder = myformbuilder

Si vous voulez utiliser votre générateur uniquement sur des formulaires spécifiques, vous pouvez indiquer le générateur de votre choix en passant son nom aux plugins de template {form} ou {formfull} :


  {formfull $formulaire, 'monmodule~default:sauver', array(), 'myformbuilder'}

Plugin widget

Le générateur HTML fourni par Jelix est un plugin, lui même extensible, utilisant des plugins de type "formwidget" pour générer chaque contrôle. Vous n'avez ainsi pas à développer tout un plugin générateur pour simplement rédéfinir le code HTML et JS généré d'un contrôle.

Un plugin "formwidget" doit implementer l'interface jelix\forms\HtmlWidget\WidgetInterface, et donc fournir ces methodes :

  • getId(): renvoi l'id de l'élement HTML généré
  • getName(): renvoi le nom de l'élement HTML généré
  • getValue(): renvoi la valeur de l'élement HTML généré (valeur du controle en fait)
  • outputMetaContent($resp): génére des liens CSS et Javascript pour la partie <head>
  • outputHelp(): génère le code HTML de l'aide pour le champs de saisie
  • outputLabel($format = '', $editMode = true): génère le libellé HTML du champs
  • outputControl(): génère le champs HTML
  • setAttributes($attributes): définie les attributs qui seront ajoutés sur l'élément HTML, ou des options pour le plugin.

Le plugin peut hériter de la classe jelix\forms\HtmlWidget\WidgetBase, ainsi il y a moins de méthode à implémenter.

Le plugin doit avoir un nom. Il doit être stocké dans un fichier plugins/formwidget/{nom}/{nom}.formwidget.php.

Voyez le code des plugins existants dans lib/jelix/plugins/formwidget/ pour en savoir plus sur le fonctionnement des plugins "formwidget".

Notez qu'il y a un widget spécifique, le widget "racine", qui peut générer du html dans le formulaire, en plus du html généré par le générateur ou les plugins widgets. Il a pour nom le même que celui du générateur. Par exemple pour celui du générateur html, il s'agit du plugin plugins/formwidget/html/html.formwidget.php. Ou pour celui de votre propre générateur monhtml par exemple, dérivant du générateur html, il s'agira de plugins/formwidget/monhtml/monhtml.formwidget.php.

Déclarer un plugin de widget

Après avoir fait un plugin de widget pour le générateur HTML (ou tout autre générateur dérivant du générateur HTML), vous devez le déclarer pour qu'il soit utilisé.

Il y a plusieurs moyens de le déclarer, selon le contexte.

Si vous voulez utiliser un plugin particulier dans un formulaire spécifique, indiquez-le dans les options du générateur, dans le template, au niveau de la liste des plugins. Exemple:


 {form $form, 'action', array(), 'html',
    array('plugins' => array ('birthdaydate' => 'mydateplugin')) }
    ...
 {/form}

 {formfull $form, 'action', array(), 'html',
    array('plugins' => array ('birthdaydate' => 'mydateplugin')) }

Vous indiquez donc ici que pour le champs de saisie qui a pour identifiant 'birthdaydate', vous voulez utiliser plugin "mydateplugin". Le nom du plugin est son nom sans 'formwidget'. Donc ici il s'agit du plugin plugins/formwidget/mydateplugin/mydateplugin.formwidget.php.

Si vous voulez utiliser le plugin dans tous les formulaires utilisant le générateur html, vous pouvez l'indiquer dans la configuration :


[jforms_builder_html]
;<control type> = <nom du plugin>
date = mydateplugin

Si vous faites votre propre builder héritant du générateur html, le générateur tentera de récupérer automatiquement les widgets dont les noms se terminent par le nom du générateur, <controle_type>_<builder_type>.

Ainsi si vous faites un builder "htmlbootstrap", pour le controle date, il utilisera le plugin de widget date_htmlbootstrap. Nul besoin de déclarer le widget quelque part.

Et si les widgets ne suivent pas la nomenclateur du générateur, vous pouvez indiquer dans votre générateur la liste des plugins à utiliser, dans la propriété $pluginsConf :


protected $pluginsConf = array(
    'control type' => 'nom du plugin'
);

Pour le widget 'racine', le type à indiquer dans $pluginsConf, jforms_builder_html, ou {form}, est 'root',