Bug #11974
closedWt's Dbo Forms has no support for dynamically making fields visible
100%
Description
Whenever we would make a field dynamically (in)visible by using WFormModel::setVisible
the widget would be changed in the view by WTemplateFormView::updateViewField
. The changing of the widget can either be removing it from the WTemplate
when the widget is set to be invisible or binding it again when we're making it visible.
When using Wt's Dbo Forms and setting the model in the FormView
the widgets are correctly constructed using the default/custom delegates that are defined for the fields in the model.
If we would then make one of the fields invisible, updateViewField
will remove the widget from the template. If we make it visible after a while updateViewField
will try to either resolve the widget from the template (but it has been previously removed so cannot be found) or create it using WTemplateFormView::createFormWidget
.
The default implementation of createFormWidget
simply returns std::unique_ptr<WWidget>
so it has no effect and no widget will be bound.
Solution: FormView
needs to override createFormWidget
to recreate the widget based on the delegate set for the field.
The bug can be tested by making the below changes to the dbo forms example found in examples/dbo-form/DboForm.C
class TestDboModel : public Wt::Form::Dbo::FormModel<TestDboObject>
{
public:
TestDboModel(Wt::Dbo::Session& session, Wt::Dbo::ptr<TestDboObject> item)
: Wt::Form::Dbo::FormModel<TestDboObject>(session, item)
{
addAllDboColumnsAsFields();
initDboValues();
// ADD THIS LINE
setVisible("bool_value", false);
}
};
class TestDboView : public Wt::Form::Dbo::FormView<TestDboObject>
{
public:
TestDboView(const Wt::WString& text, std::shared_ptr<TestDboModel> model)
: Wt::Form::Dbo::FormView<TestDboObject>(text)
{
// ADD THESE LINES
auto btn = std::make_unique<Wt::WPushButton>("Show bool field");
btn-> clicked().connect([this] {
this->model()->setVisible("bool_value", true);
updateViewValue(this->model().get(), "bool_value");
});
bindWidget("show-bool-btn", std::move(btn));
...
}
};
In example/dbo-form/approot/templates.xml
you will then need to add the show-bool-btn
placeholder to the message to ensure that the button is visible.
Running the modified example will then give the following behavior.
Initial view (note that the bool field isn't visible):
After clicking the button:
The label becomes visible but the widget isn't bound.
Files
Updated by Yoika Ghysens about 1 year ago
- Status changed from InProgress to Review
- Assignee deleted (
Yoika Ghysens) - Target version set to 4.10.2
Updated by Matthias Van Ceulebroeck about 1 year ago
- Assignee changed from Marnik Roosen to Matthias Van Ceulebroeck
Updated by Matthias Van Ceulebroeck about 1 year ago
- Status changed from Review to Implemented @Emweb
- Assignee changed from Matthias Van Ceulebroeck to Yoika Ghysens
- % Done changed from 0 to 100
Updated by Matthias Van Ceulebroeck about 1 year ago
- Status changed from Implemented @Emweb to Closed