The Artima Developer Community
Sponsored Link

Agile Buzz Forum
JSF: DataTable and CommandLink

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Dominik Wei-Fieg

Posts: 60
Nickname: dominikwei
Registered: Aug, 2005

Dominik Wei-Fieg is a software developer living and working in Freiburg, Germany
JSF: DataTable and CommandLink Posted: Feb 7, 2007 7:26 AM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by Dominik Wei-Fieg.
Original Post: JSF: DataTable and CommandLink
Feed Title: Ars Subtilior
Feed URL: http://typo.ars-subtilior.com/articles.rss
Feed Description: Finest Handmade Code Random thoughts about agile software development as an art
Latest Agile Buzz Posts
Latest Agile Buzz Posts by Dominik Wei-Fieg
Latest Posts From Ars Subtilior

Advertisement

Like a lot of other programmers who are forced to work with JSF, I fell into THE TRAP!

If you are using ManagedBeans in request scope, you get problems with CommandLinks inside DataTables.

DataTables are one thing I really like about JSF, and CommandLinks often come in handy as well. But when you put a CommandLink inside a DataTable, e. g., to select the entry of the row in which the CommandLink is, you get bitten. That is, if you want ManagedBeans with request scope. The action which should be triggered by the CommandLink is never triggered, the page is simply rendered again.

The reason for this behaviour is that the DataTable modifies the id of the CommandLink during renderering, but the CommandLink does not know that it was rendererd with a different id. During the decoding of the request which was triggered by clicking the CommandLink, the ComandLinkRenderer looks at a hidden form parameter. If the value of that form parameter equals the id of the CommandLink, an action is queued. If not, nothing is done.

Since the DataTable changes the ids, the value of the hidden form parameter does not match the id of the CommandLink.

So I wrote my own CommandLinkRenderer, overwrote the decode method and patched it so that the id match up again. When I want a CommandLink in a DataTable, I then specify that it should use my CommandLinkRenderer.

Here is the source of the decode method:

     @Override
    public void decode(FacesContext context, UIComponent component)
    {
        if (context == null || component == null)
        {
            throw new NullPointerException(Util
                    .getExceptionMessageString(Util.NULLPARAMETERSERRORMESSAGEID));
        }

    if (log.isTraceEnabled())
    {
        log.trace("Begin decoding component " + component.getId());
    }

    UICommand command = (UICommand) component;

    // If the component is disabled, do not change the value of the
    // component, since its state cannot be changed.
    if (Util.componentIsDisabledOnReadonly(component))
    {
        if (log.isTraceEnabled())
        {
            log.trace("No decoding necessary since the component "
                    + component.getId() + " is disabled");
        }
        return;
    }

    String clientId = command.getClientId(context), paramName = getHiddenFieldName(
            context, command);
    Map requestParameterMap = context.getExternalContext()
            .getRequestParameterMap();
    String value = (String) requestParameterMap.get(paramName);
    clientId = clientId.substring(0, clientId.lastIndexOf(":"));
    value = value.substring(0, value.lastIndexOf(":"));
    if (value == null || value.equals("") || !clientId.equals(value))
    {
        return;
    }
    ActionEvent actionEvent = new ActionEvent(component);
    component.queueEvent(actionEvent);

    if (log.isDebugEnabled())
    {
        log.debug("This command resulted in form submission "
                + " ActionEvent queued " + actionEvent);
    }
    if (log.isTraceEnabled())
    {
        log.trace("End decoding component " + component.getId());
    }
    return;
}

The diff to the original method is:

diff CommandLinkRenderer.java PatchedCommandLinkRenderer.java
124a125,126
>       clientId = clientId.substring(0, clientId.lastIndexOf(":"));
>       value = value.substring(0, value.lastIndexOf(":"));

It works form me, maybe others get some benefit from it as well.

(P.S. this is crossposted to http://forum.java.sun.com/thread.jspa?threadID=5116147)

Read: JSF: DataTable and CommandLink

Topic: TP 2.0 Quick Tour Previous Topic   Next Topic Topic: Uber agility

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use