Project

General

Profile

WComboBox::currentIndex does not return actual currentIndex

Added by Paolo Greppi over 11 years ago

steps to reproduce with Wt 3.1.0 and Iceweasel 10.0 or Chromium 22.0:

1) restart application (refresh browser)

2) click Download button; get this:

********** currentIndex in FileResource::handleRequest = 0

3) click Go button; get this:

********** currentIndex in ApplicationLibfp::go = 0

4) change pull-down list selection from "zero" to "one"

5) click Download button; get this:

********** currentIndex in FileResource::handleRequest = 0

(should have read 1)

6) click Go button; get this:

********** currentIndex in ApplicationLibfp::go = 1

(correct)

7) click Download button; get this (should have read 1):

********** currentIndex in FileResource::handleRequest = 1

(now this one is correct too)

zzz.zip (2.93 KB) zzz.zip

Replies (7)

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Wim Dumon over 11 years ago

Paolo,

A few things are wrong with your application:

As explained in http://www.webtoolkit.eu/wt/doc/reference/html/classWt_1_1WResource.html you cannot access the widget tree in handleResource() without grabbing the update lock. This will however not make your issue go away.

The second thing is that the state between the browser Wt are not synchronized when the file is fetched from the server. By attaching a resource to the button, the browser will launch a GET for that resource when you click the button. It will not wait for the synchronization between the client and the server to happen (this synchronisation will not happen since there is no event happening, you can compare this to clicking an anchor).

So what I recommend: put a listener on changed() of your combobox. In that listener, configure your WFileResource to point to the right file (by calling a method of FileResource, e.g. setFilename(), ...). When the user now changes the selection, the file resource will point to the right file.

Also it's a bit weird to modify the target of a resource - even though this may not be problematic.

BR,

Wim.

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Jan Hrubeš over 11 years ago

and little warning at the end:

WPushButton::setResource() is marked as deprecated.

use

xls->setLink( WLink(fileResource_) );

to avoid problems with feature releases of wt.

Jan

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Paolo Greppi over 11 years ago

@Jan Lindemann: thanks, but I am stuck with wt 3.1.10 where WPushButton::setResource is the only option; I'll keep a note to implement your suggestion when I upgrade.

@Wim Dumon:

  1. OK I instantiate a Wt::WApplication::UpdateLock in the FileResource::handleRequest method. For that, the pointer to the application has to be passed as non-const to the FileResource constructor.

2. In the stripped-down example I prepared, there is just one combobox and preparing the resource is cheap. In the real application, there are many controls and preparing the resource is expensive. I'd rather not have the change() event of all those controls trigger the recomputation of the resource ! What I want is to have the user trigger that on clicking on the WPushButton. Is there any way we can trip a dummy event to force synchronization ?

3. About modifying the target of the resource: the resource is a report that has to be custom-generated on the server, different for each user and for each state of the application. We generate it, save it to a temporary location with a random name, and serve the link to the resource.

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Jan Hrubeš over 11 years ago

Hi,

for such a thing I'm using folowing steps:

- user clicks on a button

- block user interface

- execute some asynchronous stuff (even in separated thread)

- when file is ready, lock the session with UpdateLock

- unblock user interface

  • use redirect to start download

    report_ = new WFileResource("application/x-tgz", "generatedReport.tgz", this);
    report_->suggestFileName("report.tgz", WResource::Attachment);
    wApp->redirect(report_->url());

Jan

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Paolo Greppi over 11 years ago

Using Wt::WApplication::redirect in the Wt::WPushButton::clicked event handler rather than Wt::WPushButton::setResource did the trick.

So far everything is clear except how to block the UI. Do you mean Wt::WApplication::deferRendering (which I can not try in 3.1.10) ?

Thanks, Paolo

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Jan Hrubeš over 11 years ago

Hi,

you can use wApp~~loadingIndicator()~~>show() / hide(), to control visibility of loading indicator. However it is not a good way because Wt itself will control it too.

Another way is usage of WDialog with setModal(true) a show(). Do not use exec().

Jan.

RE: WComboBox::currentIndex does not return actual currentIndex - Added by Wim Dumon over 11 years ago

There's a different way to tell Wt that even though you return from the event hander, the event is not handled and will be finished somehow later. See WApplication::deferRendering() and WApplication::resumeRendering(). Actually using these makes Wt behave node.js alike (asynchronous everywhere, but with Wt you can choose when you want it), which is hot nowadays. You use this in combination with the usual functions that you use when you're updating the widget tree asynchronously: WApplication::post() and the WApplication::UpdateLock.

Best regards,

Wim.

    (1-7/7)