dominoGuru.com

Your Development & Design Resource

IBM XPages Dojo borderContainer Layout Custom Control

Extending the Extension Library xe:djBorderContainer, this take on a "Lotus Notes Client frameset" for XPages shows how we can create a reusable layout-type Custom Control that provides an alternative to an OneUI application layout.

Now while I don't hate OneUI themeing for XPages applications, I think it's absolutely critical to the adoption of XPages as an application services platform that we show the ability to serve alternative application UIs lest people unfamiliar with the technologies at play think XPages is OneUI...

Let's kick things off with an overview of the desired end-result:

IBM XPages Dojo borderContainer Layout Custom Control

This wireframe/mockup of the Dojo borderContainer (seen below) shows off a headline layout configuration. Alternately, there's a sidebar option that gives us a more traditional Lotus Notes client frameset-layout.

There are also various configuration options (such as enabling liveSplitters, which allows the user to resize the "frames") which we'll want to support.

The basic setup of an xe:djBorderContainer layout looks like this:

<xe:djBorderContainer>

    <xe:djContentPane>
        top
    </xe:djContentPane>

    <xe:djContentPane>
        leading
    </xe:djContentPane>

    <xe:djContentPane>
        center
    </xe:djContentPane>

    <xe:djContentPane>
        trailing
    </xe:djContentPane>

    <xe:djContentPane>
        bottom
    </xe:djContentPane>

</xe:djBorderContainer>

This is, of course, sans any functional properties. But it should give you an idea of the basic setup:

The xe:djBorderContainer uses xe:djContentPane children controls to act as a container for each "frame". The order I've used here - top, leading, center, trailing, bottom - is more for visual/logical flow and has absolutely nothing to do with function: position of a "frame" has nothing to do with position, but rather the "region" attribute on the generated HTML DIV (which the Dojo library runs with to create the frame/frameset layout).

To make our xc:layout Custom Control as dynamic and configuration-controlled as possible, we'll want to wire as many xe:djBorderContainer and xe:djContentPane properties to the Properties of the Custom Control.

The cool thing about an xe:djBorderContainer is that you can either use the xe:djContentPane as a standard xp:div-like "container" Control, or use the AJAX-driven "scraping" abilities to create an iframe-like container for any content from within the same domain (or cross-domain should you choose to employ an XAgent -- for example -- to interact with an external web service).

Let's take a look at a configured xc:layout first to get an idea of the various options you'll have for populating your "frameset" layout:

<xc:layout>
    <xp:this.facets>
        <xp:div
            xp:key="contentPane_top_bodycontent">
            <xp:text tagName="h1" styleClass="heading" value="#{javascript:@DbTitle();}" />
        </xp:div>
    </xp:this.facets>
    <xc:this.borderContainer>
        <xc:borderContainer
            bC_gutters="true"
            bC_liveSplitters="true"
            bC_design="sidebar"
            bC_parseOnLoad="true"
            bC_persist="true">
        </xc:borderContainer>
    </xc:this.borderContainer>
    <xc:this.contentPane_bottom>
        <xc:contentPane_bottom
            cP_region="bottom"
            cP_splitter="true">
        </xc:contentPane_bottom>
    </xc:this.contentPane_bottom>
    <xc:this.contentPane_center>
        <xc:contentPane_center
            cP_region="center"
            cP_splitter="true">
        </xc:contentPane_center>
    </xc:this.contentPane_center>
    <xc:this.contentPane_leading>
        <xc:contentPane_leading
            cP_region="leading"
            cP_splitter="true"
            cP_href="navigation.xsp"
            cP_extractContent="false"
            cP_loadingMessage="Loading application navigation controls..."
            cP_maxSize="350"
            cP_minSize="200"
            cP_parseOnLoad="true">
        </xc:contentPane_leading>
    </xc:this.contentPane_leading>
    <xc:this.contentPane_top>
        <xc:contentPane_top
            cP_region="top"
            cP_splitter="false">
        </xc:contentPane_top>
    </xc:this.contentPane_top>
    <xc:this.contentPane_trailing>
        <xc:contentPane_trailing
            cP_region="trailing"
            cP_splitter="true"
            cP_rendered="false">
        </xc:contentPane_trailing>
    </xc:this.contentPane_trailing>
</xc:layout>

Here we're using a combination of XPage markup (in the "top" xe:djContentPane), "scraped" XPages (in the "leading" and "center" xe:djContentPanes). We'll also be using a "scraped" download.html Page Design Element for the Demo download. We're also telling the "trailing" xe:djContentPane to not render, again all driven via the configuration of the xc:layout Custom Control.

Now let's take a look at the XPage markup for the xc:layout Custom Control:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    dojoParseOnLoad="true"
    dojoTheme="true">

    <xp:this.resources>
        <xp:styleSheet
            href="/screen.css" />
        <xp:script
            src="/screen.js"
            clientSide="true">
        </xp:script>
    </xp:this.resources>

    <xe:djBorderContainer
        id="djBorderContainer_layout"
        design="#{compositeData.borderContainer.bC_design}"
        dir="#{compositeData.borderContainer.bC_dir}"
        gutters="#{compositeData.borderContainer.bC_gutters}"
        liveSplitters="#{compositeData.borderContainer.bC_liveSplitters}"
        persist="#{compositeData.borderContainer.bC_persist}"
        rendered="#{compositeData.borderContainer.bC_rendered}"
        styleClass="#{compositeData.borderContainer.bC_styleClass}"
        themeId="${compositeData.borderContainer.bC_themeId}">

        <xe:djContentPane
            id="djContentPane_top"
            dir="#{compositeData.contentPane_top.cP_dir}"
            errorMessage="#{compositeData.contentPane_top.cP_errorMessage}"< /span>
            extractContent="#{compositeData.contentPane_top.cP_extractContents}"
            href="#{compositeData.contentPane_top.cP_href}"             loadingMessage="#{compositeData.contentPane_top.cP_loadingMessage}"
            partialRefresh=

About the author: Chris Toohey

Thought Leadership, Web & Mobile Application Development, Solutions Integration, Technical Writing & Mentoring

A published developer and webmaster of dominoGuru.com, Chris Toohey specializes in platform application development, solutions integration, and evangelism of platform capabilities and best practices.



More from dominoGuru.com


dominoGuru.com is powered by IBM Notes Domino XPages & hosted by Prominic.NET

Contact Us

Use our Contact / Feedback form or one of these email addresses:

Creative Commons License

Except where otherwise noted, dominoGuru.com by Chris Toohey is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.