Bug #5353 » 0002-Minor-improvements-to-Integration-Example-part-1.patch
examples/widgetgallery/examples/FormModel.cpp | ||
---|---|---|
{
|
||
public:
|
||
// Associate each field with a unique string literal.
|
||
static const Field FirstNameField;
|
||
static const Field LastNameField;
|
||
static const Field CountryField;
|
||
static const Field CityField;
|
||
static const Field BirthField;
|
||
static const Field ChildrenField;
|
||
static const Field RemarksField;
|
||
static const struct FieldNamesType {
|
||
Field FirstName = "first-name";
|
||
Field LastName = "last-name";
|
||
Field Country = "country";
|
||
Field City = "city";
|
||
Field Birth = "birth";
|
||
Field Children = "children";
|
||
Field Remarks = "remarks";
|
||
} Fld;
|
||
UserFormModel(Wt::WObject *parent = 0)
|
||
: Wt::WFormModel(parent)
|
||
{
|
||
initializeModels();
|
||
addField(FirstNameField);
|
||
addField(LastNameField);
|
||
addField(CountryField);
|
||
addField(CityField);
|
||
addField(BirthField);
|
||
addField(ChildrenField);
|
||
addField(RemarksField);
|
||
setValidator(FirstNameField, createNameValidator(FirstNameField));
|
||
setValidator(LastNameField, createNameValidator(LastNameField));
|
||
setValidator(CountryField, createCountryValidator());
|
||
setValidator(CityField, createCityValidator());
|
||
setValidator(BirthField, createBirthValidator());
|
||
setValidator(ChildrenField, createChildrenValidator());
|
||
addValidatedField(Fld.FirstName, createNameValidator(Fld.FirstName));
|
||
addValidatedField(Fld.LastName, createNameValidator(Fld.LastName));
|
||
addValidatedField(Fld.Country, new Wt::WValidator(true));
|
||
addValidatedField(Fld.City, new Wt::WValidator(true));
|
||
addValidatedField(Fld.Birth,
|
||
[=] () {
|
||
auto v = new Wt::WDateValidator();
|
||
v->setBottom(Wt::WDate(1900, 1, 1));
|
||
v->setTop(Wt::WDate::currentDate());
|
||
v->setFormat("dd/MM/yyyy");
|
||
v->setMandatory(true);
|
||
return v;
|
||
} ());
|
||
addValidatedField(Fld.Children,
|
||
[=] () {
|
||
auto v = new Wt::WIntValidator(0, MAX_CHILDREN);
|
||
v->setMandatory(true);
|
||
return v;
|
||
} ());
|
||
addField(Fld.Remarks);
|
||
// Here you could populate the model with initial data using
|
||
// setValue() for each field.
|
||
setValue(BirthField, Wt::WDate());
|
||
setValue(ChildrenField, Wt::WString());
|
||
setValue(Fld.Birth, Wt::WDate());
|
||
setValue(Fld.Children, Wt::WString());
|
||
}
|
||
void addValidatedField(Field field, Wt::WValidator* validator)
|
||
{
|
||
addField(field);
|
||
setValidator(field, validator);
|
||
}
|
||
Wt::WAbstractItemModel *countryModel() {
|
||
... | ... | |
}
|
||
int countryModelRow(const std::string& code) {
|
||
for (int i = 0; i < countryModel_->rowCount(); ++i)
|
||
if (countryCode(i) == code)
|
||
return i;
|
||
for (int i = 0; i < countryModel_->rowCount(); ++i)
|
||
if (countryCode(i) == code)
|
||
return i;
|
||
return -1;
|
||
return -1;
|
||
}
|
||
Wt::WAbstractItemModel *cityModel() {
|
||
... | ... | |
// Get the user data from the model
|
||
Wt::WString userData() {
|
||
return
|
||
Wt::asString(value(FirstNameField)) + " " +
|
||
Wt::asString(value(LastNameField))
|
||
+ ": country code=" + Wt::asString(value(CountryField))
|
||
+ ", city=" + Wt::asString(value(CityField))
|
||
+ ", birth=" + Wt::asString(value(BirthField))
|
||
+ ", children=" + Wt::asString(value(ChildrenField))
|
||
+ ", remarks=" + Wt::asString(value(RemarksField))
|
||
Wt::asString(value(Fld.FirstName)) + " " +
|
||
Wt::asString(value(Fld.LastName))
|
||
+ ": country code=" + Wt::asString(value(Fld.Country))
|
||
+ ", city=" + Wt::asString(value(Fld.City))
|
||
+ ", birth=" + Wt::asString(value(Fld.Birth))
|
||
+ ", children=" + Wt::asString(value(Fld.Children))
|
||
+ ", remarks=" + Wt::asString(value(Fld.Remarks))
|
||
+ ".";
|
||
}
|
||
// Get the right code for the current index.
|
||
std::string countryCode (int row) {
|
||
return boost::any_cast<std::string>
|
||
(countryModel_->data(row, 0, Wt::UserRole));
|
||
(countryModel_->data(row, 0, Wt::UserRole));
|
||
}
|
||
typedef std::map< std::string, std::vector<std::string> > CityMap;
|
||
... | ... | |
// - set the country name for the display role,
|
||
// - set the city names for the user role.
|
||
row = 1;
|
||
for (CountryMap::const_iterator i = countries.begin();
|
||
i != countries.end(); ++i) {
|
||
countryModel_->setData(row, 0, i->second, Wt::DisplayRole);
|
||
countryModel_->setData(row++, 0, i->first, Wt::UserRole);
|
||
for (auto i: countries) {
|
||
countryModel_->setData(row, 0, i.second, Wt::DisplayRole);
|
||
countryModel_->setData(row++, 0, i.first, Wt::UserRole);
|
||
}
|
||
// Create a city model.
|
||
... | ... | |
}
|
||
Wt::WValidator *createNameValidator(const std::string& field) {
|
||
Wt::WLengthValidator *v = new Wt::WLengthValidator();
|
||
v->setMandatory(true);
|
||
v->setMinimumLength(1);
|
||
v->setMaximumLength(MAX_LENGTH);
|
||
return v;
|
||
}
|
||
Wt::WValidator *createCountryValidator() {
|
||
Wt::WLengthValidator *v = new Wt::WLengthValidator();
|
||
v->setMandatory(true);
|
||
return v;
|
||
}
|
||
Wt::WValidator *createCityValidator() {
|
||
Wt::WLengthValidator *v = new Wt::WLengthValidator();
|
||
v->setMandatory(true);
|
||
return v;
|
||
}
|
||
Wt::WValidator *createBirthValidator() {
|
||
Wt::WDateValidator *v = new Wt::WDateValidator();
|
||
v->setBottom(Wt::WDate(1900, 1, 1));
|
||
v->setTop(Wt::WDate::currentDate());
|
||
v->setFormat("dd/MM/yyyy");
|
||
Wt::WLengthValidator *v = new Wt::WLengthValidator(1, MAX_LENGTH);
|
||
v->setMandatory(true);
|
||
return v;
|
||
}
|
||
};
|
||
Wt::WValidator *createChildrenValidator() {
|
||
Wt::WIntValidator *v = new Wt::WIntValidator(0, MAX_CHILDREN);
|
||
v->setMandatory(true);
|
||
return v;
|
||
}
|
||
const UserFormModel::FieldNamesType UserFormModel::Fld;
|
||
const UserFormModel::CityMap UserFormModel::cities = {
|
||
{ "BE", { "Antwerp", "Bruges", "Brussels", "Ghent" } },
|
||
{ "NL", { "Amsterdam", "Eindhoven", "Rotterdam", "The Hague"} },
|
||
{ "UK", { "London", "Bristol", "Oxford", "Stonehenge"} },
|
||
{ "US", { "Boston", "Chicago", "Los Angeles", "New York"} }
|
||
};
|
||
const Wt::WFormModel::Field UserFormModel::FirstNameField = "first-name";
|
||
const Wt::WFormModel::Field UserFormModel::LastNameField = "last-name";
|
||
const Wt::WFormModel::Field UserFormModel::CountryField = "country";
|
||
const Wt::WFormModel::Field UserFormModel::CityField = "city";
|
||
const Wt::WFormModel::Field UserFormModel::BirthField = "birth";
|
||
const Wt::WFormModel::Field UserFormModel::ChildrenField = "children";
|
||
const Wt::WFormModel::Field UserFormModel::RemarksField = "remarks";
|
||
// In C++11, this initializing can be done inline, within the declaration:
|
||
//
|
||
// const UserFormModel::CityMap UserFormModel::cities = {
|
||
// { "BE", { "Antwerp", "Bruges", "Brussels", "Ghent" } },
|
||
// { "NL", { "Amsterdam", "Eindhoven", "Rotterdam", "The Hague"} },
|
||
// { "UK", { "London", "Bristol", "Oxford", "Stonehenge"} },
|
||
// { "US", { "Boston", "Chicago", "Los Angeles", "New York"} }
|
||
// };
|
||
namespace {
|
||
UserFormModel::CountryMap getCountryMap() {
|
||
UserFormModel::CountryMap retval;
|
||
retval["BE"] = "Belgium";
|
||
retval["NL"] = "Netherlands";
|
||
retval["UK"] = "United Kingdom";
|
||
retval["US"] = "United States";
|
||
return retval;
|
||
}
|
||
}
|
||
const UserFormModel::CountryMap UserFormModel::countries = getCountryMap();
|
||
namespace {
|
||
UserFormModel::CityMap getCityMap() {
|
||
std::vector<std::string> beCities;
|
||
beCities.push_back("Antwerp");
|
||
beCities.push_back("Bruges");
|
||
beCities.push_back("Brussels");
|
||
beCities.push_back("Ghent");
|
||
std::vector<std::string> nlCities;
|
||
nlCities.push_back("Amsterdam");
|
||
nlCities.push_back("Eindhoven");
|
||
nlCities.push_back("Rotterdam");
|
||
nlCities.push_back("The Hague");
|
||
std::vector<std::string> ukCities;
|
||
ukCities.push_back("London");
|
||
ukCities.push_back("Bristol");
|
||
ukCities.push_back("Oxford");
|
||
ukCities.push_back("Stonehenge");
|
||
std::vector<std::string> usCities;
|
||
usCities.push_back("Boston");
|
||
usCities.push_back("Chicago");
|
||
usCities.push_back("Los Angeles");
|
||
usCities.push_back("New York");
|
||
UserFormModel::CityMap retval;
|
||
retval["BE"] = beCities;
|
||
retval["NL"] = nlCities;
|
||
retval["UK"] = ukCities;
|
||
retval["US"] = usCities;
|
||
return retval;
|
||
}
|
||
}
|
||
const UserFormModel::CityMap UserFormModel::cities = getCityMap();
|
||
const UserFormModel::CountryMap UserFormModel::countries = {
|
||
{ "BE", "Belgium" },
|
||
{ "NL", "Netherlands"},
|
||
{ "UK", "United Kingdom"},
|
||
{ "US", "United States"}
|
||
};
|
||
class UserFormView : public Wt::WTemplateFormView
|
||
{
|
||
public:
|
||
const UserFormModel::FieldNamesType& Fld = UserFormModel::Fld;
|
||
// inline constructor
|
||
UserFormView() {
|
||
model = new UserFormModel(this);
|
||
... | ... | |
setTemplateText(tr("userForm-template"));
|
||
/*
|
||
* First Name
|
||
*/
|
||
setFormWidget(UserFormModel::FirstNameField, new Wt::WLineEdit());
|
||
/*
|
||
* Last Name
|
||
*/
|
||
setFormWidget(UserFormModel::LastNameField, new Wt::WLineEdit());
|
||
/*
|
||
* Country
|
||
*/
|
||
Wt::WComboBox *countryCB = new Wt::WComboBox();
|
||
countryCB->setModel(model->countryModel());
|
||
countryCB->activated().connect(std::bind([=] () {
|
||
std::string code = model->countryCode(countryCB->currentIndex());
|
||
model->updateCityModel(code);
|
||
}));
|
||
setFormWidget(UserFormModel::CountryField, countryCB);
|
||
/*
|
||
* City
|
||
*/
|
||
Wt::WComboBox *cityCB = new Wt::WComboBox();
|
||
cityCB->setModel(model->cityModel());
|
||
setFormWidget(UserFormModel::CityField, cityCB, 0,
|
||
* First Name
|
||
*/
|
||
setFormWidget(Fld.FirstName, new Wt::WLineEdit());
|
||
/*
|
||
* Last Name
|
||
*/
|
||
setFormWidget(Fld.LastName, new Wt::WLineEdit());
|
||
/*
|
||
* Country
|
||
*/
|
||
auto countryCB = new Wt::WComboBox();
|
||
countryCB->setModel(model->countryModel());
|
||
countryCB->activated().connect(std::bind([=] () {
|
||
auto code = model->countryCode(countryCB->currentIndex());
|
||
model->updateCityModel(code);
|
||
}));
|
||
setFormWidget(Fld.Country, countryCB);
|
||
/*
|
||
* City
|
||
*/
|
||
auto cityCB = new Wt::WComboBox();
|
||
cityCB->setModel(model->cityModel());
|
||
setFormWidget(Fld.City, cityCB, 0,
|
||
[=] () { // updateModelValue()
|
||
std::string countryCode = model->countryCode(countryCB->currentIndex());
|
||
model->updateCityModel(countryCode);
|
||
model->setValue(UserFormModel::CityField, cityCB->valueText());
|
||
auto countryCode = model->countryCode(countryCB->currentIndex());
|
||
model->updateCityModel(countryCode);
|
||
model->setValue(Fld.City, cityCB->valueText());
|
||
});
|
||
/*
|
||
* Birth Date
|
||
*/
|
||
setFormWidget(UserFormModel::BirthField, new Wt::WDateEdit());
|
||
/*
|
||
* Birth Date
|
||
*/
|
||
setFormWidget(Fld.Birth, new Wt::WDateEdit());
|
||
/*
|
||
* Children
|
||
*/
|
||
Wt::WSpinBox *childrenSB = new Wt::WSpinBox();
|
||
setFormWidget(UserFormModel::ChildrenField, childrenSB,
|
||
* Children
|
||
*/
|
||
auto childrenSB = new Wt::WSpinBox();
|
||
setFormWidget(Fld.Children, childrenSB,
|
||
[=] () { // updateViewValue()
|
||
if (childrenSB->validate() == Wt::WValidator::Valid)
|
||
childrenSB->setValueText(boost::any_cast<Wt::WString>
|
||
(model->value(UserFormModel::ChildrenField)));
|
||
}, 0);
|
||
/*
|
||
* Remarks
|
||
*/
|
||
Wt::WTextArea *remarksTA = new Wt::WTextArea();
|
||
remarksTA->setColumns(40);
|
||
remarksTA->setRows(5);
|
||
setFormWidget(UserFormModel::RemarksField, remarksTA);
|
||
/*
|
||
* Title & Buttons
|
||
*/
|
||
Wt::WString title = Wt::WString("Create new user");
|
||
if (childrenSB->validate() == Wt::WValidator::Valid)
|
||
childrenSB->setValueText(boost::any_cast<Wt::WString>
|
||
(model->value(Fld.Children)));
|
||
}, 0);
|
||
/*
|
||
* Remarks
|
||
*/
|
||
auto remarksTA = new Wt::WTextArea();
|
||
remarksTA->setColumns(40);
|
||
remarksTA->setRows(5);
|
||
setFormWidget(Fld.Remarks, remarksTA);
|
||
/*
|
||
* Title & Buttons
|
||
*/
|
||
auto title = Wt::WString("Create new user");
|
||
bindString("title", title);
|
||
Wt::WPushButton *button = new Wt::WPushButton("Save");
|
||
auto button = new Wt::WPushButton("Save");
|
||
bindWidget("submit-button", button);
|
||
bindString("submit-info", Wt::WString());
|
||
... | ... | |
// Do something with the data in the model: show it.
|
||
bindString("submit-info",
|
||
Wt::WString::fromUTF8("Saved user data for ")
|
||
+ model->userData(), Wt::PlainText);
|
||
// Udate the view: Delete any validation message in the view, etc.
|
||
+ model->userData(), Wt::PlainText);
|
||
// Update the view: Delete any validation message in the view, etc.
|
||
updateView(model);
|
||
// Set the focus on the first field in the form.
|
||
Wt::WLineEdit *viewField =
|
||
resolve<Wt::WLineEdit*>(UserFormModel::FirstNameField);
|
||
auto viewField =
|
||
resolve<Wt::WLineEdit*>(Fld.FirstName);
|
||
viewField->setFocus(true);
|
||
} else {
|
||
bindEmpty("submit-info"); // Delete the previous user data.
|
||
... | ... | |
SAMPLE_BEGIN(FormModel)
|
||
UserFormView *view = new UserFormView();
|
||
auto view = new UserFormView();
|
||
SAMPLE_END(return view)
|