[Solved] Lazy Loading p:fieldset inside p:dataGrid

UI Components for JSF
Post Reply
xRinox
Posts: 12
Joined: 14 Jul 2010, 18:30

08 Nov 2010, 01:55

Hi,

I'm fairly new to PrimeFaces and want to make a nice vertical menu bar, like the one theme roller has. Main options can be all collapsed, in fact they first show all collapsed, and just in case there is a huge list of inner options inside one or more, i want to make these inner options lazy loaded when the parent is expanded. All these collections are dynamic and load depending of granted profiles. I made it till the dynamic main options loading, using a one column data grid of fieldsets. The above works nicely, but when I expand one fieldset and fire the toggleListener, the population of inner options in the backing bean doesn't refresh the new content inside the fieldset (which is a tree).

Here's the code from the view:

Code: Select all

        <h:form prependId="false" id="frmSideMenu">
            <p:dataGrid value="#{userController.sideMenu}" var="menuL1" columns="1">
                <p:column>
                    <p:fieldset toggleable="true" legend="#{menuL1.label}" collapsed="true"
                                toggleListener="#{menuL1.handleToggle}" onToggleUpdate="#{menuL1.id}Tree">
                        <p:outputPanel id="#{menuL1.id}Tree" >
                            <p:tree value="#{menuL1.root}" var="node" dynamic="true">
                                <p:treeNode>
                                    <h:outputText value="#{node}"/>
                                </p:treeNode>
                            </p:tree>
                        </p:outputPanel>
                    </p:fieldset>
                </p:column>
            </p:dataGrid>
        </h:form>
And here's the code for the inner option population when firing toggleListener:

Code: Select all

    public void handleToggle(ToggleEvent event) {
        if (root.getChildren().size() <= 0) {
            // Si no hay hijos, Popular los hijos del fieldset
            TreeNode auxNode = new DefaultTreeNode("Option 1", root);
            auxNode = new DefaultTreeNode("Option 2", root);
            auxNode = new DefaultTreeNode("Option 3", root);
        }
    }
I know the inner options are populated because when i make a page refresh i can see the inner options inside the expanded fieldset, but it seems the ajax update is done before the bean values. So there's no inmediate refresh :(. Maybe there's some tweaking to do using onToggleComplete or maybe using the ajax tag, maybe i have to do an ajax push?? I can't really tell, any help is more than welcome.
Last edited by xRinox on 09 Nov 2010, 05:12, edited 1 time in total.
PrimeFaces-2.2.RC2-SNAPSHOT, Mojarra 2.0.2 (FCS b10), Facelets, GlassFish 3.0.1

xRinox
Posts: 12
Joined: 14 Jul 2010, 18:30

09 Nov 2010, 05:11

It's me again! :oops:

Just wanted to document I figured out what was going on, maybe some other people will get around this problem too.

The thing with p:dataGrid is that it ensures inner id's overriding the ones assigned in the code, just like a form, generates a correlative id for the grid, then does the same thing with it's children, appending the grid id as a prefix ([generated grid id]:[generated child id]). Because of this, the content I wanted updated was never done.

Anyways, figuring it isn't posible to assign unique custom ids for my child components, chose asign one fixed id for all fieldset contents, so when i want to update one fieldset content, all fieldset contents are updated, this kind of update is smooth and won't affect performance i believe, its just drawing what's inside of the backing bean. But I have actually saved resources from collecting options from the database thanks to the Toggle handler which has the actual fieldset and collect the necesary records.

Well here's the code:

Code: Select all

<h:form prependId="false" id="frmSideMenu">
    <p:dataGrid value="#{userController.sideMenu}" var="menuL1" columns="1"
                id="gridSideMenu">
        <p:column>
            <p:fieldset toggleable="true" legend="#{menuL1.label}" collapsed="#{menuL1.collapsed}"
                     toggleListener="#{menuL1.handleToggle}" onToggleUpdate="gridSideMenu:content">
                <p:outputPanel id="content">
                    <p:tree value="#{menuL1.root}" var="doc" dynamic="true"
                            expandAnim="FADE_IN" collapseAnim="FADE_OUT">
                        <p:treeNode>
                            <h:outputText value="#{doc}"/>
                        </p:treeNode>
                    </p:tree>
                </p:outputPanel>
            </p:fieldset>
        </p:column>
    </p:dataGrid>
</h:form>
And a sligh change to the backing bean handler, thanks to this post: http://primefaces.prime.com.tr/forum/vi ... f=3&t=5429

Code: Select all

public void handleToggle(ToggleEvent event) {
    if (event.getVisibility().equals(org.primefaces.model.Visibility.VISIBLE)) {
        if (root.getChildren().size() <= 0) {
            // Si no hay hijos, Popular los hijos del fieldset
            TreeNode auxNode = new DefaultTreeNode("Option 1", root);
            auxNode = new DefaultTreeNode("Option 2", root);
            auxNode = new DefaultTreeNode("Option 3", root);
        }
        this.collapsed = false;
    } else this.collapsed = true;
}
My backing bean is Session scoped, that is because its an options menu that has to stick around all the time a user is logged, and that property sets the state for the collapsed/expanded fieldsets.

If someone can tell me a way to assign custom ids inside a datagrid, it'll be much appreciated.

Later.
PrimeFaces-2.2.RC2-SNAPSHOT, Mojarra 2.0.2 (FCS b10), Facelets, GlassFish 3.0.1

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 47 guests