20 private bool $mDropdown =
false;
22 private ?
string $mPlaceholder =
null;
39 parent::__construct( $params );
42 if ( !isset( $this->mParams[
'disabled-options'] ) ) {
43 $this->mParams[
'disabled-options'] = [];
46 if ( isset( $params[
'dropdown'] ) ) {
47 $this->mDropdown =
true;
48 if ( isset( $params[
'placeholder'] ) ) {
49 $this->mPlaceholder = $params[
'placeholder'];
50 } elseif ( isset( $params[
'placeholder-message'] ) ) {
51 $this->mPlaceholder = $this->
msg( $params[
'placeholder-message'] )->text();
55 if ( isset( $params[
'flatlist'] ) ) {
56 $this->mClass .=
' mw-htmlform-flatlist';
65 $p = parent::validate( $value, $alldata );
71 if ( !is_array( $value ) ) {
76 $value = array_filter( $value,
'is_scalar' );
78 if ( isset( $this->mParams[
'required'] )
79 && $this->mParams[
'required'] !==
false
82 return $this->
msg(
'htmlform-required' );
85 if ( isset( $this->mParams[
'max'] ) && ( count( $value ) > $this->mParams[
'max'] ) ) {
86 return $this->
msg(
'htmlform-multiselect-toomany', $this->mParams[
'max'] );
89 # If all options are valid, array_intersect of the valid options
90 # and the provided options will return the provided options.
93 $validValues = array_intersect( $value, $validOptions );
94 if ( count( $validValues ) == count( $value ) ) {
97 return $this->
msg(
'htmlform-select-badoption' );
123 $attribs = $this->
getAttributes( [
'disabled',
'tabindex' ] );
125 foreach ( $options as $label => $info ) {
126 if ( is_array( $info ) ) {
127 $html .= Html::rawElement(
'h1', [], $label ) .
"\n";
131 'id' =>
"{$this->mID}-$info",
134 if ( in_array( $info, $this->mParams[
'disabled-options'],
true ) ) {
135 $thisAttribs[
'disabled'] =
'disabled';
137 $checked = in_array( $info, $value,
true );
139 $checkbox = $this->
getOneCheckbox( $checked, $attribs + $thisAttribs, $label );
141 $html .=
' ' . Html::rawElement(
143 [
'class' =>
'mw-htmlform-flatlist-item' ],
160 throw new RuntimeException( __METHOD__ .
' is not supported' );
163 Html::check(
"{$this->mName}[]", $checked, $attribs ) .
167 [
'for' => $attribs[
'id'] ],
176 $optionsOouiSections = [];
181 foreach ( $options as $label => $section ) {
182 if ( is_array( $section ) ) {
183 $optionsOouiSections[ $label ] = Html::listDropdownOptionsOoui( $section );
184 unset( $options[$label] );
190 $optionsOouiSections = array_merge(
191 [
'' => Html::listDropdownOptionsOoui( $options ) ],
196 return $optionsOouiSections;
212 $this->mParent->getOutput()->addModules(
'oojs-ui-widgets' );
213 if ( $this->mDropdown ) {
214 $this->mParent->getOutput()->addModuleStyles(
'mediawiki.widgets.TagMultiselectWidget.styles' );
218 $value = array_filter( $value,
'is_scalar' );
222 foreach ( $optionsSections as $sectionLabel => &$groupedOptions ) {
224 $attr[
'name'] =
"{$this->mName}[]";
226 $attr[
'value'] = $value;
228 foreach ( $groupedOptions as &$option ) {
229 $option[
'disabled'] = in_array( $option[
'data'], $this->mParams[
'disabled-options'],
true );
231 foreach ( $groupedOptions as &$option ) {
235 $attr[
'options'] = $groupedOptions;
237 $attr += \OOUI\Element::configFromHtmlAttributes(
241 if ( $this->mClass !==
'' ) {
245 $widget = new \OOUI\CheckboxMultiselectInputWidget( $attr );
246 if ( $sectionLabel ) {
247 $out[] = new \OOUI\FieldsetLayout( [
248 'items' => [ $widget ],
255 unset( $groupedOptions );
258 if ( $this->mPlaceholder ) {
259 $params[
'placeholder'] = $this->mPlaceholder;
261 if ( isset( $this->mParams[
'max'] ) ) {
262 $params[
'tagLimit'] = $this->mParams[
'max'];
264 if ( $this->mDropdown ) {
266 'name' => $this->mName,
267 'options' => $optionsSections,
269 'noJsFallback' => $out,
270 'allowReordering' =>
false,
272 } elseif ( count( $out ) === 1 ) {
273 $firstFieldData = $out[0]->getData() ?: [];
274 $out[0]->setData( $firstFieldData + $params );
280 return implode(
'', $out );
285 return $this->mDropdown ? [
'mediawiki.widgets.MenuTagMultiselectWidget' ] : [];
290 return $this->mDropdown;
300 $fromRequest = $request->getArray( $this->mName, [] );
320 return $this->mDefault ?? [];
330 $forcedOn = array_intersect( $this->mParams[
'disabled-options'], $this->
getDefault() );
333 foreach ( $options as $opt ) {
334 $res[
"$opt"] = in_array( $opt, $forcedOn,
true ) || in_array( $opt, $data,
true );
350class_alias( HTMLMultiSelectField::class,
'HTMLMultiSelectField' );