Trees & Tables — widgets for tabular and tree-like data

Tables

The most direct way to organize widgets in a tabular grid is using WTable. This widget renders as an HTML <table> element.

Each table cell is a Container to which ontents can be added. The table will grow as necessary while you add data to it.

Our first example shows a plain table, with default browser styling.

Example
#First NameLast NamePay
1MarkOtto
2JacobThornton
3Larry the Bird
source
#include <Wt/WTable.h>
#include <Wt/WTableCell.h>
#include <Wt/WLineEdit.h>
#include <Wt/WText.h>

namespace {
    struct Employee {
	std::string firstName;
	std::string lastName;
	double pay;

        Employee(const std::string& aFirstName, 
		 const std::string& aLastName,
		 double aPay)
	  : firstName(aFirstName),
	    lastName(aLastName),
	    pay(aPay) { }
    };

    Employee employees[] = {
      Employee("Mark", "Otto", 100),
      Employee("Jacob", "Thornton", 50),
      Employee("Larry the Bird", "", 10)
    };
}

auto table = cpp14::make_unique<WTable>();
table->setHeaderCount(1);
table->setWidth(WLength("100%"));

table->elementAt(0, 0)->addWidget(cpp14::make_unique<WText>("#"));
table->elementAt(0, 1)->addWidget(cpp14::make_unique<WText>("First Name"));
table->elementAt(0, 2)->addWidget(cpp14::make_unique<WText>("Last Name"));
table->elementAt(0, 3)->addWidget(cpp14::make_unique<WText>("Pay"));

for (unsigned i = 0; i < 3; ++i) {
    Employee& employee = employees[i];
    int row = i + 1;

    table->elementAt(row, 0)
        ->addWidget(cpp14::make_unique<WText>(WString("{1}")
				  .arg(row)));
    table->elementAt(row, 1)
        ->addWidget(cpp14::make_unique<WText>(employee.firstName));
    table->elementAt(row, 2)
        ->addWidget(cpp14::make_unique<WText>(employee.lastName));
    table->elementAt(row, 3)
        ->addWidget(cpp14::make_unique<WLineEdit>(WString("{1}")
				      .arg(employee.pay)));
}

If you only need to display a static table (with a fixed number of rows and columns), then you might just as well consider using a WTemplate containing the HTML markup for a table, and providing the contents (widgets or strings) by substituting place holders.

In contrast, the WTable class is suitable when the table is to be constructed dynamically, based on information that may be variable in size.

Finally, you may want to consider using a WTableView if you would like to display large amounts of data (more than could fit in memory!), or if you would like the user to be able to resort the data or resize columns.

Top

Bootstrap styling

The bootstrap theme provides optional markup for the table. These styles are enabled by adding the "table" style class, and other optional style classes. The other styling options are enabled by adding one of the following classes:

table-bordered
Adds borders
table-hover
Enables a row hover effect
table-condensed
Makes the table more compact
table-striped
Adds alternating row colors

Example
#First NameLast NamePay
1MarkOtto
2JacobThornton
3Larry the Bird
Options:
source
#include <Wt/WTable.h>
#include <Wt/WTableCell.h>
#include <Wt/WLineEdit.h>
#include <Wt/WText.h>
#include <Wt/WCheckBox.h>

namespace {
    struct Employee {
	std::string firstName;
	std::string lastName;
	double pay;

        Employee(const std::string& aFirstName, 
		 const std::string& aLastName,
		 double aPay)
	  : firstName(aFirstName),
	    lastName(aLastName),
	    pay(aPay) { }
    };

    Employee employees[] = {
      Employee("Mark", "Otto", 100),
      Employee("Jacob", "Thornton", 50),
      Employee("Larry the Bird", "", 10)
    };


    void addOptionToggle(WWidget *widget, const char *option,
                         const char *styleClass, WContainerWidget *parent) {
        WCheckBox *checkBox =
            parent->addWidget(cpp14::make_unique<WCheckBox>(option));
	checkBox->setInline(false);
	checkBox->changed().connect([=] {
	      widget->toggleStyleClass(styleClass, checkBox->isChecked());
	});
    }
}

auto table = cpp14::make_unique<WTable>();
auto table_ = table.get();
table_->setHeaderCount(1);

table_->elementAt(0, 0)->addWidget(cpp14::make_unique<WText>("#"));
table_->elementAt(0, 1)->addWidget(cpp14::make_unique<WText>("First Name"));
table_->elementAt(0, 2)->addWidget(cpp14::make_unique<WText>("Last Name"));
table_->elementAt(0, 3)->addWidget(cpp14::make_unique<WText>("Pay"));

for (unsigned i = 0; i < 3; ++i) {
    Employee& employee = employees[i];
    int row = i + 1;

    table_->elementAt(row,0)->
        addWidget(cpp14::make_unique<WText>(WString("{1}").arg(row)));
    table_->elementAt(row,1)->
        addWidget(cpp14::make_unique<WText>(employee.firstName));
    table_->elementAt(row,2)->
        addWidget(cpp14::make_unique<WText>(employee.lastName));
    table_->elementAt(row,3)->
        addWidget(cpp14::make_unique<WLineEdit>(WString("{1}").arg(employee.pay)));
}

table_->addStyleClass("table form-inline");

auto result = cpp14::make_unique<WContainerWidget>();
auto result_ = result.get();
result_->addWidget(std::move(table));

result_->addWidget(cpp14::make_unique<WText>("Options:"));

addOptionToggle(table_, "borders", "table-bordered", result_);
addOptionToggle(table_, "hover", "table-hover", result_);
addOptionToggle(table_, "condensed", "table-condensed", result_);
addOptionToggle(table_, "stripes", "table-striped", result_);

Top