11
votes

Accrocher un événement GWT sur un élément d'une iframe externe

J'écris une application GWT qui implique d'interagir avec un document externe dans une iframe. Comme une preuve de concept, j'essaie de joindre un gestionnaire de clic sur un bouton.

Les travaux suivants dans JavaScript P>

public class ElementWrapper extends Widget implements HasClickHandlers {

    public ElementWrapper(Element theElement) {
        setElement(theElement);
    }

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


}


0 commentaires

7 Réponses :


0
votes

Vous pouvez utiliser JSNI pour réutiliser votre morceau de code JavaScript. Votre code JavaScript appellerait une méthode GWT sur un objet qui le jetterait au nom du bouton de l'IFrame.

Quant pourquoi le code GWT ne fonctionne pas - je suppose que c'est parce qu'ils utilisent une couche sur des événements de navigateur réguliers qui ne peuvent probablement pas couvrir plus d'une image. C'est juste une hypothèse cependant. Vous pouvez classer cela comme une requête de fonctionnalité / bogue à nouveau. Équipe GWT. Si je suis correct, votre code semble très bien.


1 commentaires

Cool, merci pour la réponse. Je suppose que je vais explorer le chemin JSNI, bien que je souhaite rester à l'écart de l'écriture de JavaScript sur mesure autant que possible.



1
votes

Après avoir recherché cela plus loin, j'ai constaté que l'IFRAME est sans importance. Le même comportement ne fonctionne pas sur un bouton normal de la page d'hôte.

Je l'ai essentiellement corrigé en utilisant JSNI pour reproduire une partie du mécanisme de traitement des événements de GWT. Les travaux suivants: P>

public class ClickEventManager {
private boolean clickHandlerRegistered = false;
private ClickHandler clickHandler;
private Element element;

public ClickEventManager(Element element) {
    this.element = element;
}

public void invokeClickHandler() {
    //This shouldn't really be null but we are bypassing GWT's native event mechanism
    //so we can't create an event
    clickHandler.onClick(null);
}

public boolean isClickHandlerRegistered() {
    return clickHandlerRegistered;
}

HandlerRegistration registerClickHandler(ClickHandler handler) {
    clickHandler = handler;

    if (!clickHandlerRegistered) {
        registerClickHandlerInJS(element);
        clickHandlerRegistered = true;
    }
    return new HandlerRegistration() {
        public void removeHandler() {
            //For now, we don't support the removal of handlers
            throw new UnsupportedOperationException();
        }
    };
}
private native void registerClickHandlerInJS(Element element)/*-{
    element.__clickManager = this;
    element.onclick 
        = function() {
            var cm = this.__clickManager; 
            cm.@com.talktactics.agent2.client.widgets.ClickEventManager::invokeClickHandler()();
        }
}-*/;
}


1 commentaires

Merci merci! C'était exactement ce dont j'avais besoin de le faire travailler dans IE7!



4
votes

Je pense que le problème est que la méthode GWT onatach () n'est pas appelée lorsque vous utilisez l'emballage comme dans votre premier exemple. Vous pouvez essayer d'utiliser la méthode static wrap sur le widget de boutons. Bien que l'utilisation de cette entrée doit être de type . Ou examiner la mise en œuvre de la méthode . Voici le code modifié lors de l'utilisation de la méthode wrap : xxx


0 commentaires

10
votes

Hilbrand a raison sur le problème que la méthode GWT Onatach () n'a pas été appelée.

J'ai implémenté votre solution d'origine, ajoutant la méthode suivante à Elementwrapper : xxx

et appelé wrapper.onattach () après le EMPELWRAPPER est créé. Fonctionne comme un charme!


1 commentaires

Merci! Je savais qu'il devait y avoir une manière plus propre :)



0
votes

S'il vous plaît voir ma réponse précédente. Une légère modification de votre solution d'origine le fera fonctionner.


0 commentaires

1
votes

Vous pouvez trouver cela utile:

IFrameElement frm = Document.get().createIFrameElement();
Document d = frm.getContentDocument();
NodeList<Element> inputs = d.getElementsByTagName("input");
InputElement target = null;
for(int i = 0; i < inputs.getLength(); ++i) {
  Element e = inputs.getItem(0);
  if (e.getNodeName().equals("submit")) {
    target = InputElement.as(e);
    break;
  }
}
if (target != null) {
  DirectPanel p = new DirectPanel(target);
  p.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
      // TODO Auto-generated method stub
    }
  });
}


0 commentaires

1
votes

Au lieu d'utiliser Iframes, je vous suggère de créer simplement une demande HTTP de GWT via com.google.gwt.http.client.RequestBuilder. Comme: xxx


0 commentaires