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

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: Re: improvements to f:websocket and PushContext

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Fri, 28 Oct 2016 01:19:40 -0500

Hi

BS>> Usage of <h:commandScript name> is essentially exactly the same as
BS>> <f:ajax onevent>. Its vdldoc however merely states "The name of the
BS>> JavaScript function that will handle UI events". Should this also be
BS>> improved?

Well, to be honest f:ajax onevent is one of those things I really hate with
passion in JSF spec. I never understood that part. Let me show the defects
of the old solution and possible solutions to this defects.

The first defect is described in this spec issue:

https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-873
Add pre and post ajax transaction function callbacks

The description says this:

"... Use case: say the user wants to use some effect to fade in/out the
content to be updated via Ajax. It would be nice to have a way to install
pre-request and post request callback functions. On the post request, we
need to have actually two functions. One when we have the response but
have not yet done the replacement, and another after we have done the
replacement. ..."

The reason why this issue exists is there is no easy way to hook scripts to
f:ajax without define a function callback. In other words the callback
is not a good match for f:ajax.

The reason is developers are usually interested in perform actions before
and after the ajax operation, so why define a global function for something
that should be an attribute of f:ajax? Why do developers have to embed
all these lines of code?:

function onEventFunction(data) {
    var status = data.status; // Can be "begin", "complete" or "success".

    switch (status) {
        case "begin": // Before the ajax request is sent.
            // ...
            break;

        case "complete": // After the ajax response is arrived.
            // ...
            break;

        case "success": // After update of HTML DOM based on ajax response..
            // ...
            break;
    }
}

Instead this:

<f:ajax event="click" render="renderMe" onsuccess="do_something_useful"/>

No callback, no useless code, just what the developer really needs.

Think a bit radical further:

<f:ajax event="click" render="renderMe">
    <s:effectFade event="success" forId="panel"/>
</f:ajax>

A client behavior could have nested client behavior instances? Of course.
THAT SHOULD BE POSSIBLE IN THE SPEC.

Why do you want to write an ugly callback when you can declare what you
want
and encapsulate the client behavior in a graceful way?

h:commandScript fills the gap when you really need to call the script from
somewhere. Ok, I get it. But it is better if we can kill the callback and
instead prefer client behavior + strenght the event model.

If the callback is still required by whatever reason, let the user define
the "name" but if the user doesn't want to remember the function name use
a generated one derived from the clientId using an EL Function. This will
cover all possible combinations without any degradation over flexibility.

In summary:

- Client Behavior API has a mayor fault, and it is that you can't mix them.
- All ClientBehavior instances should implement ClientBehaviorHolder.
- f:ajax has 3 client behavior events : begin, complete and success.
- h:commandScript is a component that is useful but on situations where
the client behavior event model does not help, and you need to get your
hands dirty with javascript (a hack cannot be a substitute of an
abstraction).
- The changes proposed does not suppose any degradation over flexibility.
Instead, they are improvements that can be done on the way and that helps
to build more stable and reusable component units in JSF applications.

regards,

Leonardo Uribe

2016-10-27 3:15 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:

> Hi,
>
> Usage of <h:commandScript name> is essentially exactly the same as <f:ajax
> onevent>. Its vdldoc however merely states "The name of the JavaScript
> function that will handle UI events". Should this also be improved?
>
> Cheers, B
>
> On Wed, Oct 26, 2016 at 3:47 AM, Leonardo Uribe <leonardo.uribe_at_irian.at>
> wrote:
>
>> Hi
>>
>> NG>> Therefore I propose that the responsibility of namespacing the
>> NG>> h:commandScript "name" attribute be placed on the JSF portlet
>> developer,
>> NG>> and not on the FacesBridge or Faces Runtime.
>>
>> Sounds good to me. Maybe a warning in the tlddoc or javadoc of
>> h:commandScript
>> "name" would be helpful, to avoid later reports on the issue tracker.
>> Something like "... it is resposibility of the developer to choose a
>> naming
>> convention if the component could be rendered many times on the same view
>> ..."
>>
>> The important thing is one way or another, the way how to use "name" must
>> be clear to developers.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>>
>> 2016-10-25 18:28 GMT-05:00 Neil Griffin <neil.griffin_at_portletfaces.org>:
>>
>>> Sorry, typo: I should have written "responsibility of namespacing the
>>> h:commandScript ..." and not h:commandButton.
>>>
>>> > On Oct 25, 2016, at 7:19 PM, Neil Griffin <
>>> neil.griffin_at_portletfaces.org> wrote:
>>> >
>>> > @Bauke, @Leonardo: Thank you very much for considering the portlet
>>> case.
>>> >
>>> > Portlet developers are aware that they need to namespace JavaScript
>>> function names.
>>> >
>>> > I recently tried the following example with Pluto 3.0 + Mojarra 2.3
>>> and it worked fine:
>>> >
>>> > <?xml version="1.0" encoding="UTF-8"?>
>>> > <ui:composition xmlns="http://www.w3.org/1999/xhtml"
>>> > xmlns:h="http://xmlns.jcp.org/jsf/html"
>>> > xmlns:portlet="http://xmlns.jcp.org/portlet_3_0"
>>> > xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
>>> >
>>> > <portlet:namespace var="portletNamespace" />
>>> > <h:form>
>>> > <h:commandScript name="#{portletNamespace}myJsClientFunction"
>>> action="#{myBean.myJavaServerMethod('bar')}" render=":output" />
>>> > </h:form>
>>> > <button onclick="#{portletNamespace}myJsClientFunction()" />
>>> > <h:outputText id="output" value="#{myBean.output}" />
>>> >
>>> > </ui:composition>
>>> >
>>> > Therefore I propose that the responsibility of namespacing the
>>> h:commandButton "name" attribute be placed on the JSF portlet developer,
>>> and not on the FacesBridge or Faces Runtime.
>>> >
>>> >
>>> > Best Regards,
>>> >
>>> > Neil
>>> >
>>> >> On Oct 8, 2016, at 4:02 PM, Bauke Scholtz <balusc_at_gmail.com> wrote:
>>> >>
>>> >> Hi,
>>> >>
>>> >> I just added <f:ajax> support to OmniFaces <o:socket>:
>>> https://github.com/omnifaces/omnifaces/commit/6f0407c2d5d877
>>> d20025a7f249597cfce06c924d
>>> >>
>>> >> The basics work fine and it's indeed much more natural, but I still
>>> need to investigate and if necessary improve the behavior of "connected"
>>> and "rendered" attributes. Once I'm satisfied, I will rework f:websocket
>>> based on this.
>>> >>
>>> >> I will get back on h:commandScript+portlets later. This is a separate
>>> issue not related to f:websocket.
>>> >>
>>> >> Cheers, B
>>> >
>>>
>>>
>>
>