开发者

Getting JQuery to act on class name dynamically added by GWT

I'm trying to get jquery to do some ui affects for me while using GWT. I have notifications that I add to a page that when clicked should disappear. Since there could be multiple notifications of the same type (warning, error, etc.) I'm trying to dynamically add a style name only when they are clicked through GWT and then have jquery act on that particular class name.

The problem is that the jquery function is firing before the style name can be added so the user has to click the notification twice in order for it to close.

Any ideas?

  public abstract class AbstractNotificationWidget extends Composite implements ClickHandler, HasClickHandlers {

  protected abstract String getUniqueId();

  @Override
  public HandlerRegistration addClickHandler(ClickHandler handler) {
    return addDomHandler(handler, ClickEvent.getType());
  }

  @Override
  public void onClick(ClickEvent event) {
    doClick(getUniqueId());
  }

  protected static native void doClick(String name) /*-{
    $wnd.$("#" + name).click(function () {
      $wnd.$(this).slideUp("slow");
      $wnd.$("div", this).fadeOut("slow");
      });
  }-*/;

}

I then have subclasses that extend the above class

开发者_StackOverflowpublic class ErrorNotificationWidget extends AbstractNotificationWidget {

  private final String uniqueId;

  public ErrorNotificationWidget (String title, String message) {
    uniqueId = DOM.createUniqueId();

    initWidget(uiBinder.createAndBindUi(this));

    this.getElement().setId(uniqueId);

    this.addClickHandler(this);
  }
  @Override
  protected String getUniqueId() {
    return this.uniqueId;
  }

These subclasses use the UIBinder to determine how they should be drawn. Then these widgets get added to a panel to be displayed.


What are you exactly trying to achieve? Hide the widget based on the styles it has applied or it's id? (in the current version it seems you're mixing one with the other)

If the ClickEvent is firing to fast (which can be tested by adding a timeout before it), you can try wrapping it in a DeferredCommand.

The other possibility is that jQuery is crapping up ;) I had some weird issues when using callbacks in jQuery/Mootools - the reason was that these frameworks extend/change function() (among other things) - however, JSNI stuff is executed from a "clean" iframe, where there are no changes made by jQuery (that's why you have to reference to the main window via $wnd). You can test if this is the issue here by defining, for example, a test function in your host HTML page and then passing it as the callback function in your void doClick(String name) method:

protected static native void doClick(String name) /*-{
  $wnd.$("." + name).click($wnd.jqueryTest); // BTW, why '"." + '?
}-*/;

And my initial suggestion still holds - use FocusPanel as your main widget - trying to correctly implement HasClickHandlers (and similar interfaces) is a PITA from my experience and can lead to weird bugs and/or memory leaks.


Maybe you should try GWTQuery http://code.google.com/p/gwtquery/ instead try to integrate it natively.


Add a class to the element which you want to close on click, i.e.

<div class="close-on-click">Content</div>

Your javascript can auto-bind the function for any existing or dynamically created elements that match the selector:

$('.close-on-click').live('click', function() {
  $(this).remove();
});


Your code requires two clicks because you install the Jquery click binding event on the first click (via the onclick method) and so this last reacts a the second click. Change your code in something like that:

protected static native void doClick(String name) /*-{     
      var $_this = $("#" + name);
      $_this.slideUp("slow");       
      $wnd.$("div", $_this).fadeOut("slow");       
}-*/; 

FYI, you can use GwtQuery (gwt clone of jQuery) and the code should look like that :

import static com.google.gwt.query.client.GQuery.$; 

public abstract class AbstractNotificationWidget extends Composite implements ClickHandler, HasClickHandlers {    

@Override   
public HandlerRegistration addClickHandler(ClickHandler handler) {     
    return addDomHandler(handler, ClickEvent.getType());   
}    

@Override   

public void onClick(ClickEvent event) {     
    $(this).slideUp(Speed.SLOW);
    $("div", getElement()).fadeOut(Speed.SLOW);
}    

} 

no need to use an uniqueId

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