From 5a113417e5af9d0d0dbed63429649a9780784d45 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Thu, 28 Sep 2017 13:31:41 +0200 Subject: [PATCH] HTMLMultiSelectField: Support sections in OOUI mode The resulting HTML makes very little sense semantically, but no worries, because so does the existing one for non-OOUI forms. Change-Id: I99bf6341c58869f6322b9d9c780d9c66739d00b6 --- .../htmlform/fields/HTMLMultiSelectField.php | 69 ++++++++++++++----- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/includes/htmlform/fields/HTMLMultiSelectField.php b/includes/htmlform/fields/HTMLMultiSelectField.php index 0d5eeba92c..515166c5f1 100644 --- a/includes/htmlform/fields/HTMLMultiSelectField.php +++ b/includes/htmlform/fields/HTMLMultiSelectField.php @@ -125,11 +125,8 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable * @return array Options for inclusion in a select or whatever. */ public function getOptionsOOUI() { - $options = parent::getOptionsOOUI(); - foreach ( $options as &$option ) { - $option['disabled'] = in_array( $option['data'], $this->mParams['disabled-options'], true ); - } - return $options; + // Sections make this difficult. See getInputOOUI(). + throw new MWException( 'HTMLMultiSelectField#getOptionsOOUI() is not supported' ); } /** @@ -142,28 +139,62 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable public function getInputOOUI( $value ) { $this->mParent->getOutput()->addModules( 'oojs-ui-widgets' ); - $attr = []; - $attr['id'] = $this->mID; - $attr['name'] = "{$this->mName}[]"; + $optionsOouiSections = []; + $options = $this->getOptions(); + // If the options are supposed to be split into sections, each section becomes a separate + // CheckboxMultiselectInputWidget. + foreach ( $options as $label => $section ) { + if ( is_array( $section ) ) { + $optionsOouiSections[ $label ] = Xml::listDropDownOptionsOoui( $section ); + unset( $options[$label] ); + } + } + // If anything remains in the array, they are sectionless options. Put them in a separate widget + // at the beginning. + if ( $options ) { + $optionsOouiSections = array_merge( + [ '' => Xml::listDropDownOptionsOoui( $options ) ], + $optionsOouiSections + ); + } + + $out = ''; + foreach ( $optionsOouiSections as $sectionLabel => $optionsOoui ) { + $attr = []; + $attr['name'] = "{$this->mName}[]"; - $attr['value'] = $value; - $attr['options'] = $this->getOptionsOOUI(); + $attr['value'] = $value; + $attr['options'] = $optionsOoui; - if ( $this->mOptionsLabelsNotFromMessage ) { foreach ( $attr['options'] as &$option ) { - $option['label'] = new OOUI\HtmlSnippet( $option['label'] ); + $option['disabled'] = in_array( $option['data'], $this->mParams['disabled-options'], true ); } - } + if ( $this->mOptionsLabelsNotFromMessage ) { + foreach ( $attr['options'] as &$option ) { + $option['label'] = new OOUI\HtmlSnippet( $option['label'] ); + } + } + + $attr += OOUI\Element::configFromHtmlAttributes( + $this->getAttributes( [ 'disabled', 'tabindex' ] ) + ); - $attr += OOUI\Element::configFromHtmlAttributes( - $this->getAttributes( [ 'disabled', 'tabindex' ] ) - ); + if ( $this->mClass !== '' ) { + $attr['classes'] = [ $this->mClass ]; + } - if ( $this->mClass !== '' ) { - $attr['classes'] = [ $this->mClass ]; + $widget = new OOUI\CheckboxMultiselectInputWidget( $attr ); + if ( $sectionLabel ) { + $out .= new OOUI\FieldsetLayout( [ + 'items' => [ $widget ], + 'label' => $sectionLabel, + ] ); + } else { + $out .= $widget; + } } - return new OOUI\CheckboxMultiselectInputWidget( $attr ); + return $out; } /** -- 2.20.1