Merge "Drop zh-tw message "saveprefs""
[lhc/web/wiklou.git] / includes / htmlform / HTMLAutoCompleteSelectField.php
1 <?php
2
3 /**
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
6 * options.
7 *
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
11 * present.
12 *
13 * Besides the parameters recognized by HTMLTextField, the following are
14 * recognized:
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
21 * autocomplete.
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
25 *
26 */
27 class HTMLAutoCompleteSelectField extends HTMLTextField {
28 protected $autocomplete = array();
29
30 function __construct( $params ) {
31 $params += array(
32 'require-match' => false,
33 );
34
35 parent::__construct( $params );
36
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 );
41 }
42 } elseif ( array_key_exists( 'autocomplete', $this->mParams ) ) {
43 foreach ( $this->mParams['autocomplete'] as $key => $value ) {
44 $this->autocomplete[$key] = strval( $value );
45 }
46 }
47 if ( !is_array( $this->autocomplete ) || !$this->autocomplete ) {
48 throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
49 }
50
51 $this->getOptions();
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'];
57 } else {
58 $msg = wfMessage( 'htmlform-selectorother-other' )->text();
59 }
60 $this->mOptions[$msg] = 'other';
61 }
62 }
63
64 function loadDataFromRequest( $request ) {
65 if ( $request->getCheck( $this->mName ) ) {
66 $val = $request->getText( $this->mName . '-select', 'other' );
67
68 if ( $val === 'other' ) {
69 $val = $request->getText( $this->mName );
70 if ( isset( $this->autocomplete[$val] ) ) {
71 $val = $this->autocomplete[$val];
72 }
73 }
74
75 return $val;
76 } else {
77 return $this->getDefault();
78 }
79 }
80
81 function validate( $value, $alldata ) {
82 $p = parent::validate( $value, $alldata );
83
84 if ( $p !== true ) {
85 return $p;
86 }
87
88 $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
89
90 if ( in_array( strval( $value ), $validOptions, true ) ) {
91 return true;
92 } elseif ( in_array( strval( $value ), $this->autocomplete, true ) ) {
93 return true;
94 } elseif ( $this->mParams['require-match'] ) {
95 return $this->msg( 'htmlform-select-badoption' )->parse();
96 }
97
98 return true;
99 }
100
101 // FIXME Ewww, this shouldn't be adding any attributes not requested in $list :(
102 public function getAttributes( array $list, array $mappings = null ) {
103 $attribs = array(
104 'type' => 'text',
105 'data-autocomplete' => FormatJson::encode( array_keys( $this->autocomplete ) ),
106 ) + parent::getAttributes( $list, $mappings );
107
108 if ( $this->getOptions() ) {
109 $attribs['data-hide-if'] = FormatJson::encode(
110 array( '!==', $this->mName . '-select', 'other' )
111 );
112 }
113
114 return $attribs;
115 }
116
117 function getInputHTML( $value ) {
118 $oldClass = $this->mClass;
119 $this->mClass = (array)$this->mClass;
120
121 $valInSelect = false;
122 $ret = '';
123
124 if ( $this->getOptions() ) {
125 if ( $value !== false ) {
126 $value = strval( $value );
127 $valInSelect = in_array(
128 $value, HTMLFormField::flattenOptions( $this->getOptions() ), true
129 );
130 }
131
132 $selected = $valInSelect ? $value : 'other';
133 $select = new XmlSelect( $this->mName . '-select', $this->mID . '-select', $selected );
134 $select->addOptions( $this->getOptions() );
135 $select->setAttribute( 'class', 'mw-htmlform-select-or-other' );
136
137 if ( !empty( $this->mParams['disabled'] ) ) {
138 $select->setAttribute( 'disabled', 'disabled' );
139 }
140
141 if ( isset( $this->mParams['tabindex'] ) ) {
142 $select->setAttribute( 'tabindex', $this->mParams['tabindex'] );
143 }
144
145 $ret = $select->getHTML() . "<br />\n";
146
147 $this->mClass[] = 'mw-htmlform-hide-if';
148 }
149
150 if ( $valInSelect ) {
151 $value = '';
152 } else {
153 $key = array_search( strval( $value ), $this->autocomplete, true );
154 if ( $key !== false ) {
155 $value = $key;
156 }
157 }
158
159 $this->mClass[] = 'mw-htmlform-autocomplete';
160 $ret .= parent::getInputHTML( $valInSelect ? '' : $value );
161 $this->mClass = $oldClass;
162
163 return $ret;
164 }
165
166 /**
167 * Get the OOUI version of this input.
168 * @param string $value
169 * @return false
170 */
171 function getInputOOUI( $value ) {
172 // To be implemented, for now override the function from HTMLTextField
173 return false;
174 }
175 }