Saturday, November 12, 2011

Primefaces global AJAX events

You can use jQuery global AJAX events with PrimeFaces to refactor behaviors that appear on multiple components.  A good example is if you have a data grid with multiple p:commandLinks and other controls that execute different methods and re-render the grid, and need to run the same onComplete in all of them.

For example, if you start with something like this:

<h:panelGroup id="grid">...</h:panelGroup>
<p:commandLink update="grid" actionListener="#{bean.update1}" onComplete="updateGrid()"/>
<p:commandLink update="grid" actionListener="#{bean.update2}" onComplete="updateGrid()"/>
<p:commandLink update="grid" actionListener="#{bean.update3}" onComplete="updateGrid()"/>

You could pull the updateGrid() statement out into an AJAX listener like this

jQuery(document).ajaxComplete(function(e, xhr, opts) {
  $response = jQuery(xhr.responseXML);
  if ($response.find("div[id$='grid']").length > 0) {
By using ajaxComplete and parsing the XHR response object, you can see which DIV was going to be impacted by the partial update.  That way, if you had some other AJAX controls (say, an autocompleter) that you didn't want to trigger the updateGrid() function, you could filter that out.  Another option would be to set global=false on the specific Primefaces components that you don't want to fire the global jQuery ajaxComplete event.  The Primefaces autocompleter doesn't support this in Primefaces 2.x but does in 3.0.  

Tuesday, November 08, 2011

Primefaces p:ajax and jQuery AJAX events

All of Primefaces' JSF components use the jQuery AJAX engine, which means you can catch global AJAX events with $(document).ajaxStart and $(document).ajaxStop.

Standard JSF components like h:selectOneMenu will also go through jQuery when using a p:ajax facet (vs. standard f:ajax).

Conversely, jsf.ajax.onEvent does not appear to work with Primefaces components as it does for f:ajax.  

See also:

IE9 and strict JSON checking

Got an error from IE9 complaining about "invalid character". Turned out this was because the JSON response string had control characters (newlines) in it. These need to be escaped.

Other browsers will let you get away with it, but IE9 is particularly strict and jQuery doesn't check the JSON response string before handing it off to JSON.parse.

 Similar issue found here: