Jump to content

Manuel:Tutoriel HTMLForm seconde partie

From mediawiki.org
This page is a translated version of the page Manual:HTMLForm Tutorial 2 and the translation is 100% complete.

La suite de cette page concerne l'utilisation de HTMLForm à travers les entrées génériques de $formDescriptor (valeurs communes à tous les types de champs). Nous allons donc travailler uniquement avec l'entrée HTMLTextField.

Sauter la partie générique et aller directement aux chapîtres de spécification des champs

Ici nous sommes dans /mediawiki/extensions/MyForm/MyForm_body.php et nous travaillons avec la fonction execute() ...

Point de départ

public function execute( $par ) {
    $this->setHeaders();
    $this->getOutput()->addHTML( 'Hello World' );
}

Ajouter un texte simple

Nous souhaitons remplacer « Hello World » par un champ de texte appelé simpletextfield

public function execute( $par ) {
    $this->setHeaders();

    // tableau formDescriptor pour dire à HTMLForm ce qu'il faut construire
    $formDescriptor = [
        'simpletextfield' => [
            'label' => 'Simple Text Field', // Label of the field
            'class' => 'HTMLTextField', // Input type
        ]
    ];

    // construire l'objet HTMLForm
    $htmlForm = HTMLForm::factory( 'table', $formDescriptor, $this->getContext() );

    // texte à afficher sur le bouton submit
    $htmlForm->setSubmitText( 'Allons-y gaiement' );

    $htmlForm->show(); // afficher le formulaire
}

Maintenant le formulaire ressemble à :

Ajouter une fonction de callback

Malheureusement, le code précédent affiche le formulaire, mais celui-ci ne fonctionne pas. Il faut écrire la logique qui va traiter l'entrée !

public function execute( $par ) {
    $this->setHeaders();

    // tableau formDescriptor pour dire à HTMLForm ce qu'il faut construire
    $formDescriptor = [
        'simpletextfield' => [
            'label' => 'Simple Text Field', // Label of the field
            'class' => 'HTMLTextField', // Input type
        ]
    ];
    // construire l'objet HTMLForm avec le nom de formulaire 'myform'
    $htmlForm = new HTMLForm( $formDescriptor, $this->getContext(), 'myform' );
    // texte à afficher sur le bouton submit
    $htmlForm->setSubmitText( 'Allons-y gaiement' );

    // identifier une fonction de callback
    $htmlForm->setSubmitCallback( [ $this, 'processInput' ] );  
    // appelez processInput() dans votre classe SpecialPage étendue quand on appuie sur submit

    // afficher le formulaire
    $htmlForm->show();
}

// fonction de callback
// fonction de retour de OnSubmit; ici nous exécutons la logique que nous voulons implémenter...
public static function processInput( $formData ) {
    // si true est retourné, le formulaire ne se réaffichera pas
    if ( $formData['simpletextfield'] === 'next' ) {
        return true; 
    } elseif ( $formData[ 'simpletextfield' ] === 'again' ) {
        // si false est retourné, le formulaire sera réaffiché
        return false;
    }

    // si une chaîne est retournée, elle sera affichée avec le formulaire en tant que message d'erreur
    return 'Try again';
}

Maintenant le formulaire peut traiter les données saisies :

Méthodes de soumission

