Page MenuHomePhabricator

HTMLForm multiselect field does not retain its values after submit, when action=GET
Closed, ResolvedPublic

Description

This bug relates to code in includes/htmlform.

When the user submits an HTMLForm, its fields (dropdowns, individual checkboxes, radio buttons, etc.) retain their values when the form redisplays. This feature seems broken for HTMLMultiSelectField fields, however, as of MediaWiki 1.28, when the form is submitted by GET (i.e., $form->setMethod('get')). These fields did retain their value in MediaWiki 1.27, so this behavior appears to be a bug.

Here is sample code that demonstrates the problem. The following special page has a form with two fields: an individual checkbox, and a pair of checkboxes as an HTMLMultiSelectField. On the page, check all three checkboxes and submit the form. The individual checkbox retains its checked state, but the multiselect checkboxes do not. However, if you change the submit method to POST, all three checkboxes retain their values.

Alternatively, if my code has a bug, please educate me - thanks!

<?php

class SpecialOrgStructure extends SpecialPage {

  public function __construct() {
    parent::__construct('OrgStructure');
  }


  public function execute($par) {
    $this->setHeaders();
    $form = new MyForm();
    $form->setTitle($this->getTitle());
    $form->setMethod('get');
    $form->loadData();
    $form->displayForm('');
  }

}

class MyForm extends HTMLForm {
  public function __construct() {
    parent::__construct($this->render(), 'orgstructure');
  }


  public function render() {
    $formElements = array(
      'onecheckbox' => array(
        'name' => 'onecheckbox',
        'type' => 'check',
        'label' => 'Single checkbox',
       ),

      'twocheckboxes' => array(
        'name' => 'twocheckboxes',
        'type' => 'multiselect',
        'label' => 'Multiselect:',
        'options' => array('a'=>'b', 'c'=>'d'),
       ),

    );

    return $formElements;
  }
}

Event Timeline

matmarex edited projects, added MediaWiki-HTMLForm; removed MediaWiki-General.
matmarex subscribed.

This is a change in behavior caused by rMWb5237cfc1b47: HTMLForm: Allow distinguishing between form views and submission attempts to fix T29676.

In short, you need to call $form->setFormIdentifier( 'specialorgstructure' ); for your form to work. (Do it in a method_exists() check if you need to support older MW versions.)

The root cause of the problem is that when dealing with a GET form with a 'multiselect' field (or in general, HTML checkboxes, this is not MediaWiki-specific), we can't tell the difference between the user viewing the form for the first time, or the user submitting the form with no checkboxes checked. We have to always assume one of these two cases:

  • Always assume the user submitted the form. This means that you can not have any checkboxes checked by default (the checks would reappear after unchecking and submitting the form). We did this prior to MW 1.28.
  • Always assume the user viewing the form for the first time. This means that any checked checkboxes will be cleared after submitting the form. We do this after MW 1.28.

To work around this problem, we can now add an extra hidden field to the page (the "form identifier"), and assume the form was submitted only if it's present in the GET data. The change was a while ago, so I'm not certain, but I think the change in behavior you're seeing was for some reason necessary to support this (but it might've been a mistake in my code).

Given that GET forms with a 'multiselect' field are a hopeless case anyway without the identifier, I don't think it's worth the effort trying to make them work better again (but feel free to submit a patch). But it seems that I forgot to document this new feature on mediawiki.org (somewhere near https://www.mediawiki.org/wiki/HTMLForm), so I'm claiming this task as a reminder to myself to do so.

@matmarex - Thanks so much for your extremely clear and detailed explanation. Thanks to you, I have updated the affected extension on our wiki, and it's now working perfectly. I also appreciate very much that the docs will be updated.

matmarex triaged this task as Low priority.

I've been busy with other issues for a while, sorry for the delay. I have now documented this requirement: https://www.mediawiki.org/w/index.php?title=HTMLForm%2Ftutorial2&type=revision&diff=2483995&oldid=2404442