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.h>
#include <Wt/WBreak.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WDialog.h>
#include <Wt/WEnvironment.h>
#include <Wt/WLabel.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WRegExpValidator.h>
#include <Wt/WText.h>

namespace {

void showDialog(Wt::WObject *owner, Wt::WText *out)
{
    auto dialog = owner->addChild(std::make_unique<Wt::WDialog>("Go to cell"));

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

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

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

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

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

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

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

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

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

        owner->removeChild(dialog);
    });

    dialog->show();
}

}
auto container = std::make_unique<Wt::WContainerWidget>();

Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Jump");

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

auto c = container.get();
button->clicked().connect([=] {
  showDialog(c, 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 whether 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 interprets 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.h>
#include <Wt/WMessageBox.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>

auto container = std::make_unique<Wt::WContainerWidget>();

Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Status");

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

auto c = container.get();
button->clicked().connect([=] {
    out->setText("The status button is clicked.");

    auto messageBox =
      c->addChild(std::make_unique<Wt::WMessageBox>(
                  "Status",
                  "<p>Ready to launch the rocket...</p>"
                  "<p>Launch the rocket immediately?</p>",
                  Wt::Icon::Information,
                  Wt::StandardButton::Yes | Wt::StandardButton::No));

    messageBox->setModal(false);

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

        c->removeChild(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.h>
#include <Wt/WMessageBox.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>

using namespace Wt;


auto container = std::make_unique<Wt::WContainerWidget>();

Wt::WPushButton *button = container->addNew<Wt::WPushButton>("Start");

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

button->clicked().connect([=] {
    Wt::StandardButton answer
      = Wt::WMessageBox::show("Launch phase",
                          "<p>Launch the rocket?</p>",
                          Wt::StandardButton::Ok | Wt::StandardButton::Cancel);
    if (answer == Wt::StandardButton::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