Implement HTMLComboboxField

It's a dropdown select with the ability to add custom options, or a
text field with input suggestions, whichever you prefer.

This is meant to be a replacement for HTMLSelectOrOtherField and
HTMLAutoCompleteSelectField.

In regular HTML mode, it uses HTML5 `<datalist>` element with no
custom JavaScript. This is supported by a wide range of browsers
(IE 10+, modern Firefox and Chrome, Opera 12+).

In OOUI mode, it uses a ComboBoxInputWidget.

Depends on: I14b40884f185fb4e5

Bug: T118119
Change-Id: I954d3d24ed4efe90be9596a1bd9586ba3aee1e23
This commit is contained in:
Bartosz Dziewoński 2015-11-08 16:21:58 +01:00
parent e1ebc2de02
commit 77d759aab4
6 changed files with 75 additions and 3 deletions

View file

@ -491,6 +491,7 @@ $wgAutoloadLocalClasses = array(
'HTMLCacheUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/HTMLCacheUpdateJob.php',
'HTMLCheckField' => __DIR__ . '/includes/htmlform/HTMLCheckField.php',
'HTMLCheckMatrix' => __DIR__ . '/includes/htmlform/HTMLCheckMatrix.php',
'HTMLComboboxField' => __DIR__ . '/includes/htmlform/HTMLComboboxField.php',
'HTMLEditTools' => __DIR__ . '/includes/htmlform/HTMLEditTools.php',
'HTMLFileCache' => __DIR__ . '/includes/cache/HTMLFileCache.php',
'HTMLFloatField' => __DIR__ . '/includes/htmlform/HTMLFloatField.php',

View file

@ -21,11 +21,12 @@
*/
/**
* Class for generating HTML <select> elements.
* Class for generating HTML <select> or <datalist> elements.
*/
class XmlSelect {
protected $options = array();
protected $default = false;
protected $tagName = 'select';
protected $attributes = array();
public function __construct( $name = false, $id = false, $default = false ) {
@ -49,6 +50,13 @@ class XmlSelect {
$this->default = $default;
}
/**
* @param string|array $tagName
*/
public function setTagName( $tagName ) {
$this->tagName = $tagName;
}
/**
* @param string $name
* @param string $value
@ -127,6 +135,6 @@ class XmlSelect {
$contents .= self::formatOptions( $options, $this->default );
}
return Html::rawElement( 'select', $this->attributes, rtrim( $contents ) );
return Html::rawElement( $this->tagName, $this->attributes, rtrim( $contents ) );
}
}

View file

@ -5,6 +5,9 @@
* auto-completion and optionally with a select dropdown for selecting common
* options.
*
* HTMLComboboxField implements most of the same functionality and should be
* used instead, if possible.
*
* If one of 'options-messages', 'options', or 'options-message' is provided
* and non-empty, the select dropdown will be shown. An 'other' key will be
* appended using message 'htmlform-selectorother-other' if not already
@ -22,7 +25,6 @@
* other-message - Message to use instead of htmlform-selectorother-other for
* the 'other' message.
* other - Raw text to use for the 'other' message
*
*/
class HTMLAutoCompleteSelectField extends HTMLTextField {
protected $autocomplete = array();

View file

@ -0,0 +1,57 @@
<?php
/**
* A combo box field.
*
* You can think of it as a dropdown select with the ability to add custom options,
* or as a text field with input suggestions (autocompletion).
*
* When JavaScript is not supported or enabled, it uses HTML5 `<datalist>` element.
*
* Besides the parameters recognized by HTMLTextField, the following are
* recognized:
* options-messages - As for HTMLSelectField
* options - As for HTMLSelectField
* options-message - As for HTMLSelectField
*/
class HTMLComboboxField extends HTMLTextField {
// FIXME Ewww, this shouldn't be adding any attributes not requested in $list :(
public function getAttributes( array $list, array $mappings = null ) {
$attribs = array(
'type' => 'text',
'list' => $this->mName . '-datalist',
) + parent::getAttributes( $list, $mappings );
return $attribs;
}
function getInputHTML( $value ) {
$datalist = new XmlSelect( false, $this->mName . '-datalist' );
$datalist->setTagName( 'datalist' );
$datalist->addOptions( $this->getOptions() );
return parent::getInputHTML( $value ) . $datalist->getHTML();
}
function getInputOOUI( $value ) {
$disabled = false;
$allowedParams = array( 'tabindex' );
$attribs = $this->getAttributes( $allowedParams, array( 'tabindex' => 'tabIndex' ) );
if ( $this->mClass !== '' ) {
$attribs['classes'] = array( $this->mClass );
}
if ( !empty( $this->mParams['disabled'] ) ) {
$disabled = true;
}
return new OOUI\ComboBoxInputWidget( array(
'name' => $this->mName,
'id' => $this->mID,
'options' => $this->getOptionsOOUI(),
'value' => strval( $value ),
'disabled' => $disabled,
) + $attribs );
}
}

View file

@ -128,6 +128,7 @@ class HTMLForm extends ContextSource {
'textwithbutton' => 'HTMLTextFieldWithButton',
'textarea' => 'HTMLTextAreaField',
'select' => 'HTMLSelectField',
'combobox' => 'HTMLComboboxField',
'radio' => 'HTMLRadioField',
'multiselect' => 'HTMLMultiSelectField',
'limitselect' => 'HTMLSelectLimitField',

View file

@ -2,6 +2,9 @@
/**
* Select dropdown field, with an additional "other" textbox.
*
* HTMLComboboxField implements the same functionality using a single form field
* and should be used instead.
*/
class HTMLSelectOrOtherField extends HTMLTextField {
function __construct( $params ) {