2

I am using JSF 2.2.4 with the following in head tag:

<h:outputScript library="javax.faces" name="jsf.js" />

Later I found following post and removed the above code as it will be included automatically: renaming jsf.js.jsf to jsf.js.xhtml

When I checked found that it is included automatically as said but we are getting error with a script that is put in the head of common template. The error is the script is getting the object jsf as undefined. The purpose of this script is to show a common loader for all JSF AJAX calls. The script is given below:

//To display loading indicator for all JSF f:ajax calls.
jsf.ajax.addOnEvent(function(data) {
  var ajaxstatus = data.status; // Can be "begin", "complete" and "success"
  switch (ajaxstatus) {
    case "begin": // This is called right before ajax request is been sent.
      wizShowAjaxLoader();
      break;
    case "complete": // This is called right after ajax response is received.
      wizHideAjaxLoader();
      break;
    case "success": // This is called when ajax response is successfully processed.
      // NOOP.
      break;
  }
});

I wonder why it is working when I explicitly include jsf.js. When I remove this, script is showing jsf object as undefined.

Community
  • 1
  • 1
Valsaraj Viswanathan
  • 1,473
  • 5
  • 28
  • 51

1 Answers1

3

You need to make sure that your script is invoked after javax.faces:jsf.js is being included, for the very simple reason that jsf is only defined in JavaScript scope when the javax.faces:jsf.js has been included (and executed).

In a nutshell, you need to make sure that the JavaScript code flow is like below:

var jsf = ...;
...
jsf.ajax.addOnEvent(...);

And thus not like so:

jsf.ajax.addOnEvent(...);
...
var jsf = ...;

One way of ensuring this is to include your script as <h:outputScript> in <h:body> with the target set to head.

<h:head>
    ...
</h:head>
<h:body>
    <h:outputScript name="yourscript.js" target="head" />
    ...
</h:body>

JSF will ensure that it ends up in HTML head after the auto-included scripts.

An alternative is to keep it in <h:head>, but set target to body.

<h:head>
    ...
    <h:outputScript name="yourscript.js" target="body" />
</h:head>

JSF will ensure that it ends up in very end of HTML body, so that it's basically executed right before DOM loaded event.

See also:

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • If so, I wonder why it is not showing any error when I move the loader display script from head to bottom of body. When I inspected with firebug, jsf.js is called on the page load. – Valsaraj Viswanathan Jul 02 '15 at 08:24
  • You didn't state that anywhere in the question. I'll update the answer. – BalusC Jul 02 '15 at 08:29