MediaWiki master
HTMLAutoCompleteSelectField.php
Go to the documentation of this file.
1<?php
2
4
5use FormatJson;
6use InvalidArgumentException;
8use XmlSelect;
9
39 protected $autocompleteData = [];
40
45 public function __construct( $params ) {
46 $params += [
47 'require-match' => false,
48 ];
49
50 parent::__construct( $params );
51
52 if ( array_key_exists( 'autocomplete-data-messages', $this->mParams ) ) {
53 foreach ( $this->mParams['autocomplete-data-messages'] as $key => $value ) {
54 $key = $this->msg( $key )->plain();
55 $this->autocompleteData[$key] = strval( $value );
56 }
57 } elseif ( array_key_exists( 'autocomplete-data', $this->mParams ) ) {
58 foreach ( $this->mParams['autocomplete-data'] as $key => $value ) {
59 $this->autocompleteData[$key] = strval( $value );
60 }
61 }
62 if ( !is_array( $this->autocompleteData ) || !$this->autocompleteData ) {
63 throw new InvalidArgumentException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
64 }
65
66 $this->getOptions();
67 if ( $this->mOptions && !in_array( 'other', $this->mOptions, true ) ) {
68 if ( isset( $params['other-message'] ) ) {
69 $msg = $this->getMessage( $params['other-message'] )->text();
70 } elseif ( isset( $params['other'] ) ) {
71 $msg = $params['other'];
72 } else {
73 $msg = wfMessage( 'htmlform-selectorother-other' )->text();
74 }
75 $this->mOptions[$msg] = 'other';
76 }
77 }
78
79 public function loadDataFromRequest( $request ) {
80 if ( $request->getCheck( $this->mName ) ) {
81 $val = $request->getText( $this->mName . '-select', 'other' );
82
83 if ( $val === 'other' ) {
84 $val = $request->getText( $this->mName );
85 if ( isset( $this->autocompleteData[$val] ) ) {
86 $val = $this->autocompleteData[$val];
87 }
88 }
89
90 return $val;
91 } else {
92 return $this->getDefault();
93 }
94 }
95
96 public function validate( $value, $alldata ) {
97 $p = parent::validate( $value, $alldata );
98
99 if ( $p !== true ) {
100 return $p;
101 }
102
103 $validOptions = HTMLFormField::flattenOptions( $this->getOptions() ?: [] );
104
105 if (
106 in_array( strval( $value ), $validOptions, true ) ||
107 in_array( strval( $value ), $this->autocompleteData, true )
108 ) {
109 return true;
110 } elseif ( $this->mParams['require-match'] ) {
111 return $this->msg( 'htmlform-select-badoption' );
112 }
113
114 return true;
115 }
116
117 // FIXME Ewww, this shouldn't be adding any attributes not requested in $list :(
118 public function getAttributes( array $list ) {
119 $attribs = [
120 'type' => 'text',
121 'data-autocomplete' => FormatJson::encode( array_keys( $this->autocompleteData ) ),
122 ] + parent::getAttributes( $list );
123
124 if ( $this->getOptions() ) {
125 $attribs['data-cond-state'] = FormatJson::encode( [
126 'hide' => [ '!==', $this->mName . '-select', 'other' ],
127 ] );
128 }
129
130 return $attribs;
131 }
132
133 public function getInputHTML( $value ) {
134 $oldClass = $this->mClass;
135 $classes = (array)$this->mClass;
136
137 $valInSelect = false;
138 $ret = '';
139
140 if ( $this->getOptions() ) {
141 if ( $value !== false ) {
142 $value = strval( $value );
143 $valInSelect = in_array(
144 $value, HTMLFormField::flattenOptions( $this->getOptions() ), true
145 );
146 }
147
148 $selected = $valInSelect ? $value : 'other';
149 $select = new XmlSelect( $this->mName . '-select', $this->mID . '-select', $selected );
150 $select->addOptions( $this->getOptions() );
151
152 if ( !empty( $this->mParams['disabled'] ) ) {
153 $select->setAttribute( 'disabled', 'disabled' );
154 }
155
156 if ( isset( $this->mParams['tabindex'] ) ) {
157 $select->setAttribute( 'tabindex', $this->mParams['tabindex'] );
158 }
159
160 $ret = $select->getHTML() . "<br />\n";
161
162 $classes[] = 'mw-htmlform-hide-if';
163 }
164
165 if ( $valInSelect ) {
166 $value = '';
167 } else {
168 $key = array_search( strval( $value ), $this->autocompleteData, true );
169 if ( $key !== false ) {
170 $value = $key;
171 }
172 }
173
174 $classes[] = 'mw-htmlform-autocomplete';
175 $this->mClass = implode( ' ', $classes );
176 $ret .= parent::getInputHTML( $valInSelect ? '' : $value );
177 $this->mClass = $oldClass;
178
179 return $ret;
180 }
181
187 public function getInputOOUI( $value ) {
188 // To be implemented, for now override the function from HTMLTextField
189 return false;
190 }
191}
192
194class_alias( HTMLAutoCompleteSelectField::class, 'HTMLAutoCompleteSelectField' );
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
JSON formatter wrapper class.
Text field for selecting a value from a large list of possible values, with auto-completion and optio...
loadDataFromRequest( $request)
Get the value that this input has been set to from a posted form, or the input's default value if it ...
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.
getAttributes(array $list)
Returns the given attributes from the parameters.
getInputOOUI( $value)
Get the OOUI version of this input.
getInputHTML( $value)
This function must be implemented to return the HTML to generate the input object itself....
The parent class to generate form fields.
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.
msg( $key,... $params)
Get a translated interface message.
Class for generating HTML <select> or <datalist> elements.
Definition XmlSelect.php:28