Monday, March 30, 2015

Xpages : TabContainer : Dynamically Add Tabs in Java

When I was looking on the web for a way to add a page dynamically to a Tab Container in Xpages,
many sources were talking about CSJS (the dojo way addChild) or via SSJS createTab function of the extension library control.
I decided to use the Extension Library control, now I did want to control this via Java instead of CSJS/SSJS.
On the Ext. Lib control UIDojoTabContainer there’s a function called createTab().
When I tried to use this function it kept complaining, CreateTab is not a function.
Why? I really can't say… After some frustration and a good night sleep I came up with a different way using JSF.

On my Xpage I have defined a Tab Container with 1 page, this page holds our dynamic view panel.


    
        
    


In the custom control which holds our dynamic view panel, I have defined an onColumnClick event.


                           <![CDATA[#{javascript:var docId = viewEntry.getUniversalID();
//var noteId = viewEntry.getNoteID();
 
var number = viewEntry.getDocument().getItemValueString("jeNumber");
var formName = viewEntry.getDocument().getItemValueString("Form");
var baseURL = com.jacobs.JPI.Utils.GetXpageURL(formName + ".xsp");
var url = baseURL+ '?documentId='+docId+'&action=openDocument';
 
var tabContainer:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabContainer = getComponent("TabContainer");
 
if(Main.Navigation.currentPage.Controls.createTab(tabContainer, number, docId, url)){
       print("New Tab Created : " + number);
}else{
       print("Error creating new Tab");
}}]]>
                     
First we get the universal ID of the document, this will be used as the tab’s unique key,
second we get some text to display as a title on this tab
and then we compute the new URL of the document you want to open in a new tab.
We grab a handle on our TabContainer control and call a function in one of my managed java beans (Main).

com.mycompany.PageObject.Controls.createTab

com.mycompany.PageObject.Controls.createTab

import com.ibm.xsp.complex.Attr;
import com.ibm.xsp.component.UIPanelEx;
import com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabContainer;
import com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabPane;
              
public boolean createTab(UIDojoTabContainer tabContainer, String title, String unid, String url) {

                     try {
                           // create a new Tab
                           UIDojoTabPane newTab = new UIDojoTabPane();
                           newTab.setTitle(title);
                           newTab.setTabUniqueKey(unid);
                           newTab.setClosable(true);
                           // newTab.setHref(url); => does not work properly, un clickable content
                           
                           // create new Panel
                           UIPanelEx newPanel = new UIPanelEx();
                           newPanel.setId("IFrame" + unid);
                           newPanel.setStyle("height:700px;width:100%; overflow-y: auto");
                           // make an iFrame of this panel with our URL as src
                           newPanel.setTagName("iframe");
                           Attr property = new Attr();
                           property.setName("src");
                           property.setValue(url);
                           newPanel.addAttr(property);
                           
                           // add Panel to our new Tab
                           newTab.getChildren().add(newPanel);
                           
                           // add the new tab to our tab container
                           tabContainer.getChildren().add(newTab);
                     
                           return true;
                     } catch (Exception ex) {
                           Utils.WriteToConsole("Unable to add a new Tab Page to the Tab Container", ex);
                           return false;
                     }

}
First we create a new tab pane, we set some properties (title, unique key, closable tab).
You would think that using the href property, you can easily set the url you want the page to display.
Although this actually displays our xpage, the content becomes unusable (un-clickable).
Another way to display the xpage is by using an iframe…
To create a new iframe, we need to create a new panel UIPanelEx.
This panel needs some styling to set (mainly the height & width).
To transform this to an iframe you’ll need to specify the tagName ‘iframe’.
Of course we’ll need to provide our iframe with an URL, this is done by adding a special attribute ‘src’.
The attribute consists of a name ‘src’ and a value, the URL.

We then add the panel to our new tab page and the new tab page to our container,
by using the function component.getChildren().add(newcomponent).

Looking back this is in fact a very simple solution and easy to debug in Domino Designer.
For this point you can start building a library that controls the way you work with tabs in Java.
For instance, block the tab container of adding already added tabs…

  // check if the tab isn't already created if so just select it
   for (Object obj : tabContainer.getChildren()) {
    if (obj.getClass().getName().equalsIgnoreCase("com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabPane")) {
     newTab = (UIDojoTabPane) obj;
     if (newTab != null) {
      if (newTab.getTabUniqueKey().equalsIgnoreCase(unid)) {
          // tab already created, just select it and exit
          tabContainer.setSelectedTab(unid);
          return true;
      }
     }
    }
   }

Tuesday, March 17, 2015

Xpages : Connect RestService to a different database/server




Recently I found that it was not so well known that you actually can specify a server in the databaseName property of the Rest Service in Xpages.

So let's share this with the world ;-)

In the databaseName property of your RestService:

var databasePathName = "MyDatabase.nsf";
var serverName = "MyServer/MyOrg/MyDomain";
return serverName + "!!" + databasePathName;