On Wed, Sep 9, 2009 at 12:33 AM, Lincoln Baxter, III <lincolnbaxter@gmail.com> wrote:
One more issue I'd like to bring up: it appears that when using <f:valueChangeListener action="..." /> the value of the object provided has not yet been updated in the model, hence, the value is the old value, not the new value.

When using <f:actionListener> on the button submitting the values, the new value is populated into the model instead... which is the behavior I would expect.

Pardon the probably obvious question...

Is there an contract with valueChangeListeners that states they fire before model updates? I see in the spec that it fires: "when a new local value has been created, and has passed all validations," but nothing about if the model has been updated or not.

They're fired after the Process Validations phase (or Apply Request Values if immediate=true), which always occurs before the Update Model phase. The idea is that the input must be in a valid state before the model is updated.

--Lincoln


On Tue, 2009-09-08 at 09:59 -0700, Ryan Lubke wrote:
On 9/7/09 6:06 PM, Andy Schwartz wrote:
> Thanks Lincoln.  I haven't had time to debug this, but I have a theory 
> about what might be happening.  In your sample:
>
>> <a:editText value="#{cc.attrs.task.text}" 
>> rendered="#{!cc.attrs.disabled}">
>> *<f:actionListener for="submit" 
>> action="#{taskController.saveTaskAjax(cc.attrs.story, 
>> cc.attrs.task)}" /> *
>> </a:editText>
>
> We expect "cc" to resolve to the containing composite component (ie. 
> to the <socialpm:taskBlock> component).  I wouldn't be surprised if 
> what is actually happening is that "cc" is  being resolved to the 
> <a:editText> composite component instead.
Yep, that's what is happening.
> One reason why I suspect this might be happening is that I know that 
> Ryan has investigated/resolved similar problems not too long ago.
The problem we resolved was the passing of #{cc.attrs} attributes 
between nested composite components.
For this case, the spec recommends using cc.parent.attrs.story and 
cc.parent.attrs.task, where parent resolves
to the nearest composite component parent of the current composite 
component.
> Another reason why I am suspicious about this is because we have faced 
> similar issues in our own (ADF Faces) declarative component solution.  
> This stuff can get tricky. :-)
>
> Hey Ryan -
>
> Does this problem look familiar?  Any thoughts on this?
>
> Andy
>
> Lincoln Baxter, III wrote:
>> Hey Andy, here you go:
>>
>> In the mean time I'm going to sign up for the dev lists.
>>
>> ----------------------------------------------------------------------
>> Using:
>> <f:actionListener for="submit" 
>> action="*#{taskController.saveTaskAjax(cc.attrs.story, 
>> cc.attrs.task)}*" />
>>
>>     *#{taskController.saveTaskAjax(cc.attrs.story, cc.attrs.task)}* =
>>     null values passed to method
>>     *#{taskController.saveTaskAjax(currentStoryBean.story, task)}* =
>>     correct values resolved, assuming currentStoryBean.story and task
>>     are both in the EL/page scope somewhere.
>>
>>
>> ----------------------------------------------------------------------
>> *CC Impl:*
>>
>>
>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
>>         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
>> <html xmlns="http://www.w3.org/1999/xhtml"
>> xmlns:h="http://java.sun.com/jsf/html"
>> xmlns:f="http://java.sun.com/jsf/core"
>> xmlns:a="http://java.sun.com/jsf/composite/ajax"
>> xmlns:cc="http://java.sun.com/jsf/composite">
>> <cc:interface>
>> <cc:attribute name="story" required="true" type="Object" />
>> <cc:attribute name="task" required="true" type="Object" />
>> <cc:attribute name="disabled" required="false" type="Boolean" 
>> default="false" />
>> <cc:insertChildren />
>> </cc:interface>
>>
>> <cc:implementation>
>> <h:outputStylesheet name="socialpm/socialpm.css" />
>> <h:panelGroup id="taskBlock" layout="block" class="box-bordered p5 
>> #{cc.attrs.styleClass} taskBlock_#{cc.attrs.task.status}" 
>> style="#{cc.attrs.style}">
>>
>> <div class="m5l" style="margin-right: 25px;" >
>> <h:outputText value="#{cc.attrs.task.text}" 
>> rendered="#{cc.attrs.disabled}"/>
>> <a:editText value="#{cc.attrs.task.text}" 
>> rendered="#{!cc.attrs.disabled}">
>> *<f:actionListener for="submit" 
>> action="#{taskController.saveTaskAjax(cc.attrs.story, 
>> cc.attrs.task)}" /> *
>> </a:editText>
>> </div>
>> </cc:implementation>
>> </html>
>>
>>
>> ----------------------------------------------------------------------
>> *consuming page code:* <-- this is where task is defined in the 
>> UI:Repeat, so it is in scope
>>
>> <!DOCTYPE html
>>       PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
>>       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
>> <html xmlns="http://www.w3.org/1999/xhtml"
>> xmlns:c="http://java.sun.com/jsp/jstl/core"
>> xmlns:f="http://java.sun.com/jsf/core"
>> xmlns:h="http://java.sun.com/jsf/html"
>> xmlns:socialpm="http://java.sun.com/jsf/composite/socialpm"
>> xmlns:pretty="http://ocpsoft.com/prettyfaces"
>> xmlns:ui="http://java.sun.com/jsf/facelets" xml:lang="en" lang="en">
>>
>> <ui:composition>
>> <h:form id="tasksForm">
>> <c:if test="#{empty currentStoryBean.story.tasks}">
>> <div class="m5">This story has no tasks. That could be a problem 
>> later...</div>
>> </c:if>
>>
>> <ui:repeat value="#{currentStoryBean.story.tasks}" var="task">
>> <socialpm:taskBlock task="#{task}" story="#{currentStoryBean.story}"
>> members="#{currentProjectBean.project.activeMembers}"
>> disabled="#{!authorizationBean.isMember or 
>> !currentStoryBean.story.open}"
>> deletable="true" styleClass="m5t" refreshOnSave="false" />
>> </ui:repeat>
>> </h:form>
>> </ui:composition>
>> </html>
>>
>>
>>
>>
>> On Sat, 2009-09-05 at 15:23 -0400, Andy Schwartz wrote:
>>> Hey Lincoln -
>>>
>>> Lincoln Baxter, III wrote:
>>> > First, please let me know if there is a better place to ask JSF 
>>> Dev > related questions.
>>> >
>>>
>>> I suppose the Mojarra dev list might be the right place for 
>>> implementation questions:
>>>
>>> https://javaserverfaces.dev.java.net/mailinglists.html
>>>
>>> Though personally I am fine with you asking here. :-)
>>>
>>> Could you send along your composite component implementation (and 
>>> perhaps a snippet from the consuming page)?  Just want to make sure 
>>> I understand the use case.
>>>
>>> Andy
>>>
>>>
>> -- 
>> *Lincoln Baxter, III*
>> Co-Founder of OcpSoft <http://ocpsoft.com>
>> Author of PrettyFaces <http://ocpsoft.com/prettyfaces> URL Rewriting 
>> for JSF
>>
>>
>

--

Lincoln Baxter, III
Co-Founder of OcpSoft
Author of PrettyFaces URL Rewriting for JSF