Wt provides different kinds of text entry widgets:
WLineEdit
,
WTextArea
,
WTextEdit
and
WSpinBox
.
The WLineEdit class is an inline widget that provides a single line edit.
A <WLineEdit>
corresponds to an HTML
<input type="text">
element.
You can restrict its input using a validator providing immediate client-side feedback. In the example below characters that aren't numbers are not accepted. If you enter a number out of the predefined range (0..130) then the widget colour is changed. See Forms > Validation for more details.
The line edit below reacts on every 'key pressed' event. It also shows how you can embed the label within the control (when empty).
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WText.h>
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WLineEdit *edit = container->addNew<Wt::WLineEdit>();
edit->setPlaceholderText("Edit me");
Wt::WText *out = container->addNew<Wt::WText>("");
out->addStyleClass("help-block");
edit->keyPressed().connect([=] (const Wt::WKeyEvent& e) {
out->setText("You pressed the '" + e.text() + "' key.");
});
WTextArea is an inline widget that provides a multi-line edit.
A WTextArea
corresponds to an HTML <textarea>
element.
Form validators can be used to validate the user's input with immediate client-side feedback.
#include <Wt/WContainerWidget.h>
#include <Wt/WText.h>
#include <Wt/WTextArea.h>
#include <Wt/WDateTime.h>
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WTextArea *ta =
container->addNew<Wt::WTextArea>();
ta->setColumns(80);
ta->setRows(5);
ta->setText("Change this text... \n"
"and click outside the text area to get a changed event.");
Wt::WText *out = container->addNew<Wt::WText>("<p></p>");
out->addStyleClass("help-block");
ta->changed().connect([=] {
out->setText("<p>Text area changed at " +
Wt::WDateTime::currentDateTime().toString() + ".</p>");
});
WTextEdit is a full-featured editor for rich text editing. It is based on the TinyMCE editor, which must be downloaded separately from its author's website. The TinyMCE toolbar layout and plugins can be configured through Wt's interface. The default layout - as shown below - covers only a small portion of TinyMCE's capabilities.
#include <Wt/Utils.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>
#include <Wt/WTextEdit.h>
using namespace Wt;
auto container = std::make_unique<Wt::WContainerWidget>();
Wt::WTextEdit *edit = container->addNew<Wt::WTextEdit>();
edit->setHeight(300);
edit->setText("<p>"
"<span style=\"font-family: 'courier new', courier; font-size: medium;\">"
"<strong>WTextEdit</strong></span></p>"
"<p>Hey, I'm a <strong>WTextEdit</strong> and you can make me"
" <span style=\"text-decoration: underline;\"><em>rich</em></span>"
" by adding your <span style=\"color: #ff0000;\"><em>style</em>"
"</span>!</p>"
"<p>Other widgets like...</p>"
"<ul style=\"padding: 0px; margin: 0px 0px 10px 25px;\">"
"<li>WLineEdit</li>"
"<li>WTextArea</li>"
"<li>WSpinBox</li>"
"</ul>"
"<p>don't have style.</p>");
Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Get text");
button->setMargin(10, Wt::Side::Top | Wt::Side::Bottom);
Wt::WText *out = container->addNew<Wt::WText>();
out->setStyleClass("xhtml-output");
button->clicked().connect([=] {
out->setText("<pre>" + Wt::Utils::htmlEncode(edit->text()) + "</pre>");
});
You could also render the XHTML text to pdf using the WPdfRenderer class. See Media > Pdf output for more details.
A spin box is an inline widget to enter a number; WSpinBox is an input control for integer numbers, while WDoubleSpinBox is an input control for fixed point numbers. A spin box consists of a line edit, and buttons which allow to increase or decrease the value.
#include <Wt/WContainerWidget.h>
#include <Wt/WDoubleSpinBox.h>
#include <Wt/WLabel.h>
#include <Wt/WText.h>
auto container = std::make_unique<Wt::WContainerWidget>();
container->addStyleClass("form-group");
Wt::WLabel *label = container->addNew<Wt::WLabel>("Enter a number (0 - 100):");
Wt::WDoubleSpinBox *sb = container->addNew<Wt::WDoubleSpinBox>();
sb->setRange(0,100);
sb->setValue(50);
sb->setDecimals(2);
sb->setSingleStep(0.1);
label->setBuddy(sb);
Wt::WText *out = container->addNew<Wt::WText>("");
out->addStyleClass("help-block");
sb->changed().connect([=] {
if (sb->validate() == Wt::ValidationState::Valid) {
out->setText(Wt::WString("Spin box value changed to {1}")
.arg(sb->text()));
} else {
out->setText(Wt::WString("Invalid spin box value!"));
}
});
A user may be steered to providing correct input by providing an input mask. The input mask indicates the expected format and constrains the user to provide data only in the expected format.
In the example below we use an input mask to ask the user to enter an IP address.
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WTemplate.h>
auto result =
std::make_unique<Wt::WTemplate>(Wt::WString::tr("lineEdit-template"));
result->addFunction("id", &Wt::WTemplate::Functions::id);
auto edit = std::make_unique<Wt::WLineEdit>();
edit->setTextSize(15);
edit->setInputMask("009.009.009.009;_");
result->bindString("label", "IP Address:");
result->bindWidget("edit", std::move(edit));
WEmailEdit can be used if the user needs to enter an email
address. A WEmailValidator will automatically be associated,
which will validate the email address according to the WHATWG specification
for <input type="email">
.
In the example below, pressing "Submit" will validate the entered input. You can allow multiple email addresses by checking "Allow multiple" and verify that the email address matches a certain pattern by checking the "Use pattern" checkbox.
#include <Wt/WCheckBox.h>
#include <Wt/WEmailEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
auto result = std::make_unique<Wt::WTemplate>(Wt::WString::tr("emailEdit-template"));
auto tpl = result.get();
tpl->addFunction("id", &Wt::WTemplate::Functions::id);
tpl->bindString("label", "Email address: ", Wt::TextFormat::Plain);
auto edit = tpl->bindNew<Wt::WEmailEdit>("edit");
auto submit = tpl->bindNew<Wt::WPushButton>("submit", "Submit");
auto multiple = tpl->bindNew<Wt::WCheckBox>("multiple", "Allow multiple");
multiple->changed().connect([=]() {
edit->setMultiple(multiple->isChecked());
});
auto pattern = tpl->bindNew<Wt::WCheckBox>("pattern", "Use pattern '.*@example[.]com'");
pattern->changed().connect([=]() {
edit->setPattern(pattern->isChecked() ? ".*@example[.]com" : "");
});
tpl->bindEmpty("edit-info");
edit->validated().connect([=](const Wt::WValidator::Result& validationResult) {
tpl->bindString("edit-info", validationResult.message());
});
submit->clicked().connect([=]() {
edit->setMultiple(multiple->isChecked());
edit->setPattern(pattern->isChecked() ? ".*@example[.]com" : "");
edit->validate();
tpl->bindString("output", Wt::WString("Entered email address: {1}").arg(edit->valueText()), Wt::TextFormat::Plain);
});
tpl->bindEmpty("output");
Here is the corresponding XML template (with
message id="emailEdit-template"
) using style classes from the
Bootstrap theme.
<div class="row">
<div class="col-xs-12 col-md-6 col-xl-4">
<label class="form-label" for="${id:edit}">${label}</label>
<div class="input-group">
${edit}
${submit class="btn-outline-secondary"}
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-text">
${edit-info}
</div>
</div>
</div>
<div class="row">
<div class="col">
${multiple} ${pattern}
</div>
</div>
<div class="row">
<div class="col">
${output}
</div>
</div>
Adding on top of the standard input controls, the
Bootstrap theme
includes other useful form components
like prepended/appended inputs. You can add text or buttons before and/or
after any text-based input using the .input-group-text
class. Note
that select elements are not supported.
Wrap an .input-group-text
and an input control with the
.input-group
class to prepend or append text to an input.
To prepend and append an input at once you can also use two instances
of the .input-group-text
before and after the input control.
#include <Wt/WLineEdit.h>
#include <Wt/WTemplate.h>
auto result =
std::make_unique<Wt::WTemplate>(Wt::WString::tr("editSide-template"));
auto edit =
std::make_unique<Wt::WLineEdit>("Username");
edit->setStyleClass("span2");
result->bindWidget("name", std::move(edit));
edit =
std::make_unique<Wt::WLineEdit>();
edit->setStyleClass("span2");
result->bindWidget("amount1", std::move(edit));
edit =
std::make_unique<Wt::WLineEdit>();
edit->setStyleClass("span2");
result->bindWidget("amount2", std::move(edit));
Here is the corresponding XML template (with
message id="editSide-template"
) using style classes from
the Bootstrap theme.
<div class="input-group mb-3">
<span class="input-group-text">@</span>
${name}
</div>
<div class="input-group mb-3">
${amount1}
<span class="input-group-text">.00</span>
</div>
<div class="input-group mb-3">
<span class="input-group-text">$</span>
${amount2}
<span class="input-group-text">.00</span>
</div>
See Push buttons.