Search code examples
gwtframeonload-event

Frame contents loaded event in GWT


I am creating a DialogBox that contains a Frame widget. I have tried using both the addLoadHander and addAttachHandler hooks to try and capture changes to the frame with no success. Only the initial page load fires either event and after some research it appears that both actually occur when the Widget is attached to the DOM and not when the frames content is loaded.

DialogBox paymentProcessingDialog = new DialogBox(false);
private void submitPayment(String actionURL, String qryString){     
    Frame processCCWindow = new Frame(actionURL + "?" + qryString);     
    processCCWindow.addLoadHandler(new LoadHandler() {
        @Override 
        public void onLoad(LoadEvent event) {
            //This is called when the frame is attached to the dom
            //and not when the document is actually ready so it's 
            //kinda worthless for my scenario
            //Note: the addAttachHandler has the same issue

            //***call to JSNI idea (see below)
            checkURLChange();
        }

    });
    //...irrelevant code to style the DialogBox
    VerticalPanel panel = new VerticalPanel();
    panel.add(processCCWindow);
    paymentProcessingDialog.setWidget(panel);
    paymentProcessingDialog.center();
    paymentProcessingDialog.show();
}

The URL that is loaded into the frame contains an HTML response from an external server (Paypal - transparent redirect) that immediately re-submits itself back to my server via a form. I am trying to capture the body of the frame once the submission back to my server has completed and the document in the frame has loaded.

I have also tried to use a JSNI method that uses a MutationObserver (got the code from this solution) to try and watch the frame but I believe the JSNI is actually being run inside the parent and not inside the Frame(?) so nothing happens.

I have also tried using a setTimeout to trigger another method in my presenter class but I believe that is running into the same problem as the MutationObserver idea because the console statements never fire.

    private static native void checkURLChange()/*-{
  new MutationObserver(function(mutations) {
      mutations.some(function(mutation) {
        if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
          console.log(mutation);
          console.log('Old src: ', mutation.oldValue);
          console.log('New src: ', mutation.target.src);
          return true;
        }

        return false;
      });
    }).observe(location.href, {
      attributes: true,
      attributeFilter: ['src'],
      attributeOldValue: true,
      characterData: false,
      characterDataOldValue: false,
      childList: false,
      subtree: true
    });
    window.location = "foo";
    setTimeout(function() {
        @com.myPackage.MyoutPresenter::paymentProcessComplete(Ljava/lang/String;)(document.getElementsByTagName("body")[0].innerText);
      console.log("test" + document.getElementsByTagName("body")[0].innerText);
    }, 3000);
}-*/;

Does anyone have any thoughts on how I can accomplish this?


Solution

  • I am not familiar with Frame widget, but it appears that you add a handler after you set the URL. Try to build the Frame first (outside of submitPayment, if you use it more than once), and then set the URL:

    final Frame processCCWindow = new Frame();     
    processCCWindow.addLoadHandler(new LoadHandler() {
        @Override 
        public void onLoad(LoadEvent event) {
            // do something
        }
    
    });
    
    private void submitPayment(String actionURL, String qryString){
        processCCWindow.setUrl(actionURL + "?" + qryString);
    }