Layout — building blocks for organizing your application as a tree of widgets

Dialogs

A dialog is a window used to communicate information to the user and/or prompt the user for a response. Use the class WDialog to show a dialog. A specialized dialog is also available to alert the user with a message then use the simple WMessageBox dialog.

By default, a WDialog is modal. A modal window blocks the user interface, and does not allow the user to interact with any other part of the user interface until the dialog is closed. With a modeless dialog the window can be left open while the user continues in another window of the application. Use setModal(false) to create a non-modal dialog. In the Message box section below you can find an example of a modeless window.

Unlike other widgets, a dialog does not need to be added to a parent widget, and it is hidden by default. You must use the method show() or setHidden(false) to show the dialog. The dialog may be closed by calling accept(), reject() or done() (or connecting a signal to one of these methods). This will hide the dialog and emit the finished() signal, which you then can listen for to process the dialog result and delete the dialog. Typically, an OK button will be connected to accept(), and in some cases a Cancel button to reject(). You can add content to the dialog by adding the content to its container. You can get the container with the contents() method.

Example
source
#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WDialog>
#include <Wt/WEnvironment>
#include <Wt/WLabel>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WRegExpValidator>
#include <Wt/WText>

namespace {

void showDialog(Wt::WText *out)
{
    Wt::WDialog *dialog = new Wt::WDialog("Go to cell");

    Wt::WLabel *label = new Wt::WLabel("Cell location (A1..Z999)",
				       dialog->contents());
    Wt::WLineEdit *edit = new Wt::WLineEdit(dialog->contents());
    label->setBuddy(edit);

    dialog->contents()->addStyleClass("form-group");

    Wt::WRegExpValidator *validator = 
        new Wt::WRegExpValidator("[A-Za-z][1-9][0-9]{0,2}");
    validator->setMandatory(true);
    edit->setValidator(validator);

    Wt::WPushButton *ok = new Wt::WPushButton("OK", dialog->footer());
    ok->setDefault(true);
    if (wApp->environment().ajax())
      ok->disable();

    Wt::WPushButton *cancel = new Wt::WPushButton("Cancel", dialog->footer());
    dialog->rejectWhenEscapePressed();

    edit->keyWentUp().connect(std::bind([=] () {
	ok->setDisabled(edit->validate() != Wt::WValidator::Valid);
    }));

    /*
     * Accept the dialog
     */
    ok->clicked().connect(std::bind([=] () {
	if (edit->validate())
	    dialog->accept();
    }));

    /*
     * Reject the dialog
     */
    cancel->clicked().connect(dialog, &Wt::WDialog::reject);

    /*
     * Process the dialog result.
     */
    dialog->finished().connect(std::bind([=] () {
	if (dialog->result() == Wt::WDialog::Accepted)
	    out->setText("New location: " + edit->text());
	else
	    out->setText("No location selected.");

	delete dialog;
    }));

    dialog->show();
}

}
Wt::WContainerWidget *container = new Wt::WContainerWidget();

Wt::WPushButton *button = new Wt::WPushButton("Jump", container);

Wt::WText *out = new Wt::WText(container);
out->setStyleClass("help-block");

button->clicked().connect(std::bind([=] () {
      showDialog(out);
}));

A modal dialog can be instantiated in two ways — synchronously or asynchronously — while a non-modal dialog can only be instantiated asynchronously. By preference instantiate a dialog asynchronously. The synchronous use of a dialog is what is commonly done in desktop applications to show a modal dialog, and involves a call to exec() that starts a local event loop, and returns only when the dialog is closed. The draw-back of synchronous use is that the application is not scalable to many concurrent sessions, since it blocks a thread. This means it is only suitable for applications with restricted access or applications that are deployed on an intranet or extranet. When using a dialog asynchronously, there is no API call that waits for the dialog to be closed. In this case, the usage is similar to instantiating any other widget.

Top

Message box

A message box is a simple dialog to alert the user with a message. It may require an acknowledgment that the message has been read (usually by clicking an "OK" button), or a decision as to whether or not an action should proceed (by clicking an "OK" or "Cancel" button).

The usage is similar to instantiating a WDialog (or any other widget). You need to connect to the buttonClicked signal with a method that interpretes the result and deletes the message box. You can get the resulting standard button with buttonResult().

The buttons of a WMessageBox may be standard or customized type of buttons. Customized buttons should be dealt with using the result() method from the parent WDialog. The strings used in standard buttons can be translated by overriding the default values of localization keys.

Example
source
#include <Wt/WContainerWidget>
#include <Wt/WMessageBox>
#include <Wt/WPushButton>
#include <Wt/WText>

Wt::WContainerWidget *container = new Wt::WContainerWidget();

Wt::WPushButton *button = new Wt::WPushButton("Status", container);

Wt::WText *out = new Wt::WText(container);
out->setMargin(10, Wt::Left);

button->clicked().connect(std::bind([=] () {
    out->setText("The status button is clicked.");

    Wt::WMessageBox *messageBox = new Wt::WMessageBox
	("Status",
	 "<p>Ready to launch the rocket...</p>"
	 "<p>Launch the rocket immediately?</p>",
	 Wt::Information, Wt::Yes | Wt::No);

    messageBox->setModal(false);

    messageBox->buttonClicked().connect(std::bind([=] () {
	if (messageBox->buttonResult() == Wt::Yes)
	    out->setText("The rocket is launched!");
	else
	    out->setText("The rocket is ready for launch...");

	delete messageBox;
    }));

    messageBox->show();
}));

The following example is much more compact but it has a big disadvantage because the messagebox is instantiated synchronously. The show() method is used statically; this involves the static use of the exec() method which blocks the current thread until the user has clicked a button and the result of the messagebox is processed. It is highly recommended to use a messagebox asynchronously because there is no API call that waits for the messagebox to be processed in that case.

Example
source
#include <Wt/WContainerWidget>
#include <Wt/WMessageBox>
#include <Wt/WPushButton>
#include <Wt/WText>

Wt::WContainerWidget *container = new Wt::WContainerWidget();

Wt::WPushButton *button = new Wt::WPushButton("Start", container);

Wt::WText *out = new Wt::WText(container);
out->setMargin(10, Wt::Left);

button->clicked().connect(std::bind([=] () {
    Wt::StandardButton answer 
      = Wt::WMessageBox::show("Launch phase",
			      "<p>Launch the rocket?</p>",
			      Wt::Ok | Wt::Cancel);
    if (answer == Wt::Ok)
        out->setText("The rocket is launched!");
    else
        out->setText("Waiting on your decision...");
}));

A WMessageBox can be styled using the Wt-dialog and Wt-outset style classes from it's superclass WDialog. Its buttons can be styled using the Wt-msgbox-buttons style class.

Top