jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: Validate client IDs in f:ajax execute and render

From: Bauke Scholtz <balusc_at_gmail.com>
Date: Wed, 27 Jul 2016 11:58:03 +0200

Hi Leo,

I just took the opportunity to test MyFaces 2.2.10 on this. It throws an
exception on this.

javax.faces.FacesException: Component with id::form:list:1:item not found
    at
org.apache.myfaces.renderkit.html.HtmlAjaxBehaviorRenderer.getComponentId(HtmlAjaxBehaviorRenderer.java:495)
    at
org.apache.myfaces.renderkit.html.HtmlAjaxBehaviorRenderer.build(HtmlAjaxBehaviorRenderer.java:467)
    at
org.apache.myfaces.renderkit.html.HtmlAjaxBehaviorRenderer.mapToString(HtmlAjaxBehaviorRenderer.java:439)
    at
org.apache.myfaces.renderkit.html.HtmlAjaxBehaviorRenderer.makeAjax(HtmlAjaxBehaviorRenderer.java:158)
    at
org.apache.myfaces.renderkit.html.HtmlAjaxBehaviorRenderer.getScript(HtmlAjaxBehaviorRenderer.java:102)
    at
javax.faces.component.behavior.ClientBehaviorBase.getScript(ClientBehaviorBase.java:101)


It's exactly that validation which's being discussed here. Mojarra removed
the validation, but I find that it should be brought back because starters
start complaining that ajax "doesn't work". It appears that this validation
is nowhere in the spec (at least, Manfred said so in
https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1372

Cheers, B


On Wed, Jul 20, 2016 at 9:04 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:

> > In my understanding, it works in MyFaces. Am I missing something?
>
> I meant the use case of specifying an absolute client ID referring a
> specific iteration round. E.g.
>
> <h:form id="form">
> <ui:repeat id="list" value="#{['one','two','three']}" var="item">
> <h:outputText id="item" value="#{item}" /><br/>
> </ui:repeat>
>
> <h:commandButton value="Update second item">
> <f:ajax render=":form:list:1:item" />
> </h:commandButton>
> </h:form>
>
> Cheers, B
>
>
>
> On Wed, Jul 20, 2016 at 1:49 AM, Leonardo Uribe <leonardo.uribe_at_irian.at>
> wrote:
>
>> Hi
>>
>> I would like to mention some issues mentioned in MyFaces some time ago,
>> related
>> to the behavior of this part of the spec.
>>
>> The discussion comes from this issue:
>>
>> - https://issues.apache.org/jira/browse/MYFACES-3542
>> The render attribute of AjaxBehavior should support late
>> value expression evaluation
>>
>> The issue is all about when "execute" and "render" attributes should be
>> evaluated. This point is critical if you want to validate the clientids
>> properly.
>>
>> The first point to remember is the values stored in f:ajax "execute" or
>> "render"
>> attribute are not clientIds. Instead, they are relative references to
>> component
>> instances, that in some cases, where the components are inside a
>> ui:repeat or
>> a h:dataTable, they are "virtual" or "row-specific".
>>
>> Checking MyFaces, there is a validation check inside f:ajax
>> ClientBehaviorRenderer. This validation throws a FacesException if the
>> component cannot be found. The algorithm use the existing findComponent,
>> but it is called twice, once with the reference and the other with the
>> separator and the reference.
>>
>> Let's take a look at the proposed options:
>>
>> BS>> 1. Strip off anything which matches the iteration index :[0-9]+:
>> from
>> BS>> f:ajax execute/render client ID before passing to findComponent()
>> for
>> BS>> validation.
>>
>> It won't work, because there is no reliable way to remove that, at least
>> with the current spec.
>>
>> BS>> 2. Improve findComponent to recognize the iteration index and act
>> BS>> accordingly.
>>
>> It looks like a simplification of UIComponent.invokeOnComponent(...) or
>> visitTree(...), but after you have the UIComponent instance, you don't
>> have
>> the context set, so it will not be the "real" instance. I don't see how it
>> can fit in the spec.
>>
>> But at this point, I have to say I think there is another bug on the RI.
>>
>> I found it was reported long time ago here:
>>
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-865
>> Ajax inside a DataTable (getClientId append rowIndex)
>>
>> And MyFaces fixed it in 2.0.1 (see MYFACES-2744 for details)
>>
>> BS>> Being able to reference a specific ui:repeat/h:dataTable item
>> BS>> via f:ajax render is absolutely a major step forward.
>>
>> In my understanding, it works in MyFaces. Am I missing something?
>>
>> regards,
>>
>> Leonardo Uribe
>>
>> 2016-07-19 1:58 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
>>
>>> There are basically two ways to solve this:
>>>
>>> 1. Strip off anything which matches the iteration index :[0-9]+: from
>>> f:ajax execute/render client ID before passing to findComponent() for
>>> validation.
>>> 2. Improve findComponent to recognize the iteration index and act
>>> accordingly.
>>>
>>> The first way is trivial. The second way, however, is best to implement
>>> if all repeater components (UIData and UIRepeat at least) share a common
>>> interface such as UIIterable. Only, this is not really nice for backwards
>>> compatibility.
>>>
>>> What do you think?
>>>
>>> Cheers, B
>>>
>>>
>>> On Mon, Jul 11, 2016 at 6:00 AM, Josh Juneau <juneau001_at_gmail.com>
>>> wrote:
>>>
>>>> +1, I think that since this change will help to clarify the spec for
>>>> newcomers, it is a good idea.
>>>>
>>>> Josh Juneau
>>>> juneau001_at_gmail.com
>>>> http://jj-blogger.blogspot.com
>>>> https://www.apress.com/index.php/author/author/view/id/1866
>>>>
>>>>
>>>> On Sun, Jul 10, 2016 at 5:39 AM, Bauke Scholtz <balusc_at_gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> Since Mojarra 2.2.5 (https://java.net/jira/browse/JAVASERVERFACES-2958)
>>>>> the f:ajax stopped validating client IDs in execute and render attributes
>>>>> with the reason to support updating a specific ui:repeat/h:dataTable
>>>>> iteration round such as render="form:repeat:0:item" which updates only the
>>>>> first item of ui:repeat.
>>>>>
>>>>> However, this has the side effect that new JSF users now start asking
>>>>> questions why f:ajax execute and/or render doesn't seem to have any effect
>>>>> while there's a clear syntax error or typo in the execute and/or render
>>>>> attribute. Previously they are been notified about this much sooner by a
>>>>> clear exception. It appears that this validation is not part of JSF spec.
>>>>>
>>>>> Therefore I propose to bring back validation of client ID in f:ajax
>>>>> execute and render attributes and make it part of the spec. I already
>>>>> created an issue on this:
>>>>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1372
>>>>>
>>>>> I only wonder what's the best place in spec to state that.
>>>>> AjaxBehavior class?
>>>>>
>>>>> Cheers, B
>>>>>
>>>>
>>>>
>>>
>>
>