HTMLForm/tutorial2

From MediaWiki.org
Jump to: navigation, search

The rest of this page is about the use of HTMLForm through generic $formDescriptor entries (settings that are common to all fields types). We are therefore working only on HTMLTextField input.

Skip the generic part and directly go to the field specification Stuff

Here we are in

/mediawiki/extensions/MyForm/MyForm_body.php

And working on the execute() function...

Contents

Starting point [edit]

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

Adding One Simple Text Field [edit]

Let's replace "Hello World" by a text field called simpletextfield

# Same as before
public function execute($par) {
        $this->setHeaders();
 
        # A formDescriptor Array to tell HTMLForm what to build
        $formDescriptor = array(
                        'simpletextfield' => array(
                                'label' => 'Simple Text Field', # What's the label of the field
                                'class' => 'HTMLTextField' # What's the input type
                        )
        );
 
        $htmlForm = new HTMLForm( $formDescriptor ); # We build the HTMLForm object
 
        $htmlForm->setSubmitText( 'Allons-y gaiement' ); # What text does the submit button display
        $htmlForm->setTitle( $this->getTitle() ); # You must call setTitle() on an HTMLForm if the context has not been provided to HTMLForm.

 
 
        $htmlForm->show(); # Displaying the form
}

Now, the form looks like:
HTMLFormTutorial.simpletextfield.png

Adding Callback [edit]

Sadly, the previous code displays the form, but the form doesn't work. We need to write some logic to process the form input!

public function execute($par) {
         $this->setHeaders();
 
# A formDescriptor Array to tell HTMLForm what to build
        $formDescriptor = array(
                        'simpletextfield' => array(
                                'label' => 'Simple Text Field', # What's the label of the field
                                'class' => 'HTMLTextField' # What's the input type
                        )
                );
        $htmlForm = new HTMLForm( $formDescriptor, 'myform' ); # We build the HTMLForm object, calling the form "myform"
        $htmlForm->setSubmitText( 'Allons-y gaiement' ); # What text does the submit button display
        $htmlForm->setTitle( $this->getTitle() ); # You must call setTitle() on an HTMLForm

        /* We set a callback function */
        $htmlForm->setSubmitCallback( array( 'SpecialMyForm', 'processInput' ) );  # Call processInput() in SpecialMyForm on submit

        $htmlForm->show(); # Displaying the form
}
 
/* We write a callback function */
# OnSubmit Callback, here we do all the logic we want to do...
static function processInput( $formData ) {
        if ( $formData['simpletextfield'] == 'next' ) {
                return true; #if returned true, the form won't display again. 
        } elseif ($formData['simpletextfield'] == 'again' ) {
                return false; #if returned false, the form will be redisplayed. 
        }
        return 'Try again'; #if returned a string, it will be displayed as an error message with the form
}

Now, the form processes the submitted data:
HTMLFormTutorial.simpletextfield2.png

Adding Validation [edit]

Fields can be individually validated before submit callback

First we tell HTMLForm by adding this line

 'validation-callback' => array('SpecialMyForm', 'validateSimpleTextField'), #Calling validateSimpteTextField() within SpecialMyForm

in formDescriptor:

# A formDescriptor Array to tell HTMLForm what to build
$formDescriptor = array(
            'simpletextfield' => array(
                'label' => 'Simple Text Field', # What's the label of the field
                'class' => 'HTMLTextField', # What's the input type
                'validation-callback' => array('SpecialMyForm', 'validateSimpleTextField'), #Calling validateSimpteTextField() within SpecialMyForm
            )
        );

Then we write the validation logic:

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

Now, the validation logic checks submitted data before processing:
HTMLFormTutorial.simpletextfield3.png

Required Field [edit]

You can specify that a field is required by simply adding

required => true,

to formDescriptor. Any validation-callback will overwrite required. If you want to validate a required field, add the following logic to your validation callback function:

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

Adding Filtering [edit]

Filetering happens BEFORE validation to change input.

formDescriptor declaration:

'filter-callback' => array('SpecialMyForm', 'filterSimpleTextField'),

Filtering logic

static function filterSimpleTextField($simpleTextField, $allData) {
        return $simpleTextField."?!?"; # We add "?!?" to the input
    }

Adding i18n support [edit]

Replacing "label" by "label-message" in formDescriptor will automatically fetch the string through i18n routine:

 $formDescriptor = array(
            'simpletextfield' => array(
                'label-message' => 'myform-simpletextfield', # What's the i18n message id for the field's label
                'class' => 'HTMLTextField', # What's the input type
                'validation-callback' => array('SpecialMyForm', 'validateSimpleTextField'),
                'filter-callback' => array('SpecialMyForm', 'filterSimpleTextField'),
            )
        );

Don't forget to add the correct entry in the i18n file arrays:

'myform-simpletextfield' => 'International Simple Text Field'

For example here, english and french...

'myform-simpletextfield' => 'Champ de texte simple international'

For the submit button, we need to do it "manually" :

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

Of course, as always, you'll need to add the myform-submit entry in the i18n file.

Adding sections [edit]

Now, we need to add some fields and organize them, let's switch to a bigger formDescriptor

$formDescriptor = array(
            'field1' => array(
                'section' => 'section1',
                'class' => 'HTMLTextField',
                'label' => 'field1'
            ),
            'field2' => array(
                'section' => 'section1',
                'class' => 'HTMLTextField',
                'label' => 'field1'
            ),
            'field3' => array(
                'section' => 'section2',
                'class' => 'HTMLTextField',
                'label' => 'field1'
            ),
            'field4' => array(
                'section' => 'section3',
                'class' => 'HTMLTextField',
                'label' => 'field1'
            )
        );

The section string displayed is automatically fetched from i18n file. Here we therefore need to add this in our i18n file:

 'section1' => 'The First Section',
 'section2' => 'Section II',
 'section3' => 'Third Section'

Now, the form looks like:
HTMLFormTutorial.sections.png

Subsections [edit]

Sections can be easily nested with the incredible power of /.

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

The i18n ID will be like:

'subsectionA'

Now, the form looks like:
HTMLFormTutorial.sections2.png

Adding Help-text [edit]

What about providing users with instructions to use your form easily? help or help-message (i18n ID) are here for you

$formDescriptor = array(
            'field1' => array(
                'section' => 'section1',
                'class' => 'HTMLTextField',
                'label' => 'field1',
                'help' => 'Just say something!'
            ),
);

Now, the form looks like:
HTMLFormTutorial.helptext.png

Adding html CLASS and ID [edit]

cssclass and id are here for you

$formDescriptor = array(
            'field1' => array(
                'section' => 'section1',
                'class' => 'HTMLTextField',
                'label' => 'field1',
                'cssclass' => 'AClassForField1',  # Added to the wrapper object class
                'id' => 'AnIdForField1' # Added to the input object
            ),
);

Changing Name of input [edit]

By default, input name is wp{$fieldname}, for the previous example, input name is therefore wpfield1. This can be changed with name :

$formDescriptor = array(
            'field1' => array(
                'section' => 'section1',
                'class' => 'HTMLTextField',
                'label' => 'field1',
                'cssclass' => 'AClassForField1',
                'id' => 'AnIdForField1',
                'name' => 'ANameForField1'
            ),
);

Just to give you an idea, here is the html output generated:

<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>

Disabling input [edit]

disabled is there, user cannot copy (CTRL-C) input. The item will not be valid for submission.

'disabled' => true,

As simple as that!

Turning input read-only [edit]

readonly is there, user can copy (CTRL-C) input.

'readonly' => true,

Again, as simple as that!


NEXT PAGE OF THE TUTORIAL