Le formulaire peut être configuré pour utiliser les méthodes d'envoi POST ou GET.

  • POST (par défaut): le contenu des champs du formulaire n'apparaissent pas dans l'URL de la page. Cette méthode doit être utilisée pour les formulaires qui modifient le contenu du wiki (par exemple les modifications de pages ou le blocage d'utilisateurs).
  • GET: le contenu des champs du formulaire apparaissent dans l'URL de la page. L'URL résultante peut être ajoutée au marque-pages ou être utilisée comme un lien pour permettre aux autres utilisateurs de la voir. Néanmoins cette méthode peut échouer avec de très longs formulaires (plusieurs kilo-octets de texte). Elle doit être utilisée pour des formulaires qui ne modifient pas le contenu du wiki (par exemple pour l'affichage d'une liste de pages).

Pour envoyer les données via une requête GET, vous devez ajouter ce qui suit :

$htmlForm->setMethod( 'get' );

Pour fonctionner correctement notez que les formulaires GET qui utilisent un champ check ou multiselect doivent avoir un « identifiant de formulaire » initialisé, de la même façon que lorsque vous utilisez plusieurs formulaires sur une même page – voir Utiliser plusieurs formulaires sur la même page ci-dessous.

Ajouter la validation

Les champs peuvent être contrôlés individuellement avant d'exécuter la fonction de callback.

D'abord il faut le dire à HTMLForm en ajoutant cette ligne :

// appeler validateSimpteTextField() dans votre classe SpecialPage étendue
'validation-callback' => [ $this, 'validateSimpleTextField' ],

dans formDescriptor:

// tableau formDescriptor pour dire à HTMLForm ce qu'il faut construire
$formDescriptor = [
    'simpletextfield' => [
        // étiquette du champ
        'label' => 'Simple Text Field',
        'class' => 'HTMLTextField',
        // appeler validateSimpleTextField() dans votre classe SpecialPage étendue
        'validation-callback' => [ $this, 'validateSimpleTextField' ],
    ]
];

Puis écrivez la logique de validation :

public static function validateSimpleTextField( $simpleTextField, $allData ) {
    if ( $simpleTextField === 'merde' ) {
        return 'Excuse my French';
    }
    return true;
}

Maintenant, la logique de validation vérifie les données soumises avant de les traiter :

Champ obligatoire

Vous pouvez spécifier qu'un champ est obligatoire simplement en ajoutant :

'required' => true,

dans le formDescriptor. Tout validation-callback se substitue au caractère obligatoire. Si vous voulez valider un champ nécessaire, ajoutez la logique suivante à votre fonction callback de validation :

if ( $simpleTextField === '' ) {
    return wfMessage( 'htmlform-required', 'parseinline' );
}

Ajouter un filtrage

Le filtrage modifie l'entrée et se produit AVANT la validation.

Déclaration correspondante dans formDescriptor :

'filter-callback' => [ $this, 'filterSimpleTextField' ],

Logique de fltrage :

public static function filterSimpleTextField( $simpleTextField, $allData ) {
    // ajouter  "?!?" à l'entrée 
    return $simpleTextField . '?!?';
}

Ajouter l'internationalisation (prise en charge de i18n)

Il s'agit ici de traduire l'étiquette en fonction de la langue de l'interface utilisateur définie dans les préférences utilisateur. Il faut alors remplacer 'label' par 'label-message' dans formDescriptor pour automatiquement aller chercher la chaîne traduite à travers la routine i18n :

 $formDescriptor = [
    'simpletextfield' => [
        // id du message i18n pour l'étiquette du champ
        'label-message' => 'myform-simpletextfield',
        // type d'entrée
        'class' => 'HTMLTextField',
        'validation-callback' => [ $this, 'validateSimpleTextField' ],
        'filter-callback' => [ $this, 'filterSimpleTextField' ],
    ]
];

N'oubliez pas d'ajouter l'entrée correspondante dans les fichiers de localisation. Par exemple, ici en anglais et en français...

"myform-simpletextfield": "International Simple Text Field"

"myform-simpletextfield": "Champ de texte simple international"

Pour le bouton submit , il faut le faire « manuellement » :

$htmlForm->setSubmitText( wfMessage( 'myform-submit' ) );

bien sûr, comme toujours, ajoutez l'entrée myform-submit dans les fichiers de localisation.

Ajouter des sections

Maintenant il nous faut ajouter des champs supplémentaires et les organiser; passons à un formDescriptor un peu plus conséquent.

$formDescriptor = [
    'field1' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field2' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field3' => [
        'section' => 'section2',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field4' => [
        'section' => 'section3',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ]
];

La chaîne de la section affichée est automatiquement récupérée à partir des fichiers de localisation. C'est pourquoi à ce niveau nous devons l'ajouter dans en.json :

{
    "section1": "The First Section",
    "section2": "Section II",
    "section3": "Third Section"
}

Maintenant le formulaire ressemble à :

Cas des sous-sections

Les sections peuvent être facilement imbriquées grâce à la puissance incroyable de /.

$formDescriptor = [
    'field1' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field2' => [
        'section' => 'section1/subsectionA',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field3' => [
        'section' => 'section2/subsectionB',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ],
    'field4' => [
        'section' => 'section2/subsectionC',
        'class' => 'HTMLTextField',
        'label' => 'field1',
    ]
];

Les ID i18n ressembleront à :

'subsectionA'

Maintenant le formulaire ressemble à :

Ajouter un texte d'aide

Et que pensez-vous de fournir une aide pour que les utilisateurs puissent se servir de votre formulaire facilement ? help ou help-message (un nom de message i18n) sont faits pour vous.

$formDescriptor = [
    'field1' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
        'help' => 'Just say something!',
    ],
];

Maintenant le formulaire ressemble à :

Ajouter CLASS et ID html

cssclass et id sont faits pour cela.

$formDescriptor = [
    'field1' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
         // ajouter à la classe de l'objet conteneur
        'cssclass' => 'AClassForField1',
        // ajouter à l'objet d'entrée
        'id' => 'AnIdForField1',
    ],
];

Modifier le nom de l'entrée

Par défaut, le nom de l'entrée est wp{$fieldname} ; dans l'exemple précédent, le nom de l'entrée est donc wpfield1. Ceci peut être changé avec name :

$formDescriptor = [
    'field1' => [
        'section' => 'section1',
        'class' => 'HTMLTextField',
        'label' => 'field1',
        'cssclass' => 'AClassForField1',
        'id' => 'AnIdForField1',
        'name' => 'ANameForField1',
    ],
];

Simplement pour vous donner une idée, voici le HTML généré en sortie :

<tr class="mw-htmlform-field-HTMLTextField AClassForField1">
    <td class="mw-label">
        <label for="AnIdForField1">field1</label>
    </td>
    <td class="mw-input">
        <input id="AnIdForField1" size="45" name="ANameForField1">
    </td>
</tr>

Désactiver les entrées

disabled' est présent et l'utilisateur ne pourra pas modifier l'entrée. (avec certains navigateurs, il est possible de ne pas pouvoir copier la valeur). L'élément ne sera pas envoyé au serveur.

'disabled' => true,

c'est aussi simple que cela !

Mettre les entrées en lecture seulement

Utilisez readonly pour cela, et l'utilisateur ne pourra pas modifier l'entrée. L'élément sera envoyé au serveur.

'readonly' => true,

Encore une fois, aussi simple que cela !

Utiliser des fomulaires multiples sur une seule page

Version de MediaWiki :
1.28

Si vous utilisez plusieurs formulaires sur une page spéciale unique (par exemple un pour afficher les résultats de recherche, et un autre pour modifier un résultat), vous devez utiliser des identificateurs de formulaire pour permettre à HTMLForm de détecter d'où provient le submit. L'identifiant peut être une chaîne quelconque, mais doit être différente pour chaque formulaire de la page.

$htmlForm->setFormIdentifier( 'myform1' );

Pour des raisons techniques, ceci est aussi nécessaire lorsque vous utilisez un champ check ou multiselect dans un formulaire GET; sinon HTMLForm ne peut pas détecter si le formulaire a été soumis et donc s'il doit charger les valeurs par défaut ou non.[1]

PAGE SUIVANTE DU TUTORIEL

Références