Skip to main content

JSF2: problem executing scripts in Ajax response (bug-like)

3 replies [Last post]
vesuvius
Offline
Joined: 2007-06-02
Points: 0

I have been doing some experiments with PrimeFaces and I ran into a Mojarra behavior that I think could be improved.

So, I have a page that roughly looks like this:

Listing 1:

</p>
<p>

(Forget about the specifics of component. It could be some other component. That's not the main point.)

Ok, the page is supposed to get some input into the "inPhone" component and then, after pressing the Ajax-enabled button, to re-render both the "inPhone" and "outPhone" components.

The component has generated the following markup:

Listing 2:

</p>
<p>  PrimeFaces.onContentReady('form:inPhone', function() {<br />
  jQuery(PrimeFaces.escapeClientId('form:inPhone')).mask('(999) 999-9999')});</p>
<p>

After pressing the button, the Ajax response (reformatted for better readability) is:

Listing 3:

<br />
<?xml version="1.0" encoding="utf-8"?></p>
<p>      PrimeFaces.onContentReady('form:inPhone', function() { jQuery(PrimeFaces.escapeClientId('form:inPhone')).mask('(999) 999-9999')});<br />
      ]]></p>
<p>      The phone is: (123) 456-7890]]></p>
<p>

So, the response contains a script that must be executed at the client. But it does not get executed at all.

After some investigation, I found the following fragment in jsf.js, starting from line 927:

Listing 4:

<br />
                        ...<br />
                        runScripts(scripts);<br />
                    } else if (d.nodeName.toLowerCase() === 'input') {<br />
                        // special case handling for 'input' elements<br />
                        // in order to not lose focus when updating,<br />
                        // input elements need to be added in place.<br />
                        parserElement = document.createElement('div');<br />
                        parserElement.innerHTML = html;<br />
                        newElement = parserElement.firstChild;</p>
<p>                        cloneAttributes(d, newElement);<br />
                        deleteNode(parserElement);<br />
                    } else if (html.length > 0) {<br />
                        ...<br />
                        runScripts(scripts);<br />
                    }<br />
                    ...<br />

The runScripts(script) function does NOT get invoked for INPUT elements. But, as we see in Listing 2, "form:inPhone" is exactly an INPUT element. So, the script does NOT get executed and the component fails miserably. (It's not just the component that fails. Most of them do. I'm just using one of the components as an example.)

So, in PrimeFaces they have abandoned standard JSF2 Ajax and are using their own custom solution. If other libraries go this way, we will have a huge mess of Ajax-incompatible component libraries. We don't want that.

So, I would like to request the Mojarra team to upgrade the implementation a little bit -- to run scripts even for INPUT elements.

P.S. I understand, that if the component's implementation is wrapped inside a container element such as DIV or SPAN, the scripts will be executed. But that requires additional (arcane) knowledge. The idea of the JSF implementation is to "just work". It would be much better, if ALL scripts get executed, regardless of what element they are attached to.

(For further info, see my post on the PrimeFaces forum: http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=1312&start=10#p...)

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rogerk
Offline
Joined: 2004-05-06
Points: 0

I'll be looking into this.
We certainly don't want frameworks to do their own thing w/r/t JSF Ajax (again).
Compatibility is important.

vesuvius
Offline
Joined: 2007-06-02
Points: 0

Thanks!!!

vesuvius
Offline
Joined: 2007-06-02
Points: 0

Guys, could you, at least, tell me whether it's mandatory to put only one single child inside an [b]...[/b] tag in the Ajax response.

For example, [b]jsf.js[/b] contains code like the following:

[b]Listing 1:[/b]

[code]
var d = $(id);
...
replaceNode(parserElement.firstChild, d);
deleteNode(parserElement);
runScripts(scripts);
[/code]

In other words, only the [b]firstChild[/b] of the [b][/b] element is taken into account when updating the page contents. Something like the following will cause problems because it contains two children and the first one is a script (!!!) but it's a real-life partial response by PrimeFaces:

[b]Listing 2:[/b]

[code]



]]>

...

[/code]

It is really important for me to know whether [b]the specification[/b] requires only a single child. And it is important for me to know what the spec says about the other children. And it is important for me to know whether the response in Listing 2 is wrong.

[b]I have to know whether PrimeFaces must be fixed or whether Mojarra must be fixed.[/b] The PrimeFaces guys think that there's nothing worng with their implementation and that Mojarra must be fixed. As for me, I'm not sure which is right and which is wrong.

Could you comment on that, please?

This is a good time to clear up all the confusion [i]before[/i] the various component libraries are released and people start using them with all their incompatibilities and misunderstandings. Once a library is released, it will be very difficult for anyone to make big backward-incompatible changes.

EDIT: Could anyone direct me to an XML Schema (XSD) that can be used for validation of the JSF2 partial response?

EDIT 2: Found it -- http://java.sun.com/xml/ns/javaee/web-partialresponse_2_0.xsd