Chintan Parekh
Chintan Parekh

Reputation: 1101

XPages - Partial refresh accordion control from extension library

I am trying to do a partial refresh on my accordion control (from extension library). I have tried two approaches with no success.

Problem 1: I tried to put the accordion control inside a panel and tried to refresh the panel, however, this results in dojo error:

"Tried to register the widget with id==view:_id1:myaccordion but that id is already registered"

Problem 2: I tried to directly refresh the accordion by its id but then the accordion is broken. I can not destroy the accordion control as recommended on this link (http://www.mydominolab.com/2010/07/dijitdialog-inside-partial-refreshing.html) since it has many other issues and the link specifically deals with dialog control which is quite different from accordion.

Can you please suggest me something? Basically the accordion pane here displays the number of documents and I would like to do a timely refresh to update the count. Any help would really be appreciated.

Edit 1: Just adding a sample code for reference(This code would result in the problem 2 mentioned above and if surrounded by a panel and refreshed by panel id then problem 1 would arise):

<?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">
    <xp:button value="Refresh" id="button1">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="partial" refreshId="accordion1">
        </xp:eventHandler></xp:button>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xe:accordion id="accordion1">
        <xe:this.treeNodes>
            <xe:basicContainerNode label="Accordion 1">
                <xe:this.children>
                    <xe:basicLeafNode label="Category x"></xe:basicLeafNode>
                </xe:this.children>
</xe:basicContainerNode>
            <xe:basicContainerNode label="Accordion 2">
                <xe:this.children>
                    <xe:basicLeafNode label="Category y"></xe:basicLeafNode>
                </xe:this.children>
</xe:basicContainerNode>    

        </xe:this.treeNodes></xe:accordion>
</xp:view>

Edit 2: The above code does work when added a panel around it. It was my mistake to post it without testing that. However, I figured out that actual problem was Dojo layout which I am trying to use for the left navigation. Here is the sample code which breaks the accordion.

    <?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"
    pageTitle="S4EP TEAMGROUND"
    xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:button value="Refresh" id="button1">
        <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="myPanel">
        </xp:eventHandler></xp:button>
        <xp:div id="body" dojoType="dijit.layout.BorderContainer"
            style="height:100%;width:100%;align:center;">
            <xp:this.dojoAttributes>
                <xp:dojoAttribute name="persist" value="false"></xp:dojoAttribute>
                <xp:dojoAttribute name="gutters" value="false"></xp:dojoAttribute>
            </xp:this.dojoAttributes>
            <xp:div id="left" dojoType="dijit.layout.ContentPane"
                style="width:220px;height:50%">
                <xp:this.dojoAttributes>
                    <xp:dojoAttribute name="region" value="left"></xp:dojoAttribute>
                    <xp:dojoAttribute name="splitter" value="true"></xp:dojoAttribute>
                </xp:this.dojoAttributes>
                    <xp:panel id="myPanel">
<xe:accordion id="accordion1">
        <xe:this.treeNodes>
            <xe:basicContainerNode label="Accordion 1">
                <xe:this.children>
                    <xe:basicLeafNode label="Category x"></xe:basicLeafNode>
                </xe:this.children></xe:basicContainerNode>
            <xe:basicContainerNode label="Accordion 2">
                <xe:this.children>
                    <xe:basicLeafNode label="Category y"></xe:basicLeafNode>
                </xe:this.children></xe:basicContainerNode> 

        </xe:this.treeNodes></xe:accordion>
</xp:panel>

            </xp:div>
        </xp:div>
</xp:view>

Upvotes: 1

Views: 839

Answers (1)

Michael Saiz
Michael Saiz

Reputation: 1640

The Problem is when you partial refresh your accordion widget dojo does not create you widget again. You can workaround that by programatical creating the widget inside a script block. so if you refresh the panel with your script block it willl get executed again and recreate your widget:

<xp:div id="body"   dojoType="dijit.layout.BorderContainer" style="height:100%;width:100%;align:center;">
        <xp:this.dojoAttributes>
            <xp:dojoAttribute name="persist" value="false"></xp:dojoAttribute>
            <xp:dojoAttribute name="gutters" value="false"></xp:dojoAttribute>
        </xp:this.dojoAttributes>
        <xp:div id="left"   dojoType="dijit.layout.ContentPane" style="width:220px;height:50%">
            <xp:this.dojoAttributes>
                <xp:dojoAttribute name="region" value="left"></xp:dojoAttribute>
                <xp:dojoAttribute name="splitter" value="true"></xp:dojoAttribute>
            </xp:this.dojoAttributes>
            <xp:panel id="myPanel">
                <xp:panel id="leftAccordion">
                    <xp:scriptBlock type="text/javascript">
                        <xp:this.value><![CDATA[
                            dojo.require("dijit.layout.AccordionContainer");
                            dojo.require("dijit.layout.ContentPane");

                            XSP.addOnLoad(function() {
                                var aContainer = new dijit.layout.AccordionContainer({
                                    style: "width:220px;height:50%"
                                },
                                "#{id:leftAccordion}");

                                aContainer.addChild(new dijit.layout.ContentPane({
                                    title: "This is a content pane"
                                },'#{id:container1}'));

                                aContainer.addChild(new dijit.layout.ContentPane({
                                    title: "This is as well"
                                },'#{id:container2}'));

                                aContainer.startup();
                            });]]></xp:this.value>
                    </xp:scriptBlock>
                    <xp:panel id="container1">
                        <xp:text escape="true" id="computedField1">
                            <xp:this.value><![CDATA[#{javascript:"Entry "+ @Now().toLocaleTimeString();}]]></xp:this.value>
                        </xp:text>
                    </xp:panel>
                    <xp:panel id="container2">
                        <xp:text escape="true"  id="computedField2">
                            <xp:this.value><![CDATA[#{javascript:"Entry "+ @Now().toLocaleTimeString();}]]></xp:this.value>
                        </xp:text>
                    </xp:panel>
                </xp:panel>
            </xp:panel>
        </xp:div>
    </xp:div>

You can either use the container1 or container2 to add buttons to your accordion or create them also programatical see link. Here the Button with the partial refresh:

<xp:button
    value="Refresh"
    id="button1">
    <xp:eventHandler
        event="onclick"
        submit="true"
        refreshMode="partial"
        refreshId="myPanel">
    </xp:eventHandler>
</xp:button>

The only problem is that the accoridon gets closed again when you partial refresh the area but this solution worked for me in Firefox and IE10 =)

Upvotes: 1

Related Questions