MediaWiki master
HTMLRadioField.php
Go to the documentation of this file.
1<?php
2
4
5use InvalidArgumentException;
9
32 public function __construct( $params ) {
33 parent::__construct( $params );
34
35 if ( isset( $params['flatlist'] ) ) {
36 $this->mClass .= ' mw-htmlform-flatlist';
37 }
38 }
39
41 public function validate( $value, $alldata ) {
42 $p = parent::validate( $value, $alldata );
43
44 if ( $p !== true ) {
45 return $p;
46 }
47
48 if ( !is_string( $value ) && !is_int( $value ) ) {
49 return $this->msg( 'htmlform-required' );
50 }
51
52 $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
53
54 if ( in_array( strval( $value ), $validOptions, true ) ) {
55 return true;
56 } else {
57 return $this->msg( 'htmlform-select-badoption' );
58 }
59 }
60
69 public function getInputHTML( $value ) {
70 if (
71 isset( $this->mParams['option-descriptions'] ) ||
72 isset( $this->mParams['option-descriptions-messages'] ) ) {
73 throw new InvalidArgumentException(
74 "Non-Codex HTMLForms do not support the 'option-descriptions' parameter for radio buttons"
75 );
76 }
77
78 $html = $this->formatOptions( $this->getOptions(), strval( $value ) );
79
80 return $html;
81 }
82
84 public function getInputOOUI( $value ) {
85 if (
86 isset( $this->mParams['option-descriptions'] ) ||
87 isset( $this->mParams['option-descriptions-messages'] ) ) {
88 throw new InvalidArgumentException(
89 "Non-Codex HTMLForms do not support the 'option-descriptions' parameter for radio buttons"
90 );
91 }
92
93 $options = [];
94 foreach ( $this->getOptions() as $label => $data ) {
95 if ( is_int( $label ) ) {
96 $label = strval( $label );
97 }
98 $options[] = [
99 'data' => $data,
100 'label' => $this->makeLabelSnippet( $label ),
101 ];
102 }
103
104 return new \OOUI\RadioSelectInputWidget( [
105 'name' => $this->mName,
106 'id' => $this->mID,
107 'value' => $value,
108 'options' => $options,
109 ] + \OOUI\Element::configFromHtmlAttributes(
110 $this->getAttributes( [ 'disabled', 'tabindex' ] )
111 ) );
112 }
113
115 public function getInputCodex( $value, $hasErrors ) {
116 $optionDescriptions = $this->getOptionDescriptions();
117 $html = '';
118
119 // Iterate over an array of options and return the HTML markup.
120 foreach ( $this->getOptions() as $label => $radioValue ) {
121 $description = $optionDescriptions[$radioValue] ?? '';
122 $descriptionID = Sanitizer::escapeIdForAttribute(
123 $this->mID . "-$radioValue-description"
124 );
125
126 // Attributes for the radio input.
127 $radioInputClasses = [ 'cdx-radio__input' ];
128 $radioInputAttribs = [
129 'id' => Sanitizer::escapeIdForAttribute( $this->mID . "-$radioValue" ),
130 'type' => 'radio',
131 'name' => $this->mName,
132 'class' => $radioInputClasses,
133 'value' => $radioValue
134 ];
135 $radioInputAttribs += $this->getAttributes( [ 'disabled', 'tabindex' ] );
136 if ( $description ) {
137 $radioInputAttribs['aria-describedby'] = $descriptionID;
138 }
139
140 // Set the selected value as "checked".
141 if ( $radioValue === $value ) {
142 $radioInputAttribs['checked'] = true;
143 }
144
145 // Attributes for the radio icon.
146 $radioIconClasses = [ 'cdx-radio__icon' ];
147 $radioIconAttribs = [
148 'class' => $radioIconClasses,
149 ];
150
151 // Attributes for the radio label.
152 $radioLabelClasses = [ 'cdx-label__label' ];
153 $radioLabelAttribs = [
154 'class' => $radioLabelClasses,
155 'for' => $radioInputAttribs['id']
156 ];
157
158 // HTML markup for radio input, radio icon, and radio label elements.
159 $radioInput = Html::element( 'input', $radioInputAttribs );
160 $radioIcon = Html::element( 'span', $radioIconAttribs );
161 $radioLabel = Html::rawElement( 'label', $radioLabelAttribs,
162 $this->escapeLabel( $label ) );
163
164 $radioDescription = '';
165 if ( isset( $optionDescriptions[$radioValue] ) ) {
166 $radioDescription = Html::rawElement(
167 'span',
168 [ 'id' => $descriptionID, 'class' => 'cdx-label__description' ],
169 $optionDescriptions[$radioValue]
170 );
171 }
172 $radioLabelWrapper = Html::rawElement(
173 'div',
174 [ 'class' => 'cdx-radio__label cdx-label' ],
175 $radioLabel . $radioDescription
176 );
177
178 // HTML markup for CSS-only Codex Radio.
179 $radio = Html::rawElement(
180 'div',
181 [ 'class' => 'cdx-radio' ],
182 $radioInput . $radioIcon . $radioLabelWrapper
183 );
184
185 // Append the Codex Radio HTML markup to the initialized empty string variable.
186 $html .= $radio;
187 }
188
189 return $html;
190 }
191
197 public function formatOptions( $options, $value ) {
198 $html = '';
199
200 $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
201
202 # @todo Should this produce an unordered list perhaps?
203 foreach ( $options as $label => $info ) {
204 if ( is_array( $info ) ) {
205 $html .= Html::rawElement( 'h1', [], $label ) . "\n";
206 $html .= $this->formatOptions( $info, $value );
207 } else {
208 $id = Sanitizer::escapeIdForAttribute( $this->mID . "-$info" );
209 $classes = [ 'mw-htmlform-flatlist-item' ];
210 $radio = Html::radio(
211 $this->mName,
212 $info === $value,
213 $attribs + [ 'value' => $info, 'id' => $id ]
214 );
215
216 $radio .= "\u{00A0}" .
217 Html::rawElement( 'label', [ 'for' => $id ], $this->escapeLabel( $label ) );
218
219 $html .= ' ' . Html::rawElement(
220 'div',
221 [ 'class' => $classes ],
222 $radio
223 );
224 }
225 }
226
227 return $html;
228 }
229
236 protected function getOptionDescriptions() {
237 if ( array_key_exists( 'option-descriptions-messages', $this->mParams ) ) {
238 $needsParse = $this->mParams['option-descriptions-messages-parse'] ?? false;
239 $optionDescriptions = [];
240 foreach ( $this->mParams['option-descriptions-messages'] as $value => $msgKey ) {
241 $msg = $this->msg( $msgKey );
242 $optionDescriptions[$value] = $needsParse ? $msg->parse() : $msg->escaped();
243 }
244 return $optionDescriptions;
245 } elseif ( array_key_exists( 'option-descriptions', $this->mParams ) ) {
246 return $this->mParams['option-descriptions'];
247 }
248 }
249
251 protected function needsLabel() {
252 return false;
253 }
254
256 protected function shouldInfuseOOUI() {
257 // Avoid accessibility issues when the widget is infused (e.g. by hide-if) but the layout isn't (T396261)
258 return true;
259 }
260}
261
263class_alias( HTMLRadioField::class, 'HTMLRadioField' );
needsLabel()
Should this field have a label, or is there no input element with the appropriate id for the label to...
getInputHTML( $value)
This returns a block of all the radio options, in one cell.
getOptionDescriptions()
Fetch the array of option descriptions from the field's parameters.
shouldInfuseOOUI()
Whether the field should be automatically infused.Note that all OOUI HTMLForm fields are infusable (y...
getInputCodex( $value, $hasErrors)
Same as getInputHTML, but for Codex.This is called by CodexHTMLForm.If not overridden,...
getInputOOUI( $value)
Same as getInputHTML, but returns an OOUI object.Defaults to false, which getOOUI will interpret as "...
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.Don't forget to call pare...
The parent class to generate form fields.
makeLabelSnippet( $label)
The keys in the array returned by getOptions() can be either HTML or plain text depending on $this->m...
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.
getAttributes(array $list)
Returns the given attributes from the parameters.
msg( $key,... $params)
Get a translated interface message.
escapeLabel( $label)
The keys in the array returned by getOptions() can be either HTML or plain text depending on $this->m...
This class is a collection of static functions that serve two purposes:
Definition Html.php:43
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:32
element(SerializerNode $parent, SerializerNode $node, $contents)