Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

 

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 :wink: ), 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 :wink: if you are trying to pass some data back to the main window.

      That's it for now.

       

      10 Comments