Skip to Content

 

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.

       

      To report this post you need to login first.

      10 Comments

      You must be Logged on to comment or reply to a post.

      1. 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 @};-

        (0) 
      2. 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 ?

        (0) 
        1. 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.

          (0) 
        1. 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.

          (0) 
      3. 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

        (0) 
      4. 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??

        (0) 
      5. 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

        (0) 

      Leave a Reply