4 * Text field for selecting a value from a large list of possible values, with
5 * auto-completion and optionally with a select dropdown for selecting common
8 * If one of 'options-messages', 'options', or 'options-message' is provided
9 * and non-empty, the select dropdown will be shown. An 'other' key will be
10 * appended using message 'htmlform-selectorother-other' if not already
13 * Besides the parameters recognized by HTMLTextField, the following are
15 * options-messages - As for HTMLSelectField
16 * options - As for HTMLSelectField
17 * options-message - As for HTMLSelectField
18 * autocomplete - Associative array mapping display text to values.
19 * autocomplete-messages - Like autocomplete, but keys are message names.
20 * require-match - Boolean, if true the value must be in the options or the
22 * other-message - Message to use instead of htmlform-selectorother-other for
23 * the 'other' message.
24 * other - Raw text to use for the 'other' message
27 class HTMLAutoCompleteSelectField
extends HTMLTextField
{
28 protected $autocomplete = array();
30 function __construct( $params ) {
32 'require-match' => false,
35 parent
::__construct( $params );
37 if ( array_key_exists( 'autocomplete-messages', $this->mParams
) ) {
38 foreach ( $this->mParams
['autocomplete-messages'] as $key => $value ) {
39 $key = $this->msg( $key )->plain();
40 $this->autocomplete
[$key] = strval( $value );
42 } elseif ( array_key_exists( 'autocomplete', $this->mParams
) ) {
43 foreach ( $this->mParams
['autocomplete'] as $key => $value ) {
44 $this->autocomplete
[$key] = strval( $value );
47 if ( !is_array( $this->autocomplete
) ||
!$this->autocomplete
) {
48 throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
52 if ( $this->mOptions
&& !in_array( 'other', $this->mOptions
, true ) ) {
53 if ( isset( $params['other-message'] ) ) {
54 $msg = wfMessage( $params['other-message'] )->text();
55 } elseif ( isset( $params['other'] ) ) {
56 $msg = $params['other'];
58 $msg = wfMessage( 'htmlform-selectorother-other' )->text();
60 $this->mOptions
[$msg] = 'other';
64 function loadDataFromRequest( $request ) {
65 if ( $request->getCheck( $this->mName
) ) {
66 $val = $request->getText( $this->mName
. '-select', 'other' );
68 if ( $val === 'other' ) {
69 $val = $request->getText( $this->mName
);
70 if ( isset( $this->autocomplete
[$val] ) ) {
71 $val = $this->autocomplete
[$val];
77 return $this->getDefault();
81 function validate( $value, $alldata ) {
82 $p = parent
::validate( $value, $alldata );
88 $validOptions = HTMLFormField
::flattenOptions( $this->getOptions() );
90 if ( in_array( strval( $value ), $validOptions, true ) ) {
92 } elseif ( in_array( strval( $value ), $this->autocomplete
, true ) ) {
94 } elseif ( $this->mParams
['require-match'] ) {
95 return $this->msg( 'htmlform-select-badoption' )->parse();
101 function getAttributes( array $list ) {
104 'data-autocomplete' => FormatJson
::encode( array_keys( $this->autocomplete
) ),
105 ) + parent
::getAttributes( $list );
107 if ( $this->getOptions() ) {
108 $attribs['data-hide-if'] = FormatJson
::encode(
109 array( '!==', $this->mName
. '-select', 'other' )
116 function getInputHTML( $value ) {
117 $oldClass = $this->mClass
;
118 $this->mClass
= (array)$this->mClass
;
120 $valInSelect = false;
123 if ( $this->getOptions() ) {
124 if ( $value !== false ) {
125 $value = strval( $value );
126 $valInSelect = in_array(
127 $value, HTMLFormField
::flattenOptions( $this->getOptions() ), true
131 $selected = $valInSelect ?
$value : 'other';
132 $select = new XmlSelect( $this->mName
. '-select', $this->mID
. '-select', $selected );
133 $select->addOptions( $this->getOptions() );
134 $select->setAttribute( 'class', 'mw-htmlform-select-or-other' );
136 if ( !empty( $this->mParams
['disabled'] ) ) {
137 $select->setAttribute( 'disabled', 'disabled' );
140 if ( isset( $this->mParams
['tabindex'] ) ) {
141 $select->setAttribute( 'tabindex', $this->mParams
['tabindex'] );
144 $ret = $select->getHTML() . "<br />\n";
146 $this->mClass
[] = 'mw-htmlform-hide-if';
149 if ( $valInSelect ) {
152 $key = array_search( strval( $value ), $this->autocomplete
, true );
153 if ( $key !== false ) {
158 $this->mClass
[] = 'mw-htmlform-autocomplete';
159 $ret .= parent
::getInputHTML( $valInSelect ?
'' : $value );
160 $this->mClass
= $oldClass;