3

I have used the Dynamic Content Control with a Dynamic Page formula a fair bit but it has always been computed on page load and not changed. I have been working on a test where I want to select what page to display based on a combo box and an onChange event. I have done a full refresh as well as several different partial refreshes, but it appears that the page is only computed on the page load. The pages that this calls don't do anything but display "Page One" "Page Two" etc. The print statements only print from the initial page load. I have done a partial refresh of "customeControlInclude" "dynamicContentView" and a full Update in the onChange event of the Combo Box, but none of these cause the dynamicControlView to change the page loaded.

So my question is "Is there a way to cause the dynamic Content Control to recompute and display appropriate page?

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom"
    xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:this.resources>
        <xp:script src="/js Utils.jss" clientSide="false"></xp:script>
    </xp:this.resources>
    <xp:panel id="thisPage">

        <xp:text escape="true" id="computedField1" value="#{sessionScope.ssSelectedView}"></xp:text>
        &#160;
        <xp:br></xp:br>
        <xp:br></xp:br>

        <xp:comboBox id="comboBox1" value="#{sessionScope.ssSelectedView}"
            style="width:20%">
            <xp:selectItem itemLabel="Test One"></xp:selectItem>
            <xp:selectItem itemLabel="Test Two"></xp:selectItem>
            <xp:selectItem itemLabel="Test Three"></xp:selectItem>
            <xp:selectItem itemLabel="Test Four">
            </xp:selectItem>


            <xp:eventHandler event="onchange" submit="true"
                refreshMode="partial" refreshId="thisPage">
            </xp:eventHandler>
        </xp:comboBox>
        <xp:br></xp:br>
        <xp:panel id="panelView">
            <xp:table>
                <xp:tr>
                    <xp:td style="width:100.0%" valign="top">
                        <xe:dynamicContent id="dynamicContentView">
                            <xp:include id="customControlIncluder">
                                <xp:this.pageName>
                                    <![CDATA[${javascript:try{
    var debug:Boolean = true;
    if (debug) print("Select Page in xpMainInput.xsp");
    var viewName:String = sessionScope.ssSelectedView;
    var page:String = null;
    switch(viewName){
        case "test One" :
            page = "ccTestOne.xsp";
            break;
        case "Test Two" :
            page = "ccTestTwo.xsp";
            break;
        case "Test Three" :
            page = "ccTestThree.xsp";
            break;
        case "Test Four" :
            page = "ccTestFour.xsp";
            break
        //Add additional case statements for each additional Application
    }
    if (page == null){
        if (debug) print("Error in Main page is null ");
        return "ccTestOne.xsp";
    }else{
        if (debug) print("xpMain page = " + page)
        return page;
    }
}catch(e){
    print("Error Define Page in xpMain.xsp " + e.string());
}}]]>
                                </xp:this.pageName>
                            </xp:include>
                        </xe:dynamicContent>
                    </xp:td>

                </xp:tr>
            </xp:table>
        </xp:panel>
    </xp:panel>
</xp:view>
Abubakr Dar
  • 4,078
  • 4
  • 22
  • 28
Bill F
  • 2,057
  • 3
  • 18
  • 39

2 Answers2

2

You can load different custom controls dynamically if you redirect to the same page instead of a full or partial refresh and write the desired custom control name into a session scope variable before.

Your test XPage could look like this then:

    <xp:comboBox id="comboBox1" value="#{sessionScope.ssSelectedView}"
        style="width:20%">
        <xp:selectItem itemLabel="Test One" itemValue="ccTestOne.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Two" itemValue="ccTestTwo.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Three" itemValue="ccTestThree.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Four" itemValue="ccTestFour.xsp"></xp:selectItem>

        <xp:eventHandler event="onchange" submit="true"
            refreshMode="norefresh">
            <xp:this.action><![CDATA[#{javascript:
                facesContext.getExternalContext().redirect(context.getUrl().toString())
            }]]></xp:this.action>
        </xp:eventHandler>
    </xp:comboBox>

    <xp:br></xp:br>

    <xp:panel id="panelView">
        <xp:table>
            <xp:tr>
                <xp:td style="width:100.0%" valign="top">
                    <xp:include id="customControlIncluder">
                        <xp:this.pageName>
                            <![CDATA[${javascript:
                                !sessionScope.ssSelectedView ? "ccTestOne.xsp" : sessionScope.ssSelectedView
                            }]]>
                        </xp:this.pageName>
                    </xp:include>
                </xp:td>
            </xp:tr>
        </xp:table>
    </xp:panel>

As an alternative, you can add all custom controls to your XPage with a repeat control with option repeatControls="true" and render only one custom control at a time depending on scope variable. This works with a partial refresh.

    <xp:comboBox id="comboBox1" value="#{sessionScope.ssSelectedView}"
        style="width:20%">
        <xp:selectItem itemLabel="Test One" itemValue="ccTestOne.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Two" itemValue="ccTestTwo.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Three" itemValue="ccTestThree.xsp"></xp:selectItem>
        <xp:selectItem itemLabel="Test Four" itemValue="ccTestFour.xsp"></xp:selectItem>

        <xp:eventHandler event="onchange" submit="true"
            refreshMode="partial" refreshId="repeatCc">
        </xp:eventHandler>
    </xp:comboBox>

    <xp:br></xp:br>

    <xp:panel id="panelView">
        <xp:table>
            <xp:tr>
                <xp:td style="width:100.0%" valign="top">
                    <xp:repeat
                        id="repeatCc"
                        rows="100"
                        repeatControls="true"
                        var="cc"
                        value="#{javascript:['ccTestOne.xsp','ccTestTwo.xsp','ccTestThree.xsp','ccTestFour.xsp']}">
                        <xp:include
                             pageName="${cc}"
                             rendered="#{javascript: !sessionScope.ssSelectedView ? (cc === 'ccTestOne.xsp') : (cc === sessionScope.ssSelectedView)}" />
                    </xp:repeat>
                </xp:td>
            </xp:tr>
        </xp:table>
    </xp:panel>
Knut Herrmann
  • 30,880
  • 4
  • 31
  • 67
  • That looks like it would work well I was just trying to do it at the lowest level (partial Refresh) but in this case the redirect would probably not be that bad an option. Thanks – Bill F Feb 17 '15 at 00:20
  • I added another approach which works with partial refresh and is flexible too. – Knut Herrmann Feb 17 '15 at 07:33
  • Knut - I like the second option best, never thought of going in that direction. The Repeat Control is really powerful. – Bill F Feb 17 '15 at 15:49
  • Actually the repeat control introduces some unexpected side issues. I have some rendered areas on some of the pages that I call and because the rendered comes after the invoke Application so some code in the un-rendered repeats gets fired which really causes some unexpected results. I believe the first solution will solve this as the pages are not loaded. as an example I have the same custom control with an after page load event and this control is on several of the pages so the after Page load event fires several times and messes everything up. So back to the drawing board. – Bill F Feb 23 '15 at 03:39
0

As described above the value for the pageName can only be resolved on page load. I have used this block of code for dynamically defining the page to load in several places but they have always been when loading a new XPage so it has been working fine. In the code above I was trying to force the pageName to be recomputed on a partial refresh. I even tried a full update but that does not recompute the pageName. Wish it would but then .... :-)

Bill F
  • 2,057
  • 3
  • 18
  • 39