21 private bool $mDropdown =
false;
23 private ?
string $mPlaceholder =
null;
40 parent::__construct( $params );
43 if ( !isset( $this->mParams[
'disabled-options'] ) ) {
44 $this->mParams[
'disabled-options'] = [];
47 if ( isset( $params[
'dropdown'] ) ) {
48 $this->mDropdown =
true;
49 if ( isset( $params[
'placeholder'] ) ) {
50 $this->mPlaceholder = $params[
'placeholder'];
51 } elseif ( isset( $params[
'placeholder-message'] ) ) {
52 $this->mPlaceholder = $this->
msg( $params[
'placeholder-message'] )->text();
56 if ( isset( $params[
'flatlist'] ) ) {
57 $this->mClass .=
' mw-htmlform-flatlist';
66 $p = parent::validate( $value, $alldata );
72 if ( !is_array( $value ) ) {
77 $value = array_filter( $value,
'is_scalar' );
79 if ( isset( $this->mParams[
'required'] )
80 && $this->mParams[
'required'] !==
false
83 return $this->
msg(
'htmlform-required' );
86 if ( isset( $this->mParams[
'max'] ) && ( count( $value ) > $this->mParams[
'max'] ) ) {
87 return $this->
msg(
'htmlform-multiselect-toomany', $this->mParams[
'max'] );
90 # If all options are valid, array_intersect of the valid options
91 # and the provided options will return the provided options.
94 $validValues = array_intersect( $value, $validOptions );
95 if ( count( $validValues ) == count( $value ) ) {
98 return $this->
msg(
'htmlform-select-badoption' );
124 $attribs = $this->
getAttributes( [
'disabled',
'tabindex' ] );
126 foreach ( $options as $label => $info ) {
127 if ( is_array( $info ) ) {
128 $html .= Html::rawElement(
'h1', [], $label ) .
"\n";
132 'id' =>
"{$this->mID}-$info",
135 if ( in_array( $info, $this->mParams[
'disabled-options'],
true ) ) {
136 $thisAttribs[
'disabled'] =
'disabled';
138 $checked = in_array( $info, $value,
true );
140 $checkbox = $this->
getOneCheckbox( $checked, $attribs + $thisAttribs, $label );
142 $html .=
' ' . Html::rawElement(
144 [
'class' =>
'mw-htmlform-flatlist-item' ],
155 throw new RuntimeException( __METHOD__ .
' is not supported' );
158 Xml::check(
"{$this->mName}[]", $checked, $attribs ) .
162 [
'for' => $attribs[
'id'] ],
170 $optionsOouiSections = [];
175 foreach ( $options as $label => $section ) {
176 if ( is_array( $section ) ) {
177 $optionsOouiSections[ $label ] = Html::listDropdownOptionsOoui( $section );
178 unset( $options[$label] );
184 $optionsOouiSections = array_merge(
185 [
'' => Html::listDropdownOptionsOoui( $options ) ],
190 return $optionsOouiSections;
206 $this->mParent->getOutput()->addModules(
'oojs-ui-widgets' );
207 if ( $this->mDropdown ) {
208 $this->mParent->getOutput()->addModuleStyles(
'mediawiki.widgets.TagMultiselectWidget.styles' );
212 $value = array_filter( $value,
'is_scalar' );
216 foreach ( $optionsSections as $sectionLabel => &$groupedOptions ) {
218 $attr[
'name'] =
"{$this->mName}[]";
220 $attr[
'value'] = $value;
222 foreach ( $groupedOptions as &$option ) {
223 $option[
'disabled'] = in_array( $option[
'data'], $this->mParams[
'disabled-options'],
true );
225 foreach ( $groupedOptions as &$option ) {
229 $attr[
'options'] = $groupedOptions;
231 $attr += \OOUI\Element::configFromHtmlAttributes(
235 if ( $this->mClass !==
'' ) {
239 $widget = new \OOUI\CheckboxMultiselectInputWidget( $attr );
240 if ( $sectionLabel ) {
241 $out[] = new \OOUI\FieldsetLayout( [
242 'items' => [ $widget ],
244 'label' =>
new \OOUI\HtmlSnippet( $sectionLabel ),
250 unset( $groupedOptions );
253 if ( $this->mPlaceholder ) {
254 $params[
'placeholder'] = $this->mPlaceholder;
256 if ( isset( $this->mParams[
'max'] ) ) {
257 $params[
'tagLimit'] = $this->mParams[
'max'];
259 if ( $this->mDropdown ) {
261 'name' => $this->mName,
262 'options' => $optionsSections,
264 'noJsFallback' => $out,
265 'allowReordering' =>
false,
267 } elseif ( count( $out ) === 1 ) {
268 $firstFieldData = $out[0]->getData() ?: [];
269 $out[0]->setData( $firstFieldData + $params );
275 return implode(
'', $out );
279 return $this->mDropdown ? [
'mediawiki.widgets.MenuTagMultiselectWidget' ] : [];
283 return $this->mDropdown;
293 $fromRequest = $request->getArray( $this->mName, [] );
313 return $this->mDefault ?? [];
323 $forcedOn = array_intersect( $this->mParams[
'disabled-options'], $this->
getDefault() );
326 foreach ( $options as $opt ) {
327 $res[
"$opt"] = in_array( $opt, $forcedOn,
true ) || in_array( $opt, $data,
true );
343class_alias( HTMLMultiSelectField::class,
'HTMLMultiSelectField' );