SALT > Manuel > Tutoriel > Affichage >
La classe FormHelper permet d'écrire facilement des formulaire HTML.
Son utilisation n'est pas obligatoire, mais elle est recommandée.

Configuration

La classe dispose de quelques options de configuration statiques s'appliquant à toutes les utilisations ultérieures de la classe.

Types

Il existe 2 types de formulaire : GET et POST

Déclaration

Pour écrire un formulaire, on peux utiliser l'une des syntaxes suivantes : <?php
echo FormHelper::get();
// Contenu du formulaire
echo FormHelper::end();

// ou encore :
echo FormHelper::post();
// Contenu du formulaire
echo FormHelper::end();
Par défaut les formulaires renvoient sur la page courante, mais il est possible d'indiquer une autre page dans le 1er paramètre.
<?php
echo FormHelper::get(WEB_RELATIVE.'autre/chemin/page.php');
// Contenu du formulaire
echo FormHelper::end();
// Va générer :
// <form method="get" action="../autre/chemin/page.php">
// </form>
Si la page utilisée comme action (URL courante si le 1er paramètre est NULL, ou 1er paramètre sinon) a des paramètres dans son URL, il faut indiquer dans le 2ème paramètre lesquels on souhaite conserver et/ou surcharger. Par défault les paramètres sont ignorés.
<?php
echo FormHelper::post(WEB_RELATIVE.'autre/chemin/page.php?a=1&b=2&c=3', array('a''b' => 4'd' => 5'e'));
// Contenu du formulaire
echo FormHelper::end();
// Va générer :
// <form method="post" action="../autre/chemin/page.php?a=1&amp;b=4&amp;d=5"> // a => 1, b => 4, d => 5
// </form>
Dans l'exemple précédent on voit que dans le tableau passé en 2ème paramètre : On peut également indiquer la valeur spéciale "*" pour dire de recopier tout les paramètres de la requête ainsi que clé=>NULL pour supprimer un paramètre de la requête
Les paramètres sont interprétés dans l'ordre de leur déclaration, celui-ci a donc une importance :
<?php
// avec une page ?a=1&b=2&c=3
echo FormHelper::post(NULL, array('*''a' => NULL); // va recopier tout les paramètres, puis supprimer 'a' : ?b=2&c=3
echo FormHelper::post(NULL, array('a' => NULL'*'); // va supprimer 'a' puis recopier tout les paramètres : ?a=1&b=2&c=3

Dans le cas où le formulaire est de type GET, le code généré sera un peu différent. En effet, la spécification HTML indique que les paramètres d'une requête sont ignorés en cas de GET. Pour les conserver le framework va donc générer des balises hidden, dans une balise <p> afin de rester compatible XHTML, juste après la balise <form> : <?php
echo FormHelper::get(WEB_RELATIVE.'autre/chemin/page.php?a=1&b=2&c=3', array('a''b' => 4'd' => 5'e'));
// Contenu du formulaire
echo FormHelper::end();
// Va générer :
// <form method="get" action="../autre/chemin/page.php">
// <p style="display:none">
//    <input name="a" value="1" type="hidden">
//    <input name="b" value="4" type="hidden">
//    <input name="d" value="5" type="hidden">
// </p>
// </form>

Enfin, le 3ème paramètre permet d'ajouter n'importe quel autre attribut sur la balise form générée : <?php
echo FormHelper::get(NULLNULL, array('data-name' => '"Fladnag"''target' => '_blank'));
// Contenu du formulaire
echo FormHelper::end();
// Va générer :
// <form data-name="&quot;Fladnag&quot;" target="_blank" method="get" action="/manual/tutorial/display/formhelper/">
// </form>

Ajout d'un champ

Pour ajouter un champ au formulaire, on a deux possibilités :

FORM : Champ d'un objet mappé

Pour afficher un formulaire de modification d'un champ d'un objet mappé, il suffit d'écrire <?php
ViewControl
::edit(); // Important ! Sans cela le champ de formulaire ne s'affichera pas

echo FormHelper::post();
echo 
$monObjet->FORM->monChamp;
echo 
FormHelper::end();
La balise affichée dépend avant tout du type du champ, comme décrit dans la section précédente

La manière dont la balise est générée ensuite dépend de nombreux facteurs.
Pour écrire une balise, on a besoin des informations suivantes : Ces informations peuvent provenir de différentes sources, dans l'ordre de priorité croissante : Le tableau ci-dessous liste, par ordre de priorité décroissante, ce qui peut être spécifié et ce qui est réellement utilisé pour construire un tag HTML de formulaire:
Source Type $format name class options value Autres attributs
$_GET / $_POST           X  
Paramètre de méthode FORM type format name class options value Autres clés
Meta:displayOptions() type format name class options value Autres clés
Metadonnées type/$nullable$displayFormat$name   $values/type/$nullable    
Les éléments utilisés de la source Metadonnées en détail :
Type de champ Type options $format
Number/Text sans liste de valeurs text    
Number/Text non null avec liste de valeurs select La liste indiquée  
Number/Text nullable avec liste de valeurs select L'option ''=>'' + la liste indiquée  
Date text   $displayFormat
Boolean non null checkbox  
Boolean nullable select''=>'', 1=>'Oui', 0=>'Non' 
Les exemples ci-dessous montrent les différents cas d'utilisations : <?php
class MonObjet extends Base {
    public function 
metadata() {
        
parent::MODEL()->registerFields(
            
Field::newNumber('status''Status'TRUE1, array(
                
1=>'Nouveau',
                
2=>'En cours',
                
3=>'Terminé',
            ))->
displayOptions(array(
                
'class' => 'c1 c2',
                
'format' => 'aaa',
            )),
            
Field::newBoolean('visible''Visible'FALSETRUE), // non NULL, TRUE par defaut
            
Field::newBoolean('visible2''Visible2'TRUETRUE), // NULLABLE, TRUE par defaut
            
Field::newBoolean('decision''Décision'TRUENULL)->displayOptions(array( // NULLABLE, NULL par defaut
                
'options'=>array(
                    
=> 'A corriger',
                    
=> 'A ne pas corriger',
                )
            )),
            
Field::newDate('date''Date'SqlDateFormat::DATETIME),
        );
    }
}

$obj = new MonObjet();
$obj->date time();

ViewControl::edit();
echo 
FormHelper::get();

echo 
'Status : '.$obj->FORM->status.'<br/>'// Affiche :
// <select class="c1 c2" name="status">        // c1 c2 proviennent du displayOptions
//   <option value=""> </option>            // Cette option est générée car le champ est NULLABLE
//   <option selected="selected" value="1">Nouveau</option> // La valeur par défaut du champ est selectionnée
//   <option value="2">En cours</option>
//   <option value="3">Terminé</option>
// </select>
echo 'Status C3 : '.$obj->FORM(array('class' => 'c3'))->status.'<br/>'// affiche le meme select, mais c1 c2 sont remplacés par c3
echo 'Visible : '.$obj->FORM->visible.'<br/>'// affiche :
// <input type="checkbox" checked="checked" name="visible">   // Un booléen non null est représenté par une case à cocher
echo 'Visible 2 : '.$obj->FORM->visible2.'<br/>'// affiche :
// <select name="visible2">                 // Un booléen NULLABLE est représenté par une liste à 3 états
//   <option value=""> </option>
//   <option selected="selected" value="1">Oui</option>        // par défaut, les textes générés sont Oui/Non
//   <option value="0">Non</option>
// </select>
echo 'Decision : '.$obj->FORM->decision.'<br/>'// affiche :
// <select name="decision">
//   <option selected="selected" value=""> </option>
//   <option value="1">A corriger</option>                // ici les textes générés sont surchargés par displayOptions
//   <option value="0">A ne pas corriger</option>
// </select>
echo 'Date : '.$obj->FORM->date.'<br/>'// affiche :
// <input type="text" value="dd/mm/yyyy" name="date"> // avec dd/mm/yyyy de la forme d/m/Y qui est le format par défaut d'affichage des dates
echo 'Date : '.$obj->FORM('Y')->date.'<br/>'// affiche :
// <input type="text" value="yyyy" name="date"> // avec yyyy l'année, le format surchargé étant Y
echo 'Date : '.$obj->FORM(array(
        
'format' => 'Y/m/d',
        
'title' => 'the date',
        
'name' => 'date3',
))->
date.'<br/>'// affiche :
// <input type="text" value="yyyy/mm/dd" name="date3" title="the date">
echo 'Date : '.$obj->FORM(array(
        
'type' => 'select',        // ici on change completement le type du tag généré
        
'options' => array('a'=>'01/01/1970''b'=>'26/10/1985'), // et on peut spécifier les options souhaitées
        
'name' => 'date4',
))->
date.'<br/>'// affiche :
// <select name="date4">
//   <option value="a">01/01/1970</option>
//   <option value="b">26/10/1985</option>
// </select>
echo FormHelper::end();

FormHelper : Construction manuelle

On peut utiliser directement les méthodes statiques de la classe FormHelper pour générer des tag HTML de formulaire
Il y a 4 méthodes : Les différents paramètres ne doivent pas être échappés pour l'affichage HTML, ils le seront par ces méthodes avant leur utilisation, y compris pour le tableau $options
Le paramètre $value, si fourni, sera prioritaire par rapport à toutes les autres sources. En clair cela veux dire que le champ aura toujours la valeur de $value. Si on souhaite que le champ puisse prendre pour valeur la précédente valeur soumise, on laissera $value à NULL et on pourra éventuellement renseigner la clé 'value' dans $others pour indiquer la valeur du champ si aucune autre source n'est disponible.
Les attributs NULL ne seront pas ajoutés, et les options dont le texte est une chaine vide seront remplacées par &nbsp; (espace insécable)
<?php
ViewControl
::edit(); // Important ! Sans cela le champ de formulaire ne s'affichera pas

echo FormHelper::post();
echo 
FormHelper::select('simpleSelect', array('A'=>'Arbre''B'=>'Bizarre''C'=>'Chouette')); // affiche une liste déroulante
    // avec les options Arbre, Bizarre et Chouette
echo FormHelper::input(NULL'submit''Envoyer'); // affiche un bouton submit simple
echo FormHelper::end();

Gestion des noms

Il est possible de définir un préfixe pour les noms à utiliser dans les formulaires.
Par exemple, si on fait un formulaire de saisie ou modification multiple contenant plusieurs lignes du même type d'objet, on va générer une liste de balises qui devront avoir des noms différents, par exemple de la forme saisie[id_ligne][name_field]
Pour faire cela, il suffit d'utiliser FormHelper::withNameContainer(...) et FormHelper::withoutNameContainer pour arrêter d'utiliser un préfixe.
La méthode withNameContainer prend un nombre indéfini de paramètres : chacun paramètre sera ajouté comme préfixe. Il sera donc possible d'avoir un préfixe contenant plusieurs ids, par exemple book[id][chapter_id][paragraphe_id][...] <?php
$listeObjet 
= array();
$listeObjet[0] = new MonObjet();
$listeObjet[1] = new MonObjet();

$listeObjet[0]->id 1;
$listeObjet[1]->id 2;

ViewControl::edit();
echo 
FormHelper::post();

foreach(
$listeObjet as $obj) {
    
FormHelper::withNameContainer('saisie'$obj->id); // tout les noms vont être de la forme saisie[id_object][...]

    
echo 'Champ1 : '.$obj->FORM->champ1;
    echo 
'Champ2 : '.$obj->FORM->champ2;

    
FormHelper::withoutNameContainer();
    echo 
'<br/>';
}
echo 
FormHelper::end();
// Va générer :
// Champ1 : <input type="text" value="" name="saisie[1][champ1]"/>
// Champ2 : <input type="text" value="" name="saisie[1][champ2]"/>
// <br>
// Champ1 : <input type="text" value="" name="saisie[2][champ1]"/>
// Champ2 : <input type="text" value="" name="saisie[2][champ2]"/>

Ajout de code javascript

Il est possible d'ajouter des blocs de code javascript lors de la construction d'un formulaire.
Les codes ajoutés seront générés à la fin du formulaire, lors de l'utilisation de FormHelper::end()
Exemple : <?php
ViewControl
::edit();
echo 
FormHelper::get();
FormHelper::registerJavascript('key''alert(1)');
echo 
FormHelper::end();
On peut également : <?php
ViewControl
::edit();
echo 
FormHelper::get();

// enregistre une nouvelle fonction javascript
FormHelper::registerJavascript('log', <<<JS
    function log(e) {
        console.log(e);
    }
JS
);
// récupération de la clé JS de chargement de page
$keyPageLoaded FormHelper::registerJSPageLoaded();

// on ajoute des instructions a exécuter au chargement de la page
FormHelper::registerJSTokenValue($keyPageLoaded'log("begin")');

// on ajoute une instruction avec la clé "keyValue"
FormHelper::registerJSTokenValue($keyPageLoaded'log("bad value")''keyValue');
// on remplace l'instruction avec la clé "keyValue"
FormHelper::registerJSTokenValue($keyPageLoaded'log("good value")''keyValue');

// on ajoute un morceau de code avec un nouveau token
FormHelper::registerJSTokenValue($keyPageLoaded'log("{VALUES}")');

// on ajoute des valeurs au nouveau token
FormHelper::registerJSTokenValue('VALUES''1'NULL", ");
FormHelper::registerJSTokenValue('VALUES''2'NULL", ");
FormHelper::registerJSTokenValue('VALUES''3'NULL", ");

FormHelper::registerJSTokenValue($keyPageLoaded'log("end")');

echo 
FormHelper::end();
?>
Va produire le code javascript suivant : function log(e) {
    console.log(e);
}

if (typeof(jQuery)!="undefined") {
    jQuery(function() {
        log("begin")
        log("good value")
        log("1, 2, 3")
        log("end")
    });
} else {
    document.addEventListener("DOMContentLoaded", function(event) {
        log("begin")
        log("good value")
        log("1, 2, 3")
        log("end")
    });
}