Skip to Content
Author's profile photo Former Member

Open views in non-modal external windows – the patch version

 

h5. Prelude 

What’s common between how to share context to external browser, Re: CreateExternalWindow – pass context data and createExternalWindow thread? Well, all of them want to open an existing view in an external non-modal window. The problem here is obviously obtaining the URL of the view so that we can pass this URL to the createNonModalExternalWindow() method of IWDWindowManager.

So I tried to come up with a solution ( actually more of a workaround 😉 ), which is as follows:

  • Make sure that this newly embedded view has an ID (in this case I’ve used the ID extrnlView).

Create a method openExternalWindow in the Component Controller.

    1. Implementation of openExternalWindow:

try {

String appUrl = WDURLGenerator.getWorkloadBalancedApplicationURL(wdComponentAPI.getApplication().getDeployableObjectPart());

appUrl = appUrl.concat(“?isInExternal=X”);

wdComponentAPI.getWindowManager().createNonModalExternalWindow(appUrl,”External”).show();

} catch (WDURLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

Insert this piece of code in the wdDoInit of the Component Controller:

    String reqParam = WDProtocolAdapter.getProtocolAdapter().getRequestParameter(“isInExternal”);

     

    if(reqParam != null && reqParam.equals(“X”)){

    IWDWindowInfo win = wdComponentAPI.getComponentInfo().findInWindows(“<window name>”);

    win.setDefaultRootViewUsage(win.getViewUsageByID(“extrnlview”));

    }

     

     

    h5. What’s the idea?

    The solution is based on the idea of loading the same application again but with a new default view :). So the code just changes the default view based on a requesrt parameter which tells that the application is being run in an external window.

     

    h5. Contextmapia

    Ok, so all seemed rosy after this until How to copy data to external windows wanted to map the context between these two views. Fair enough requirement but here’s the catch, my workaround runs the application again and hence every controller will be initialized again. In short there’s no way to map the two contexts. So the only solution seems to be persistence of the context somehow.

    So i created a small class called ContextMapper and saved it in my src/packages/<path to component> folder. The idea is to hold the source node as an IWDNode reference. This becomes our source node. Next we’ll have a method which takes an IWDNode reference as parameter. This method will just map this node to the source node using the WDCopyService APIs.

    So here’s the implementation of ContextMapper.java

    public class ContextMapper {

    *      private IWDNode supplier;</p><p>      private static ContextMapper singletonObj;</p><p>      </p><p>      /**</p><p>       * </p><p>       *</p><p>       /

    *      private ContextMapper(){</p><p>      }</p><p>      </p><p>      /**</p><p>       * </p><p>       * @param s</p><p>       /

    *      public void setSupplier(IWDNode s){</p><p>            this.supplier = s;</p><p>      }</p><p>      </p><p>      /**</p><p>       * </p><p>       * @param s</p><p>       * @return</p><p>       /

    *      public static ContextMapper newInstance(){</p><p>            if(null == singletonObj){</p><p>                  singletonObj = new ContextMapper();</p><p>            }</p><p>            </p><p>            return singletonObj;</p><p>      }</p><p>      </p><p>      /**</p><p>       * </p><p>       * @param target</p><p>       /

    *      public void map(IWDNode target){</p><p>            if(!this.supplier.isEmpty()){</p><p>                  WDCopyService.copyElements(this.supplier, target);</p><p>            }</p><p>      }</p><p>}</p></td></tr></tbody></table><p> </p><p>Let’s say we have two views “FirstView” and “SecondView“. Firstview is the one which loads by default and when we run in the external window, SecondView is loaded.</p><ol><li>FirstView uses the context mapper class like the following:</li></ol><table border=”1″ cellspacing=”0″ cellpadding=”0″ width=”100%”><tbody><tr><td width=”100%” valign=”top” style=”font-size: xx-small”><p>//let’s say the value node Table needs to be mapped</p><p>ContextMapper.newInstance().setSupplier(wdContext.nodeTable());</p><p> </p><p>//any time after this the external window can be oopened</p></td></tr></tbody></table><p> </p><ol><li>SecondView uses the context mapper like this:</li></ol><table border=”1″ cellspacing=”0″ cellpadding=”0″ width=”100%”><tbody><tr><td width=”100%” valign=”top” style=”font-size: xx-small”><p>//This view has also has a value node called Table which contains identically named attributes</p><p>ContextMapper.newInstance().map(wdContext.nodeTable());*

     

    h5. Assumptions made:

    1. The two context nodes to be mapped have a flat structure, i.e. there are no nested nodes inside.
    2. Only one node needs to be mapped. The ContextMapper code can be modified if more than one node needs to be mapped.
    3. There is no need to block the parent window while the external window is visible. If a need like this arises, please use modal windows.

    There can be a problem 😉 if you are trying to pass some data back to the main window.

      That’s it for now.

       

      Assigned Tags

          10 Comments
          You must be Logged on to comment or reply to a post.
          Author's profile photo Vigneswararao Vankayala
          Vigneswararao Vankayala
          Hi..

          Satya..

          Hatesup u..

          Last 5 days onwards i am fighting with this solution and open three threds. atlost you give solution.. but still i didnt check..

          I think it works. Really thnk you @};-

          Author's profile photo Vigneswararao Vankayala
          Vigneswararao Vankayala
          thanks alot..

          please give me mail to this id vvr4us@yahoo.com

          Author's profile photo Former Member
          Former Member
          The trick seems to be the static class which stores the context temporarily and then maps it..  !

          Wouldnt it be simpler if we create a new application 
          at design time.. and use that for launchin external window.. instead.. of changing default view usage at runtime ?

          Author's profile photo Former Member
          Former Member
          Hi Bharathwaj,
             Thanks for your comments and sorry for this late reply.

             Yes, you can create one more application during design time but in that case you need to create a new window and also a new component for a new interface view. Isn't it? I just wanted to avoid that.

          Regards,
          Satyajit.

          Author's profile photo Karthik S J
          Karthik S J
          wasaaaa
          Author's profile photo Former Member
          Former Member
          Hi Satyajit,

          Thanks for this blog.

          I find this solution a little risky due to using static singleton, which is not session dependent, meaning that the external context will be replaced by latest one. Am I right?

          Here is my blog related to this topic for your reference:

          Sharing session context between parent and external windows running on same host

          Regards,
          -William

          Author's profile photo Former Member
          Former Member
          Hi William,
             Thanks for the comments. I admit that the solution is a little risky. Thread safety has not been taken care of and only the latest context can be accessed.
            
             But in this case, I think using WDScopeUtil is not the answer.

             I went through your blog - it's a nice one.

          Regards,
          Satyajit.

          Author's profile photo Former Member
          Former Member
          Hi,
          Thanks for such a helpful blog. but I think the application is not secured till we are getting the url of the application in the address bar. Is there a way to open the new window in a new browser and still keep the address bar blank or set to a default value? PLease help. Its a bit urgent.

          Thanks,

          Regards
          Kunal

          Author's profile photo Former Member
          Former Member
          Satyajit,

          I can't understand if is possible with ur tricks I receive the values of the second view. I'm using a HTML page with a applet that make a conection with a credit card system. This applet will receive a lot of data from the user. I need bring it to a table in my web dynpro app.
          If I follow ur webblog steps Will I solve my problem??

          Author's profile photo Andrea Mello
          Andrea Mello
          Hello,

          I've put in place your suggestions in a WDP test application, and everything is perfect.
          Now is it possible to apply these concepts beetween two WDP DCs?

          Thanks a lot,
          Andrea Mello