Err, mixed things up. Should be value -> allProjects and binding -> projectTable.
Thanks Jörg -----Ursprüngliche Nachricht----- Von: Jörg Liegler [mailto:[EMAIL PROTECTED] Gesendet: Donnerstag, 2. Februar 2006 00:07 An: 'MyFaces Discussion'; [EMAIL PROTECTED] Betreff: AW: Need help with HtmlCommandLink inside a UIForm I believe i got the point of your question regarding the dataModel. - A null of UIData is served via getProjectTable and the current value is set via setProjectTable. - The binding of the component is a list of all current projects via getAllProjects. - As there is no corresponding setAllProjects on the value, do I have to revise what I know about the java bean convention(getter AND setter for a property to be recognized). Is usage of EL's propertyResolver a special case thereof? Following is the SelectProjectBean from source code of Manning's "JSF in Action". /** JavaServer Faces in Action example code, Copyright (C) 2004 Kito D. Mann. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. **/ package org.jia.ptrack.web; import java.util.ArrayList; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.component.UIData; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import org.jia.ptrack.domain.*; class CommandType extends EnumeratedType { public final static CommandType APPROVE = new CommandType(0, "Approve"); public final static CommandType REJECT = new CommandType(10, "Reject"); public final static CommandType DETAILS = new CommandType(20, "Details"); private CommandType(int value, String description) { super(value, description); } } public class SelectProjectBean extends BaseBean { private javax.faces.component.UIData projectTable; private ProjectColumnType sortColumn; private ResultSetProjectCoordinator rsProjectCoordinator; public SelectProjectBean() { } public UIData getProjectTable() { return projectTable; } public void setProjectTable(UIData projectTable) { this.projectTable = projectTable; } public List getInboxProjects() throws DataStoreException { try { return getProjectCoordinator().getProjects(getVisit().getUser().getRole(), sortColumn); } catch (ObjectNotFoundException e) { return new ArrayList(0); } } public List getAllProjects() throws DataStoreException { try { return getProjectCoordinator().getProjects(sortColumn); } catch (ObjectNotFoundException e) { return new ArrayList(0); } } public void sort(ActionEvent actionEvent) { Utils.log(getFacesContext(), "Inside sort; sender id = " + actionEvent.getComponent().getId()); sortColumn = (ProjectColumnType) ProjectColumnType.getEnumManager(). getInstance(actionEvent.getComponent().getId()); /* UIParameter-based way of perameterizing an action listener method. boolean paramFound = false; List children = e.getComponent().getChildren(); for (int i = 0; i < children.size(); i++) { if (children.get(i) instanceof UIParameter) { UIParameter currentParam = (UIParameter) children.get(i); if (currentParam.getName().equals("column") && currentParam.getValue() != null) { Utils.log(getFacesContext(), "Sorting by column " + currentParam.getValue()); String paramValue = currentParam.getValue().toString(); sortColumn = (ProjectColumnType) ProjectColumnType.getEnumManager(). getInstance(paramValue); paramFound = true; break; } } } if (!paramFound) { throw new FacesException("Expected child UIParameter with name 'column' and a value equal to the column name to sort."); } */ } public String approve() { return getProject(CommandType.APPROVE); } public String reject() { return getProject(CommandType.REJECT); } public String details() { return getProject(CommandType.DETAILS); } protected String getProject(CommandType command) { FacesContext facesContext = getFacesContext(); Utils.log(facesContext, "Executing GetProjectForm.getProject(), command = " + command); Project project = (Project) projectTable.getRowData(); // make sure it still exists try { project = getProjectCoordinator().get(project.getId()); } catch (ObjectNotFoundException e) { facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "The project you selected cannot be found", "The project is no longer in the data store.")); return Constants.FAILURE_OUTCOME; } catch (DataStoreException d) { Utils.reportError(facesContext, "A database error has occrred", "Error loading project", d); return Constants.ERROR_OUTCOME; } if (command == CommandType.APPROVE || command == CommandType.REJECT) { if (!getStatusCoordinator(). isValidStateChange(project.getStatus(), command == CommandType.APPROVE)) { Utils.addInvalidStateChangeMessage(facesContext, command == CommandType.APPROVE); return Constants.FAILURE_OUTCOME; } } getVisit().setCurrentProject(project); return Constants.SUCCESS_OUTCOME; } } -----Ursprüngliche Nachricht----- Von: Jörg Liegler [mailto:[EMAIL PROTECTED] Gesendet: Mittwoch, 1. Februar 2006 23:25 An: 'MyFaces Discussion'; [EMAIL PROTECTED] Betreff: AW: Need help with HtmlCommandLink inside a UIForm Hi Martin! Thank you first for your time and interest. - Yes, the commandLink is not firing it's action-listener. - I am not sure if I am using a dataModel over requests. I did not consider that detail. If it clears things out, would you mind to elaborate about his point? On the bottom is the page I am working with. It has been taken 1:1 out of the book "JSF in Action" as are their backing bean classes and other stuff. (But when I encountered this problem, I snipped away 4 not necessary columns to isolate the problem.) The author says he has been working with SUN JSF-RI. showAllBean is a request-scoped bean that is displaying a page with tabular output-only information about projects. In each column header is a "sort" link which orders the projects by e.g. name. The showAllBean is designed to be stateless, therefore it is request-scoped and to be recreated on each request-response cycle.(BTW it is backed by a facade-like referenced-bean that talks to business objects) The rendered "sort" link is not submitting the form, as intended, but just forwards to the input page again, transmitting some generated "_id1:_link_hidden_=id1:_id5:name" request values. Please note again that the form is not submitted by this link e.g. via javascript, it's the as-is default behaviour of HtmlCommandLink. Next I describe the observed essential behaviours by following the inbound path from the browser: - The view is restored including the action-listener. That is, it's method binding is attached to the UICommand's _actionListener variable.(UICommand class, restoreState method) - Afterwards in the ApplyRequestValues Phase, on decoding the tree outer-to inner element, the HTMLFormRenderer gets it's turn. Code Lines 15o to 152 say : if no "submitted" value found, set the state isSubmitted to false, which is as expected. - But then the thread returns to UIForm which in processDecodes code line 42 says: I am not submitted, so I return immediately from decoding. All it's childOrFacet components are __NOT__ decoded, as is my link that is contained in it's header. Hence the link's action-listener is not put on the event-queue and hence my bean is never called. This is the bottom-line of my post. I hope that this description does make more sense to you. Thanks a lot. Jörg P.S. Do you think the restored method binding of the action listener is still related to the showAllBean from the outbound response or to the newly created showAllBean upon the inbound request? <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view> <html> <head> <title> <h:outputText value="ProjectTrack - Show all projects"/> </title> <link rel="stylesheet" type="text/css" href="<%= request.getContextPath() %>/stylesheet.css"/> </head> <body class="page-background"> <h:form> <h:panelGrid headerClass="page-header" styleClass="table-background" columns="1" cellpadding="5"> <%-- Header --%> <f:facet name="header"> <h:outputText value="Show all projects"/> </f:facet> <%-- Panel data --%> <h:messages globalOnly="true" styleClass="errors"/> <!> <h:dataTable styleClass="table-background" rowClasses="table-odd-row,table-even-row" cellpadding="3" value="#{showAllBean.allProjects}" var="project" binding="#{showAllBean.projectTable}"> <h:column> <f:facet name="header"> <h:commandLink styleClass="table-header" id="name" actionListener="#{showAllBean.sort}"> <h:outputText value="Project name"/> </h:commandLink> </f:facet> <h:outputText value="#{project.name}"/> </h:column> </h:dataTable> </h:panelGrid> </h:form> </body> </html> </f:view> -----Ursprüngliche Nachricht----- Von: Martin Marinschek [mailto:[EMAIL PROTECTED] Gesendet: Mittwoch, 1. Februar 2006 19:57 An: MyFaces Discussion Betreff: Re: Need help with HtmlCommandLink inside a UIForm Hi Jörg, what is not working - I think I don't understand you. The commandLink is not firing? Are you using a dataTable-model which is stored over requests? regards, Martin On 2/1/06, lij <[EMAIL PROTECTED]> wrote: > Hi! > > I have the following page setup : > UIViewRoot->UIForm->HTMLPanelGrid->HTMLDataTable...->UIColumn->HtmlComma ndLink > registered with an ActionLister to do some column sorting inside a > table. When I click on the HtmlCommandLink, the view gets restored, but > in applyRequestValues Phase's processDecode coming to the UIForm Element > the following happens : if (!isSubmitted()) return; and my > HtmlCommandLink never gets a chance to be triggered. > > To not set the form to the submitted state is okay, because it is not > true. But as of now i can think of no special reason why my > HtmlCommandLink should not be triggered. > > public void processDecodes(javax.faces.context.FacesContext context) > { > if (context == null) throw new NullPointerException("context"); > decode(context); > if (!isSubmitted()) return; > for (Iterator it = getFacetsAndChildren(); it.hasNext(); ) > { > UIComponent childOrFacet = (UIComponent)it.next(); > childOrFacet.processDecodes(context); > } > } > > Took me a a couple of hours to figure this out! Any suggestion or idea? > Is this problem known to the community? > > Cheers Jörg > -- http://www.irian.at Your JSF powerhouse - JSF Consulting, Development and Courses in English and German Professional Support for Apache MyFaces

