Chris Richards
Chris Richards

Reputation: 705

Xpages & DataTables

I'm using the dataTables jQuery plugin with xpages and have a custom control I drop onto any page, pass in a custom property of viewName and it will display a table using REST - All based on some great examples by Oliver Busse.

Everything works perfectly if this custom control is used on a basic page, however, if it is within a tab, which is not default, when I then click on the tab containing the control, I receive an error when calling viewjson.getId()

I think the issue is because I set viewjson on beforePageLoad?

Any idea how I can get this to work in a tabbed interface?

Code below:

<xp:this.beforePageLoad><![CDATA[#{javascript:var viewjson = new org.openntf.rest.DynamicView(compositeData.viewName);}]]></xp:this.beforePageLoad>
    <table
        id="#{javascript:viewjson.getId()}"
        class="table table-hover table-striped">
        <thead>
            <xp:repeat id="repeat1" rows="30" disableOutputTag="true"
                var="col">
                <xp:this.value><![CDATA[#{javascript:try {
viewjson.getCols()}
catch (e) {
openLogBean.addError(e,this)
}}]]></xp:this.value>
                <th>
                    <xp:text escape="true" disableTheme="true"
                        value="#{col}">
                    </xp:text>
                </th>
            </xp:repeat>
        </thead>
        <tbody></tbody>
    </table>

UPDATE

I've tried the following to try and load jQuery first

<xp:this.resources>
<xp:headTag
            tagName="script">
            <xp:this.attributes>
                <xp:parameter
                    name="type"
                    value="text/javascript" />
                <xp:parameter
                    name="src"
                    value="/xsp/.ibmxspres/.extlib/responsive/jquery/jquery.min.js" />
            </xp:this.attributes>
        </xp:headTag>
        </xp:this.resources>

And also this in xsp properties

xsp.client.script.dojo.djConfig="dojo-amd-factory-scan": false

But I'm still getting a blank page with no dojo elements displaying

Upvotes: 1

Views: 615

Answers (2)

Knut Herrmann
Knut Herrmann

Reputation: 30960

Custom control's beforePageLoad event gets executed when XPage is loaded already.
When later the tab is activated and with it the table is rendered the variable viewjson is gone.

One approach would be to put Java object into a composite data variable compositeData.viewjson in beforePageLoad and use it in table later. But, you would calculate all views for every tab before rendering page. In addition, this class is not serializable and couldn't be stored in composite data variable. You could make the class serializable though.

The better approach is to instantiate Java bean in table - without a beforePageLoad event:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <table
        id="#{javascript:
            var viewjson = new org.openntf.rest.DynamicView(compositeData.viewName);
            return viewjson.getId();
        }">
        <thead>
            <xp:repeat id="repeat1" rows="30" disableOutputTag="true"
                var="col" value="#{javascript: viewjson.getCols()}">
                <th>
                    <xp:text escape="true" disableTheme="true" value="#{col}">
                    </xp:text>
                </th>
            </xp:repeat>
        </thead>
        <tbody></tbody>
    </table>
</xp:view>

I tested the custom control above (ccView with property viewName) with this XPage

<?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"
    xmlns:xc="http://www.ibm.com/xsp/custom">
    <xp:br />
    <xp:panel id="tabs">
        <xe:djTabContainer id="tabContainer"
            selectedTab="djTabPane1" defaultTabContent="one">
            <xe:djTabPane id="djTabPaneView" title="one" closable="false"
                partialRefresh="true">
                tab rendered first
            </xe:djTabPane>
            <xe:djTabPane id="djTabPane2" title="two" closable="false"
                partialRefresh="true">
                <xc:ccView viewName="ByCity" />
            </xe:djTabPane>
            <xe:djTabPane id="djTabPane3" title="three" closable="false"
                partialRefresh="true">
                <xc:ccView viewName="ByName" />
            </xe:djTabPane>
        </xe:djTabContainer>
    </xp:panel>
</xp:view>

Views in tabs "two" or "three" get loaded per REST services when user clicks the respective tab.

Upvotes: 1

David Leedy
David Leedy

Reputation: 3593

I believe the main problem is that for the XPages core controls a non active tab is not actually rendered to the browser until it becomes active. So what you called in the beforePageLoad() was looking for content that didn't exist at the time. There's probably a CSJS thing that could re-init the data tables. Another option is to not use the tab core control but use the dojo version from the ext. library. I'm pretty sure that the dojo version renders all content and just uses CSS to hide non active tabs.

Upvotes: 2

Related Questions