/src/wt/src/Wt/WLineEdit.h
Line | Count | Source |
1 | | // This may look like C code, but it's really -*- C++ -*- |
2 | | /* |
3 | | * Copyright (C) 2008 Emweb bv, Herent, Belgium. |
4 | | * |
5 | | * See the LICENSE file for terms of use. |
6 | | */ |
7 | | #ifndef WLINEEDIT_H_ |
8 | | #define WLINEEDIT_H_ |
9 | | |
10 | | #include <Wt/WFormWidget.h> |
11 | | |
12 | | namespace Wt { |
13 | | |
14 | | /*! \brief Enumeration that describes how the contents is displayed. |
15 | | * |
16 | | * \sa setEchoMode(EchoMode) |
17 | | */ |
18 | | enum class EchoMode { |
19 | | Normal, //!< Characters are shown. |
20 | | Password //!< Hide the contents as for a password. |
21 | | }; |
22 | | |
23 | | /*! \brief Enumeration that describes options for input masks. |
24 | | * |
25 | | * \sa setInputMask() |
26 | | */ |
27 | | enum class InputMaskFlag { |
28 | | KeepMaskWhileBlurred = 0x1 //!< Keep the input mask when blurred |
29 | | }; |
30 | | |
31 | | /*! \brief Enumeration that describes different autocomplete modes. |
32 | | * |
33 | | * The autocomplete mode tells the browser what type of information is |
34 | | * required by the field. This helps the browser to complete the field |
35 | | * for the user. |
36 | | * |
37 | | * \sa setAutoComplete(AutoCompleteMode) |
38 | | */ |
39 | | enum class AutoCompleteMode { |
40 | | Off, //!< Forbid the browser to automatically enter or select values. \note In most modern browsers, this will not stop password manager to do it. |
41 | | On, //!< The browser will "guess" what type of data is required. |
42 | | NewPassword, //!< A new password. This should be used with field for entering a new password or confirming the new password. |
43 | | CurrentPassword, //!< The current password of the user. |
44 | | Username //!< An accout name or username. |
45 | | }; |
46 | | |
47 | | /*! \brief Enumeration that describes different input modes. |
48 | | * |
49 | | * The input mode tells the browser what layout should be used for a |
50 | | * virtual keybord when editing this field. This mainly impacts phone |
51 | | * users. |
52 | | * |
53 | | * \sa setInputMode(InputMode) |
54 | | */ |
55 | | enum class InputMode { |
56 | | Off, //!< Does not specify any input mode to the browser |
57 | | None, //!< No virtual keyboard should be displayed. |
58 | | Text, //!< The locale-specific standard virtual keyboard. |
59 | | Tel, //!< A numeric virtual keyboard wich also have "#"" and "*". |
60 | | Url, //!< Ensure that the virtual keyboard has "/" |
61 | | Email, //!< Ensure that the virtual keyboard has "@" |
62 | | Numeric, //!< Ensure that the virtual keyboard has the digit from 0 to 9. Does usually show only the numbers with maybe also "-" . |
63 | | Decimal, //!< Like Numeric + ensure that the virtual keyboard has the decimal separator. |
64 | | Search //!< A virtual keyboard convenient for search |
65 | | }; |
66 | | |
67 | | /*! \class WLineEdit Wt/WLineEdit.h Wt/WLineEdit.h |
68 | | * \brief A widget that provides a single line edit. |
69 | | * |
70 | | * To act upon text changes, connect a slot to the changed() |
71 | | * signal. This signal is emitted when the user changed the content, |
72 | | * and subsequently removes the focus from the line edit. |
73 | | * |
74 | | * To act upon editing, connect a slot to the keyWentUp() signal because the |
75 | | * keyPressed() signal is fired before the line edit has interpreted the |
76 | | * keypress to change its text. |
77 | | * |
78 | | * At all times, the current content may be accessed with the text() |
79 | | * method. |
80 | | * |
81 | | * You may specify a maximum length for the input using |
82 | | * setMaxLength(). If you wish to provide more detailed input |
83 | | * validation, you may set a validator using the |
84 | | * setValidator(const std::shared_ptr<WValidator> &) method. Validators provide, in general, |
85 | | * both client-side validation (as visual feed-back only) and |
86 | | * server-side validation when calling validate(). |
87 | | * |
88 | | * \if cpp |
89 | | * Usage example: |
90 | | * \code |
91 | | * auto w = std::make_unique<Wt::WContainerWidget>(); |
92 | | * Wt::WLabel *label = w->addWidget(std::make_unique<Wt::WLabel>("Age:")); |
93 | | * Wt::WLineEdit *edit = w->addWidget(std::make_unique<Wt::WLineEdit>("13")); |
94 | | * edit->setValidator(std::make_shared<Wt::WIntValidator>(0, 200)); |
95 | | * label->setBuddy(edit); |
96 | | * \endcode |
97 | | * \endif |
98 | | * |
99 | | * The widget corresponds to the HTML <tt><input type="text"></tt> or |
100 | | * <tt><input type="password"></tt> tag. |
101 | | * |
102 | | * %WLineEdit is an \link WWidget::setInline(bool) inline \endlink widget. |
103 | | * |
104 | | * <h3>CSS</h3> |
105 | | * |
106 | | * The emptyText style can be configured via .Wt-edit-emptyText, |
107 | | * other styling can be done using inline or external CSS as appropriate. |
108 | | * |
109 | | * \sa WTextArea |
110 | | */ |
111 | | class WT_API WLineEdit : public WFormWidget |
112 | | { |
113 | | public: |
114 | | /*! \brief Creates a line edit with empty content. |
115 | | */ |
116 | | WLineEdit(); |
117 | | |
118 | | /*! \brief Creates a line edit with given content. |
119 | | */ |
120 | | WLineEdit(const WT_USTRING& content); |
121 | | |
122 | | /*! \brief Specifies the width of the line edit in number of characters. |
123 | | * |
124 | | * This specifies the width of the line edit that is roughly |
125 | | * equivalent with \p chars characters. This does not limit the |
126 | | * maximum length of a string that may be entered, which may be set |
127 | | * using setMaxLength(int). |
128 | | * |
129 | | * The default value is 10. |
130 | | */ |
131 | | void setTextSize(int chars); |
132 | | |
133 | | /*! \brief Returns the current width of the line edit in number of characters. |
134 | | * |
135 | | * \sa setTextSize(int) |
136 | | */ |
137 | 0 | int textSize() const { return textSize_; } |
138 | | |
139 | | /*! \brief Sets the content of the line edit. |
140 | | * |
141 | | * The default value is "". |
142 | | * |
143 | | * \sa text() |
144 | | */ |
145 | | virtual void setText(const WT_USTRING& text); |
146 | | |
147 | | /*! \brief Returns the current content. |
148 | | * |
149 | | * \sa setText() |
150 | | */ |
151 | 0 | const WT_USTRING& text() const { return content_; } |
152 | | |
153 | | /*! \brief Returns the displayed text. |
154 | | * |
155 | | * If echoMode() is set to Normal, and no input mask is defined, this returns the same as |
156 | | * text(). |
157 | | * |
158 | | * If an input mask is defined, then the text is returned including space characters. |
159 | | * |
160 | | * If echoMode() is set to Password, then a string of asterisks is returned equal to the length |
161 | | * of the text. |
162 | | * |
163 | | * \sa setText() |
164 | | */ |
165 | | WT_USTRING displayText() const; |
166 | | |
167 | | /*! \brief Specifies the maximum length of text that can be entered. |
168 | | * |
169 | | * A value <= 0 indicates that there is no limit. |
170 | | * |
171 | | * The default value is -1. |
172 | | */ |
173 | | virtual void setMaxLength(int length); |
174 | | |
175 | | /*! \brief Returns the maximum length of text that can be entered. |
176 | | * |
177 | | * \sa setMaxLength(int) |
178 | | */ |
179 | 0 | int maxLength() const { return maxLength_; } |
180 | | |
181 | | /*! \brief Sets the echo mode. |
182 | | * |
183 | | * The default echo mode is Normal. |
184 | | * |
185 | | * \deprecated For EchoMode::Password, use WPasswordEdit instead. |
186 | | */ |
187 | | WT_DEPRECATED("For EchoMode::Password, use WPasswordEdit instead.") |
188 | | void setEchoMode(EchoMode echoMode); |
189 | | |
190 | | /*! \brief Returns the echo mode. |
191 | | * |
192 | | * \deprecated For EchoMode::Password, use WPasswordEdit instead. |
193 | | * |
194 | | * \sa setEchoMode(EchoMode) |
195 | | */ |
196 | | WT_DEPRECATED("For EchoMode::Password, use WPasswordEdit instead.") |
197 | 0 | EchoMode echoMode() const { return echoMode_; } |
198 | | |
199 | | /*! \brief Sets (built-in browser) autocomplete support. |
200 | | * |
201 | | * Depending on the user agent, this may assist the user in filling in |
202 | | * text for common input fields (e.g. address information) based on |
203 | | * some heuristics. |
204 | | * |
205 | | * The default value is \c true. |
206 | | */ |
207 | | void setAutoComplete(bool enabled); |
208 | | |
209 | | /*! \brief Sets (built-in browser) autocomplete support. |
210 | | * |
211 | | * Depending on the user agent, this may assist the user in filling in |
212 | | * text for common input fields (e.g. address information) based on |
213 | | * some heuristics. |
214 | | * |
215 | | * The default value is AutoCompleteMode::On. |
216 | | */ |
217 | | void setAutoComplete(AutoCompleteMode token); |
218 | | |
219 | | /*! \brief Returns if auto-completion support is not off. |
220 | | * |
221 | | * \sa setAutoComplete() |
222 | | */ |
223 | 0 | bool autoComplete() const { return autoComplete_ != AutoCompleteMode::Off; } |
224 | | |
225 | | /*! \brief Returns auto-completion support. |
226 | | * |
227 | | * \sa setAutoComplete() |
228 | | */ |
229 | 0 | AutoCompleteMode autoCompleteToken() const { return autoComplete_; } |
230 | | |
231 | | /*! \brief Sets (built-in browser) input mode support. |
232 | | * |
233 | | * The input mode suggest what type of virtual keyboard should |
234 | | * be used when applicable (mainly for phone users). |
235 | | * |
236 | | * When InputMode::Off is used, the inputmode field is not specified. |
237 | | * Not to be confused with InputMode::None, which suggest the browser to |
238 | | * not use any virtual keybord. |
239 | | * |
240 | | * The default value is InputMode::Off. |
241 | | */ |
242 | | void setInputMode(InputMode mode); |
243 | | |
244 | | /*! \brief Returns inputMode support. |
245 | | * |
246 | | * \sa setInputMode() |
247 | | */ |
248 | 0 | InputMode inputMode() const { return inputMode_; } |
249 | | |
250 | | /*! \brief Returns the current selection start. |
251 | | * |
252 | | * Returns -1 if there is no selected text. |
253 | | * |
254 | | * \sa hasSelectedText(), selectedText() |
255 | | */ |
256 | | int selectionStart() const; |
257 | | |
258 | | /*! \brief Returns the currently selected text. |
259 | | * |
260 | | * Returns an empty string if there is currently no selected text. |
261 | | * |
262 | | * \sa hasSelectedText() |
263 | | */ |
264 | | WT_USTRING selectedText() const; |
265 | | |
266 | | /*! \brief Returns whether there is selected text. |
267 | | * |
268 | | * \sa selectedtext() |
269 | | */ |
270 | | bool hasSelectedText() const; |
271 | | |
272 | | /*! \brief Selects length characters starting from the start position |
273 | | * |
274 | | * \sa selectedtext() |
275 | | */ |
276 | | void setSelection(int start, int length); |
277 | | |
278 | | /*! \brief Returns the current cursor position. |
279 | | * |
280 | | * Returns -1 if the widget does not have the focus. |
281 | | */ |
282 | | int cursorPosition() const; |
283 | | |
284 | | /*! \brief Returns the current value. |
285 | | * |
286 | | * Returns text(). |
287 | | */ |
288 | | virtual WT_USTRING valueText() const override; |
289 | | |
290 | | /*! \brief Sets the current value. |
291 | | * |
292 | | * Calls setText(). |
293 | | */ |
294 | | virtual void setValueText(const WT_USTRING& value) override; |
295 | | |
296 | | /*! \brief Returns the input mask. |
297 | | * |
298 | | * \sa setInputMask() |
299 | | */ |
300 | | WT_USTRING inputMask() const; |
301 | | |
302 | | /*! \brief Sets the input mask. |
303 | | * |
304 | | * If no input mask is supplied, or the given input mask |
305 | | * is empty, no input mask is applied. |
306 | | * |
307 | | * The following characters can be used in the input mask: |
308 | | * <table> |
309 | | * <tr><th>Character</th> <th>Description</th></tr> |
310 | | * <tr><td>A</td> |
311 | | * <td>ASCII alphabetic character: A-Z, a-z (required)</td></tr> |
312 | | * <tr><td>a</td> |
313 | | * <td>ASCII alphabetic character: A-Z, a-z (optional)</td></tr> |
314 | | * <tr><td>N</td> |
315 | | * <td>ASCII alphanumeric character: A-Z, a-z, 0-9 (required)</td></tr> |
316 | | * <tr><td>n</td> |
317 | | * <td>ASCII alphanumeric character: A-Z, a-z, 0-9 (optional)</td></tr> |
318 | | * <tr><td>X</td><td>Any character (required)</td></tr> |
319 | | * <tr><td>x</td><td>Any character (optional)</td></tr> |
320 | | * <tr><td>9</td><td>Digit: 0-9 (required)</td></tr> |
321 | | * <tr><td>0</td><td>Digit: 0-9 (optional)</td></tr> |
322 | | * <tr><td>D</td><td>Nonzero digit: 1-9 (required)</td></tr> |
323 | | * <tr><td>d</td><td>Nonzero digit: 1-9 (optional)</td></tr> |
324 | | * <tr><td>#</td><td>Digit or sign: 0-9, -, + (required)</td></tr> |
325 | | * <tr><td>H</td> |
326 | | * <td>Hexadecimal character: A-F, a-f, 0-9 (required)</td></tr> |
327 | | * <tr><td>h</td> |
328 | | * <td>Hexadecimal character: A-F, a-f, 0-9 (optional)</td></tr> |
329 | | * <tr><td>B</td><td>Binary digit: 0-1 (required)</td></tr> |
330 | | * <tr><td>b</td><td>Binary digit: 0-1 (optional)</td></tr> |
331 | | * </table> |
332 | | * The distinction between required and optional characters won't be |
333 | | * apparent on the client side, but will affect the result of validate(). |
334 | | * |
335 | | * There are also a few special characters, that won't be checked against, |
336 | | * but modify the value in some way: |
337 | | * <table> |
338 | | * <tr><th>Character</th><th>Description</th></tr> |
339 | | * <tr><td>></td><td>The following characters are uppercased</td></tr> |
340 | | * <tr><td><</td><td>The following characters are lowercased</td></tr> |
341 | | * <tr><td>!</td> |
342 | | * <td>The casing of the following characters remains the same</td></tr> |
343 | | * </table> |
344 | | * A backslash ('\\') can be used to escape any of the mask characters |
345 | | * or modifiers, so that they can be used verbatim in the input mask. |
346 | | * |
347 | | * If the mask ends with a semicolon (';') followed by a character, |
348 | | * this character will be used on the client side to display spaces. |
349 | | * This defaults to the space (' ') character. The space character will be |
350 | | * removed from the value of this %WLineEdit. |
351 | | * |
352 | | * Examples: |
353 | | * <table> |
354 | | * <tr><th>Input mask</th><th>Notes</th></tr> |
355 | | * <tr><td><pre>009.009.009.009;_</pre></td> |
356 | | * <td>IP address. Spaces are denoted by '_'. Will validate if there |
357 | | * is at least one digit per segment.</td></tr> |
358 | | * <tr><td><pre>9999-99-99</pre></td> |
359 | | * <td>Date, in yyyy-MM-dd notation. Spaces are denoted by ' '. |
360 | | * Will validate if all digits are filled in.</td></tr> |
361 | | * <tr><td><pre>>HH:HH:HH:HH:HH:HH;_</pre></td> |
362 | | * <td>MAC address. Spaces are denoted by '_'. Will validate if all |
363 | | * hexadecimal characters are filled in. All characters will be |
364 | | * formatted in uppercase.</td></tr> |
365 | | * </table> |
366 | | * |
367 | | * Input masks are enforced by JavaScript on the client side. |
368 | | * Without JavaScript or using setText(), however, non-compliant |
369 | | * strings can be entered. This does not result in an error: any |
370 | | * non-compliant characters will be removed from the input and this |
371 | | * action will be logged. |
372 | | */ |
373 | | void setInputMask(const WT_USTRING &mask = "", |
374 | | WFlags<InputMaskFlag> flags = None); |
375 | | |
376 | | virtual ValidationState validate() override; |
377 | | |
378 | | /*! \brief Event signal emitted when the text in the input field changed. |
379 | | * |
380 | | * This signal is emitted whenever the text contents has |
381 | | * changed. Unlike the changed() signal, the signal is fired on |
382 | | * every change, not only when the focus is lost. Unlike the |
383 | | * keyPressed() signal, this signal is fired also for other events |
384 | | * that change the text, such as paste actions. |
385 | | * |
386 | | * \sa keyPressed(), changed() |
387 | | */ |
388 | | EventSignal<>& textInput(); |
389 | | |
390 | | private: |
391 | | static const char *INPUT_SIGNAL; |
392 | | |
393 | | WT_USTRING content_; |
394 | | WT_USTRING displayContent_; |
395 | | int textSize_; |
396 | | int maxLength_; |
397 | | EchoMode echoMode_; |
398 | | AutoCompleteMode autoComplete_; |
399 | | InputMode inputMode_; |
400 | | |
401 | | static const int BIT_CONTENT_CHANGED = 0; |
402 | | static const int BIT_TEXT_SIZE_CHANGED = 1; |
403 | | static const int BIT_MAX_LENGTH_CHANGED = 2; |
404 | | static const int BIT_ECHO_MODE_CHANGED = 3; |
405 | | static const int BIT_AUTOCOMPLETE_CHANGED = 4; |
406 | | static const int BIT_INPUT_MODE_CHANGED = 5; |
407 | | |
408 | | std::bitset<6> flags_; |
409 | | |
410 | | static const std::string SKIPPABLE_MASK_CHARS; |
411 | | |
412 | | bool maskChanged_; |
413 | | std::string mask_; |
414 | | #if !defined(WT_TARGET_JAVA) |
415 | | std::u32string inputMask_; |
416 | | std::u32string raw_; |
417 | | char32_t spaceChar_; |
418 | | #else |
419 | | std::string inputMask_; |
420 | | std::string raw_; |
421 | | char spaceChar_; |
422 | | #endif |
423 | | WFlags<InputMaskFlag> inputMaskFlags_; |
424 | | std::string case_; |
425 | | bool javaScriptDefined_; |
426 | | |
427 | | WT_USTRING removeSpaces(const WT_USTRING& text) const; |
428 | | WT_USTRING inputText(const WT_USTRING& text) const; |
429 | | void processInputMask(); |
430 | | #if !defined(WT_TARGET_JAVA) |
431 | | bool acceptChar(char32_t chr, size_t position) const; |
432 | | #else |
433 | | bool acceptChar(char chr, size_t position) const; |
434 | | #endif |
435 | | void defineJavaScript(); |
436 | | void connectJavaScript(Wt::EventSignalBase&s, const std::string& methodName); |
437 | | bool validateInputMask() const; |
438 | | |
439 | | protected: |
440 | | virtual void updateDom(DomElement& element, bool all) override; |
441 | | virtual DomElementType domElementType() const override; |
442 | | virtual void propagateRenderOk(bool deep) override; |
443 | | virtual void getDomChanges(std::vector<DomElement *>& result, |
444 | | WApplication *app) override; |
445 | | virtual void setFormData(const FormData& formData) override; |
446 | | |
447 | | virtual int boxPadding(Orientation orientation) const override; |
448 | | virtual int boxBorder(Orientation orientation) const override; |
449 | | |
450 | | virtual void render(WFlags<RenderFlag> flags) override; |
451 | | /*! \internal |
452 | | * \brief Returns the value of the type attribute for the <input> element |
453 | | * |
454 | | * For WLineEdit this is normally "text" or "password", but this can be overridden by |
455 | | * derived classes, e.g. for a native WTimeEdit this would be "time". |
456 | | */ |
457 | | WT_NODISCARD virtual std::string type() const noexcept; |
458 | | }; |
459 | | |
460 | | } |
461 | | |
462 | | #endif // WLINEEDIT_H_ |