Monday, September 18, 2006

Wt in-place-edit widget.

As promised, and following up on my previous post, a Wt implementation of the in-place-edit widget.

The code, starting with the class definition of the new widget:

class WInPlaceEdit : public WCompositeWidget
{
public:
WInPlaceEdit(const std::string text, WContainerWidget *parent = 0);

const std::string text() const;

public signals:
Wt::Signal<std::string> valueChanged;

private slots:
void save();

private:
WContainerWidget *impl_;
WText *text_;
WLineEdit *edit_;
WPushButton *save_;
WPushButton *cancel_;
};

and the implementation of the constructor, and the two methods:

WInPlaceEdit::WInPlaceEdit(const std::string text, WContainerWidget *parent)
:
WCompositeWidget(parent)
{
setImplementation(impl_ = new WContainerWidget());
setInline(true);

text_ = new WText(text, impl_);
text_->setFormatting(WText::PlainFormatting);
text_->decorationStyle().setCursor(WCssDecorationStyle::Default);

edit_ = new WLineEdit(text, impl_);
edit_->setTextSize(20);
save_ = new WPushButton("Save", impl_);
cancel_ = new WPushButton("Cancel", impl_);
edit_->hide();
save_->hide();
cancel_->hide();

text_->clicked.connect(SLOT(text_, WWidget::hide));
text_->clicked.connect(SLOT(edit_, WWidget::show));
text_->clicked.connect(SLOT(save_, WWidget::show));
text_->clicked.connect(SLOT(cancel_, WWidget::show));

save_->clicked.connect(SLOT(save_, WWidget::hide));
save_->clicked.connect(SLOT(cancel_, WWidget::hide));
save_->clicked.connect(SLOT(edit_, WFormWidget::disable));
save_->clicked.connect(SLOT(this, WInPlaceEdit::save));

cancel_->clicked.connect(SLOT(save_, WWidget::hide));
cancel_->clicked.connect(SLOT(cancel_, WWidget::hide));
cancel_->clicked.connect(SLOT(edit_, WWidget::hide));
cancel_->clicked.connect(SLOT(text_, WWidget::show));
}

const std::string WInPlaceEdit::text() const
{
return text_->text();
}

void WInPlaceEdit::save()
{
edit_->hide();
text_->show();
text_->setText(edit_->text());
edit_->enable();

emit(valueChanged(edit_->text()));
}

And this is what it does (sorry, no demo online yet since the current CVS is not release-ready) :
  • Client-side event handling (JavaScript), for all functionality but save().
  • Server-side event handling for the save() method, using AJAX.
  • Works also without JavaScript, but then all event-handling happens server-side and requires a complete page refresh.
  • Fast load time since invisible widgets (the edit buttons) or transmitted only after the visible widgets are displayed.
  • Small bandwidth footprint: the demo application loads in 11Kb spread over 4 HTTP requests. Note that no effort has been done to compress the JavaScript. The save() button triggers generates about 200 bytes.
Looking forward to see how this compares to the echo2 + GWT implementation !

Wednesday, September 13, 2006

Wt versus echo2+GWT

At the Agile AJAX blog, Dietrich Kappe is going to look at how GWT may be merged into Echo2.

Echo2 is comparable to Wt in the sense that it is a server-side library (although they call it a framework) to build web applications. On the other hand, GWT is comparable to Wt in the sense that it allows creating client-side event handling in the Java language. Wt provides this functionality using stateless slot learning, but then naturally starting from C++ code.

Combining Echo2 and GWT thus is a compelling idea, since they are two java-based complementary toolkits for web development.

Interestingly, the choice for a widget to create (which is in the framework world a component), fell on an edit-in-place field. Competitive as we are, and of course determined to show off the nice stuff in Wt, it will be nice to compare their implementation(s) to a Wt-based implementation.

Before comparing different implementations, we need to consider whether we have a comparable feature set, with respect to:
  • Does it work when JavaScript is disabled, or on browser that do not support JavaScript ?
  • Is the server state synchronized with client (does a 'reload' give the same page ?)
And then we will want to look at:
  • Code size and elegance
  • API -- how easy it is to use the widget/component ?
  • Were we really using only one language (C++ or Java) ? Is there any chance of runtime syntax errors (caused by faulty JavaScript or XML) ?
  • Does client-side or server-side event handling look similar ? Can we easily switch ?
  • Bandwidth usage and number of round trips
Of course, I am kind of setting the rules while both competing, rendering the comparision fairly biased.

But as this is a blog, you are welcome to add additional test criteria you might be interested in !

Good luck to the Java camp!