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