MediaWiki REL1_39
HTMLSelectAndOtherField.php
Go to the documentation of this file.
1<?php
2
16 private const FIELD_CLASS = 'mw-htmlform-select-and-other-field';
18 private $mFlatOptions;
19
24 public function __construct( $params ) {
25 if ( array_key_exists( 'other', $params ) ) {
26 // Do nothing
27 } elseif ( array_key_exists( 'other-message', $params ) ) {
28 $params['other'] = $this->getMessage( $params['other-message'] )->plain();
29 } else {
30 $params['other'] = $this->msg( 'htmlform-selectorother-other' )->plain();
31 }
32
33 parent::__construct( $params );
34
35 if ( $this->getOptions() === null ) {
36 // Sulk
37 throw new MWException( 'HTMLSelectAndOtherField called without any options' );
38 }
39 if ( !in_array( 'other', $this->mOptions, true ) ) {
40 // Have 'other' always as first element
41 $this->mOptions = [ $params['other'] => 'other' ] + $this->mOptions;
42 }
43 $this->mFlatOptions = self::flattenOptions( $this->getOptions() );
44 }
45
46 public function getInputHTML( $value ) {
47 $select = parent::getInputHTML( $value[1] );
48
49 $textAttribs = [
50 'size' => $this->getSize(),
51 ];
52
53 if ( isset( $this->mParams['maxlength-unit'] ) ) {
54 $textAttribs['data-mw-maxlength-unit'] = $this->mParams['maxlength-unit'];
55 }
56
57 $allowedParams = [
58 'required',
59 'autofocus',
60 'multiple',
61 'disabled',
62 'tabindex',
63 'maxlength', // gets dynamic with javascript, see mediawiki.htmlform.js
64 'maxlength-unit', // 'bytes' or 'codepoints', see mediawiki.htmlform.js
65 ];
66
67 $textAttribs += $this->getAttributes( $allowedParams );
68
69 $textbox = Html::input( $this->mName . '-other', $value[2], 'text', $textAttribs );
70
71 $wrapperAttribs = [
72 'id' => $this->mID,
73 'class' => self::FIELD_CLASS
74 ];
75 if ( $this->mClass !== '' ) {
76 $wrapperAttribs['class'] .= ' ' . $this->mClass;
77 }
78 return Html::rawElement(
79 'div',
80 $wrapperAttribs,
81 "$select<br />\n$textbox"
82 );
83 }
84
85 protected function getOOUIModules() {
86 return [ 'mediawiki.widgets.SelectWithInputWidget' ];
87 }
88
89 public function getInputOOUI( $value ) {
90 $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.SelectWithInputWidget.styles' );
91
92 # TextInput
93 $textAttribs = [
94 'name' => $this->mName . '-other',
95 'value' => $value[2],
96 ];
97
98 $allowedParams = [
99 'required',
100 'autofocus',
101 'multiple',
102 'disabled',
103 'tabindex',
104 'maxlength',
105 ];
106
107 $textAttribs += OOUI\Element::configFromHtmlAttributes(
108 $this->getAttributes( $allowedParams )
109 );
110
111 # DropdownInput
112 $dropdownInputAttribs = [
113 'name' => $this->mName,
114 'options' => $this->getOptionsOOUI(),
115 'value' => $value[1],
116 ];
117
118 $allowedParams = [
119 'tabindex',
120 'disabled',
121 ];
122
123 $dropdownInputAttribs += OOUI\Element::configFromHtmlAttributes(
124 $this->getAttributes( $allowedParams )
125 );
126
127 $disabled = false;
128 if ( isset( $this->mParams[ 'disabled' ] ) && $this->mParams[ 'disabled' ] ) {
129 $disabled = true;
130 }
131
132 $inputClasses = [ self::FIELD_CLASS ];
133 if ( $this->mClass !== '' ) {
134 $inputClasses = array_merge( $inputClasses, explode( ' ', $this->mClass ) );
135 }
136 return $this->getInputWidget( [
137 'id' => $this->mID,
138 'disabled' => $disabled,
139 'textinput' => $textAttribs,
140 'dropdowninput' => $dropdownInputAttribs,
141 'or' => false,
142 'required' => $this->mParams[ 'required' ] ?? false,
143 'classes' => $inputClasses,
144 'data' => [
145 'maxlengthUnit' => $this->mParams['maxlength-unit'] ?? 'bytes'
146 ],
147 ] );
148 }
149
154 public function getInputWidget( $params ) {
155 return new MediaWiki\Widget\SelectWithInputWidget( $params );
156 }
157
161 public function getDefault() {
162 $default = parent::getDefault();
163
164 // Default values of empty form
165 $final = '';
166 $list = 'other';
167 $text = '';
168
169 if ( $default !== null ) {
170 $final = $default;
171 // Assume the default is a text value, with the 'other' option selected.
172 // Then check if that assumption is correct, and update $list and $text if not.
173 $text = $final;
174 foreach ( $this->mFlatOptions as $option ) {
175 $match = $option . $this->msg( 'colon-separator' )->inContentLanguage()->text();
176 if ( strpos( $final, $match ) === 0 ) {
177 $list = $option;
178 $text = substr( $final, strlen( $match ) );
179 break;
180 }
181 }
182 }
183
184 return [ $final, $list, $text ];
185 }
186
192 public function loadDataFromRequest( $request ) {
193 if ( $request->getCheck( $this->mName ) ) {
194 $list = $request->getText( $this->mName );
195 $text = $request->getText( $this->mName . '-other' );
196
197 // Should be built the same as in mediawiki.htmlform.js
198 if ( $list == 'other' ) {
199 $final = $text;
200 } elseif ( !in_array( $list, $this->mFlatOptions, true ) ) {
201 # User has spoofed the select form to give an option which wasn't
202 # in the original offer. Sulk...
203 $final = $text;
204 } elseif ( $text == '' ) {
205 $final = $list;
206 } else {
207 $final = $list . $this->msg( 'colon-separator' )->inContentLanguage()->text() . $text;
208 }
209 return [ $final, $list, $text ];
210 }
211 return $this->getDefault();
212 }
213
214 public function getSize() {
215 return $this->mParams['size'] ?? 45;
216 }
217
218 public function validate( $value, $alldata ) {
219 # HTMLSelectField forces $value to be one of the options in the select
220 # field, which is not useful here. But we do want the validation further up
221 # the chain
222 $p = parent::validate( $value[1], $alldata );
223
224 if ( $p !== true ) {
225 return $p;
226 }
227
228 if ( isset( $this->mParams['required'] )
229 && $this->mParams['required'] !== false
230 && $value[0] === ''
231 ) {
232 return $this->msg( 'htmlform-required' );
233 }
234
235 return true;
236 }
237}
getMessage( $value)
Turns a *-message parameter (which could be a MessageSpecifier, or a message name,...
static flattenOptions( $options)
flatten an array of options to a single array, for instance, a set of "<options>" inside "<optgroups>...
getOptions()
Fetch the array of options from the field's parameters.
array bool null $mOptions
msg( $key,... $params)
Get a translated interface message.
getAttributes(array $list)
Returns the given attributes from the parameters.
getOptionsOOUI()
Get options and make them into arrays suitable for OOUI.
Double field with a dropdown list constructed from a system message in the format.
getInputOOUI( $value)
Same as getInputHTML, but returns an OOUI object.Defaults to false, which getOOUI will interpret as "...
getInputHTML( $value)
This function must be implemented to return the HTML to generate the input object itself....
getOOUIModules()
Get the list of extra ResourceLoader modules which must be loaded client-side before it's possible to...
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.Don't forget to call pare...
A select dropdown field.
MediaWiki exception.