views:

98

answers:

4

The application I am working on has pages of setup data with lots of textboxes; each page having a save button. I have defined most of the pages as a *.ui.xml file and used the GWT 2.0 UI binding.

I would like to add a save button which is disabled onload and is only enabled after a user modifies the data into one of the textboxes.

I know I can register an event handler against each element on the page to enable the button, but I wanted a more elegant solution. Ideally, I would like to define a button that "listens" to events on the page and changes itself. Is this possible in GWT?

+2  A: 

Check out the GWT articles on MVP
http://code.google.com/webtoolkit/articles/mvp-architecture.html
http://code.google.com/webtoolkit/articles/mvp-architecture-2.html

Specifically the part on Events and the Event Bus.

Also look at this http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/8b0ae5eaf84d8bc2?hide_quotes=no

Romain Hippeau
+1 The video linked in that Groups thread is solid gold. http://www.youtube.com/watch?v=PDuhR18-EdM
Jason Hall
+3  A: 

You can work out a very simple solution to this.

  1. Put all your editable controls in a HTMLPanel (or any other panel if you wish)
  2. Have a ui:field reference to this HTMLPanel in the accompanying java file.
  3. Soon after you make a call to initWidget in your java class, iterate through all the child widgets of HTMLPanel and register a ChangeHandler on each input widget.

Pseudo Code:

    for ( int i = 0; i < hTMLPanel.getWidgetCount( ); i++ )
    {
        Widget widget = hTMLPanel.getWidget( i );

        if ( widget instanceof HasChangeHandlers )
            ((HasChangeHandlers)widget).addChangeHandler( <Your Change Handler to enable save>);
    }

You can make this recursive if you have nested widgets.

Ashwin Prabhu
I'd just like to add that you should define the `ChangeHandler` before entering the loop and then just reuse it - no need to create/instantiate it for every element.
Igor Klimer
+1  A: 

You can also add the change event to your whole containing widget using addDomHandler

public class SetupDataPage extends Composite{

  // Binder stuff  

  // Button from the binder
  @UiField Button saveBtn;

  public SetupDataPage(){
        addDomHandler(new ChangeHandler() {

            @Override
            public void onChange(ChangeEvent event) {
                saveBtn.setEnabled(true);
            }
        }, ChangeEvent.getType());
  }
}

Beware This will trigger the event for all textboxes in SetupDataPage. On the other side it might not work for some specific widgets. I know it works for GWT's textbox, checkbox, listbox...

DrDro
This worked well for us. Is there any performance issues on load of a page with a domHandler?
Tihom
@Tihom We haven't noticed any but no advanced performance tests have been done.
DrDro
This mostly works. The exception we found is in IE if the page has a listbox. Changing the value in the listbox in IE doesn't trigger a ChangeEvent on the dom. I had to add an explicit change handler on the listbox to make it work
Tihom
+1  A: 

DOM Handler is better and will perform faster..

iftee