Project

General

Profile

Actions

Bug #13654

open

JS error when adding submenu to a WMenu bound to a removed WTemplate variable

Added by Romain Mardulyn 13 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
03/17/2025
Due date:
% Done:

0%

Estimated time:

Description

When a WMenu is bound to a variable of a WTemplate, and that the variable stop being showed by the WTemplate due to a conditional statement being set to false, adding a submenu to that WMenu leads to the follwing JS error: "Cannot read properties of null (reading 'appendChild')". This is probably due to Wt trying to add the submenu to the deleted WMenu.

Here is the code that can be used to reproduce the bug:

#include <Wt/WApplication.h>
#include <Wt/WEnvironment.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WMenu.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include <Wt/WStackedWidget.h>


class TemplateApp : public Wt::WApplication
{
public:
TemplateApp(const Wt::WEnvironment& env)
    : Wt::WApplication(env)
  {
    messageResourceBundle().use(appRoot() + "template");
    tpl_ = root()->addWidget(std::make_unique<Wt::WTemplate>(Wt::WString::tr("test3")));
    tpl_->setCondition("if:show-item", true);

    auto displayAreaPtr  = std::make_unique<Wt::WStackedWidget>();
    displayArea_ = displayAreaPtr.get();

    menu_ = tpl_->bindWidget("Menu", std::make_unique<Wt::WMenu>(displayArea_));
    menu_->addStyleClass("flex-column");

    auto subMenu1Ptr = std::make_unique<Wt::WMenu>(displayArea_);
    auto subMenu1 = subMenu1Ptr.get();

    auto subitem1 = subMenu1->addItem("sub-item 1.1", std::make_unique<Wt::WText>("item 1.1"));

    auto subm = menu_->addMenu("item 1", std::move(subMenu1Ptr));

    tpl_->bindWidget("Stack", std::move(displayAreaPtr));

    auto disableButton = tpl_->bindWidget("disable-btn", std::make_unique<Wt::WPushButton>("Remove Menu"));
    disableButton->clicked().connect([=]{
      removeMenu();
    });
  }
private:
  Wt::WTemplate* tpl_;
  Wt::WStackedWidget* displayArea_;
  Wt::WMenu* menu_;

  void removeMenu()
  {
    auto subMenu1Ptr = std::make_unique<Wt::WMenu>(displayArea_);
    auto subMenu1 = subMenu1Ptr.get();

    auto subitem1 = subMenu1->addItem("sub-item 2.1", std::make_unique<Wt::WText>("item 2.1"));

    auto subm = menu_->addMenu("item 2", std::move(subMenu1Ptr));
    tpl_->setCondition("if:show-item", false);
  }
};

int main(int argc, char *argv[])
{
  return Wt::WRun(argc, argv, [](const Wt::WEnvironment &env) {
    return std::make_unique<TemplateApp>(env);
  });
}

And here is the template:

<message id="test3">
    ${<if:show-item>}
      <div>
        ${Menu}
      </div>
    ${</if:show-item>}
      <div>
        ${Stack}
      </div>
    ${disable-btn}
  </message>

No data to display

Actions

Also available in: Atom PDF