Project

General

Profile

Weird interaction between WTemplate and Validator

Added by Stefan Arndt about 2 years ago

Hi there, I have an issue with using a custom validator in my application and finally managed to boil it down the example below.

What To Do: Run and Open the application. Initially the line edit is not valid and marked accordingly. Click on the line edit. The "is-invalid" class goes away. This is fine. Now hit the button.
What I expect now: The line edit is still invalid, since the validator does not know anything else.
What I see instead: The line edit becomes valid.
Note: When pressing the button again, the line edit becomes invalid as it is supposed to.

Why WTemplate? That seems to be the issue. When commenting out the call to bindString() it works fine even on the first button press.
Am I missing something? Is this a bug? The validator seems to be working.

Any help would be highly appreciated.

#include <Wt/WApplication.h>
#include <Wt/WBootstrap5Theme.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/WServer.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include <Wt/WValidator.h>

using namespace Wt;

std::unique_ptr<Wt::WWidget> createPage();

class TestValidator : public Wt::WValidator
{
  public:
    Result validate(Wt::WString const& text) const override
    {
        (void)text;
        return Result(ValidationState::Invalid, "Error");
    }
};

int main(int argc, char** argv)
{
    try
    {
        WServer server(argv[0]);
        server.setServerConfiguration(argc, argv, "resources/server_config");

        server.addEntryPoint(
            Wt::EntryPointType::Application,
            [](WEnvironment const& env) {
                std::unique_ptr<Wt::WApplication> app = std::make_unique<Wt::WApplication>(env);
                app->setTheme(std::make_shared<Wt::WBootstrap5Theme>());
                app->root()->addNew<Wt::WText>("Some Test");
                app->root()->addWidget(createPage());

                return app;
            },
            "",
            "");

        if(server.start())
        {
            WServer::waitForShutdown();
            server.stop();
        }
    }
    catch(Wt::WServer::Exception const& e)
    {
        std::cerr << "Wt::WServer::Exception in main():" << e.what() << std::endl;
    }
}

std::unique_ptr<Wt::WWidget> createPage()
{
    using namespace Wt;

    auto container = std::make_unique<WTemplate>("${edit}${btn}${info}");
    auto c = container.get();

    auto edit = container->bindNew<Wt::WLineEdit>("edit");
    edit->setValidator(std::make_shared<TestValidator>());

    auto btn = container->bindNew<Wt::WPushButton>("btn", "validate");
    btn->clicked().connect([edit, c] {
        edit->validate();
        c->bindString("info", "Let me break the validator");
    });

    return container;
}

Replies (1)

RE: Weird interaction between WTemplate and Validator - Added by Roel Standaert about 2 years ago

I think this is because while your validate function always returns Invalid, the JavaScript is still the same, you should override javaScriptValidate to match:

  std::string javaScriptValidate() const override
  {
    return "{validate:function(){return {valid: false}}}";
  }
    (1-1/1)