3
votes

PrimeFaces conditionally renders the following in h:head:

<script type="text/javascript" src="/webapp/javax.faces.resource/push/push.js.jsf?ln=primefaces"><!--//--></script>

when PrimeFaces p:socket component is added to JSF/xhtml page. Some of my page refreshes, result in this push.js file 'not' being rendered in h:head.

When push.js file is 'not' rendered, I would like to conditionally render the push.js file in attempt to fix/workaround an issue I'm having with PrimeFaces Push.

For more details, please click PrimeFaces forum topic URL below:

Uncaught TypeError: undefined is not a function

I am asking this question, because I am already conditionally rendering h:head based on bean attribute values, such as the following:

<h:head rendered="#{!pageNavigationController.gmaps and !pageNavigationController.gmapsAutoComplete}">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="refresh" content="#{session.maxInactiveInterval};url=pf_viewExpired.jsf" />
    <title><h:outputText escape="false" value="MCMS"/></title>
    <h:outputStylesheet name="css/mcms.css"/>
    <h:outputScript name="js/mcms.js"/>
    <h:outputScript name="js/addUsingTemplate.js"
                    rendered="#{pageNavigationController.isPageSelected('/orders/pf_AddUsingTemplate.xhtml')}"/>
</h:head>

Maybe my use of h:head is making it difficult for the container TomEE 1.5 SNAPSHOT to serve the .js file, because of the conditional rendering of multiple h:head on the page, or this may actually be a PrimeFaces Push (Atmosphere) issue that ultimately needs to be solved, but I'm sure there is a way to render the .js file via h:outputScript, if the file is not rendered in h:head already.

The web application is using the following:

PrimeFaces 3.5 SNAPSHOT, TomEE 1.5 SNAPSHOT (Tomcat 7.0.32), JUEL 2.2.5, OmniFaces 1.3 SNAPSHOT

Please advise.

1
If there's no <h:head> been rendered during the push request, then that'd explain the problem. I'd rather use a single <h:head> which is always rendered and wrap the conditionally rendered children in an <ui:fragment>. Give it a try.BalusC
Some type of onload script 'might' be necessary. I think I may try to handle this in my login/servlet filter that I have in place already. If the .js file is not served, then set usersController.pushJSFileServed = false; if false, then onload, I can issue an AJAX request to serve the .js file and render p:socket again.Howard
BalusC, if I'm not mistaking, at least one of my h:head is always rendered. All of my resources (js and css files) are rendered, appropriately; it's just this push.js file is not always rendered in h:head for whatever reason. I'll try what you recommended though, thanks.Howard
@BalusC, I added one h:head as you suggested, and search-n-replace all other h:head with ui:fragment, and moved all the ui:fragment's inside of the one h:head. Tested app, and still duplicated this issue. I'm quite sure, if I can conditionally render the JS file when it's not rendered, then that should fix/workaround this issue.Howard

1 Answers

4
votes

This seems more like a PrimeFaces issue. In order to force loading of push.js on every request on the same view, you could explicitly add a

<h:outputScript library="primefaces" name="push/push.js" target="head" /> 

without conditional rendering. If everything went well, i.e. it behaves well as per JSF2 resource handling mechanism, then it should not be included twice at all in cases where it worked properly.