Third approach: use the Seam Remoting JavaScript library to access backend Seam components directly when a page event happens.
[plug]
This is part of my blog series on Ajax with Seam+JSF+Facelets. Sample code and detailed explanations are also covered in my book on Seam.
[/plug]
Advantage: You can access the backend components via JSF EL in the JavaScript calls. This approach works with any third party JavaScript library, and gives us the most flexibility. Plus, the Seam remoting library itself automatically handles the XML call and asynchronous callback.
Disadvantage: Some JavaScript coding is needed.
The following example shows how to use Seam remoting to implement the username check (check if the input username already exists in the database). The JavaScript obtains a stub reference to the manager component from the backend Seam context. The checkName() JavaScript method invokes the manager.checkName() backing bean method via AJAX to check whether the username is already in the database when the input field loses focus. When the backing bean method finishes, it makes a callback to the JavaScript method checkNameCallback(), which decides what message to render.
-
<script type="text/javascript"
-
src="seam/remoting/resource/remote.js">
-
</script>
-
-
<script type="text/javascript"
-
src="seam/remoting/interface.js?manager">
-
</script>
-
-
<script language="javascript">
-
// Seam.Remoting.setDebug(true);
-
-
// don't display the loading indicator
-
Seam.Remoting.displayLoadingMessage = function() {};
-
Seam.Remoting.hideLoadingMessage = function() {};
-
-
// Get the "manager" Seam component
-
var manager =
-
Seam.Component.getInstance("manager");
-
-
// Make the async call with a callback handler
-
function checkName () {
-
var e = document.getElementById("form:name");
-
var inputName = e.value;
-
manager.checkName(inputName, checkNameCallback);
-
}
-
-
function checkNameCallback (result) {
-
if (result) {
-
hideCheckNameError ();
-
} else {
-
showCheckNameError ();
-
}
-
}
-
</script>
The JSF component here is just a regular component with an ID that can be referenced from JavaScript methods, and UI event handler (e.g., onblur) associated with the above JavaScript methods.
-
<h:inputText id="name"
-
value="#{greeter.name}"
-
onfocus="hideCheckNameError()"
-
onblur="checkName()"
-
size="15"/>
-
<span id="nameError" style="display:none">
-
You have already said hello!
-
</span>
In order to access the backing bean method via Seam remoting, we have to tag it with the @WebRemote annotation in the EJB3 session bean interface.
-
@Local
-
public interface Manager {
-
... ...
-
-
@WebRemote
-
}
-
-
public class ManagerAction implements Manager {
-
-
... ...
-
-
-
"select g from Greeter g where name=:name")
-
.setParameter("name", name)
-
.getResultList();
-
-
if (existing.size() != 0) {
-
return false;
-
} else {
-
return true;
-
}
-
}
-
}
Of course, the example here is very simple and it can be easily accomplished by the Ajax4jsf approach as we have seen. But the real power of Seam remoting is that it exposes an API to JavaScript and hence allows us to work with any JavaScript library, such as Dojo and Rico, to integrate UI with server side components.
This concludes our blog series on Ajax and Seam+JSF+Facelets.