Introduction

There are two ways in which you can compose a form:

Simple form

You can create a simple form by using one or more input widgets like WLineEdit in addition to a WPushButton to process the input. You can add Validation to filter the user's input (See also the menu Validation).

Example
source
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>

auto result =
    std::make_unique<Wt::WTemplate>(Wt::WString::tr("simpleForm-template"));

auto name = result->bindWidget("name", std::make_unique<Wt::WLineEdit>());
name->setPlaceholderText("first name");

auto button = result->bindWidget("button", std::make_unique<Wt::WPushButton>("OK"));

auto out = result->bindWidget("out", std::make_unique<Wt::WText>());

button->clicked().connect([=] {
    out->setText("Hello, " + name->text() + "! I just want to help you... You"
                 + " could complete this simple form by adding validation.");
});

Here is the corresponding XML template (with message id="simpleForm-template") using style classes from the Bootstrap theme. In order to apply validation style to any widget with invalid input, you should group the widgets in a div or span section and apply the style input-group to it.

source
<div class="row">
<div class="col-auto pe-0">
${name}
</div>
<div class="col-auto">
${button}
</div>
<div class="col-auto">
${out class='form-control-plaintext'}
</div>
</div>

Top

Model/view concept

It is more convenient to create a form using a model/view concept. The model is a specialisation of WFormModel while the complementary template-based view class is a specialisation of WTemplateFormView. The main advantage is that forms based on this concept are structured in a uniform way.

The form model implements field data and validation handling for (simple) form-based views. It provides a standard way for views to perform field validation, and react to validation results. Each field has a string literal assigned to it. The string literal uniquely identifies the field. For each field, its value, the visibility, whether the field is read-only, and its current validation status is managed by the model. In addition, you will typically specialize the class to customize the validation and application logic. Although it can be setup to use WValidator objects for individual fields, you could also create a validator to simultaneously validate interdependent fields.

A model is typically used by a view (WTemplateFormView) which renders the fields configured in the model, updates the model values, invokes and reflects the validation status. For each model field, the view uses a number of conventional variable names to represent the label, editor, and validation messages in the template:

field
This variable name refers to the form widget which contains the value. It is used by createFormWidget() at the moment that the form is created.
field-label
This variable name refers to the label. It is used by label().
field-info
This variable name refers to details on the field. This could be input advice (e.g. the format or the range) or a validation message. It is used by addField() and validate().
if:field
This variable name refers to a condition for the visibility of the field. It is used by isVisible().

For a field with the name 'field', a typical template contains a block in the following format:

source
${<if:field>}
<label class="form-label" for="${id:field}">${field-label}</label>
${field} ${field-info}
${</if:field>}

The view can update the form using several methods. The updateView() method updates the view based on a model (e.g. to propagate changed values or validation), while the updateModel() method updates a model with values entered in the view. The view doesn't have to render all fields of a model. You can call updateViewField() and updateModelField() to update individual model fields.

The view is passive. It will not perform any updates by itself if either the view or model has changed. To update the form, each view method uses a service method from the model; either setValue() to update the model or value() to update the view. You will typically bind a method to a button in order to process the form (i.e. update and validate the model).

model-view picture

The view may render fields of more than one model. Note that there are still other models like WStandardItemModel which can be used to represent tables, trees and tree tables.

The form below is composed of input fields which are implemented with different controls like a line edit, a combo box, a date picker, a spin box, a text area. The push button at the end is used to start the validation of the values in the input fields.

Example
Create new user

This menu continues with controls (widgets) which you can use to assemble a form. At the end the above form is explained in detail with the source code.

Top