Getting Started with AngularFaces

Fork me on GitHubAs I mentioned in a previous post, AngularFaces is a JSF component library aiming to simplify JSF development significantly by allowing you to replace a lot of clever AJAX code by simple AngularJS code. Remember, in software engeneering cleverness is not always a virtue. You may be able to write clever code, but later it has to be maintained by someone else who doesn’t appreciate your ingenuity. The difficult part of software engeneering is not to write complicated code. The difficult part of software engeneering is writing simple code everybody can understand.

The AngularFaces approach to simplicity is to reduce the boiler plate code you have to write. Key features are

  • bringing JSR 303 annotations to the client,
  • labelled input fields
  • validating constraints as you type
  • and of course integrating AngularJS.

This article shows you an example consisting of merely three input fields. Even this tiny example is six lines shorter than the standard JSF version. At the end of the article you will know everything you need to get started with AngularJS.

Update Sept 16, 2014
AngularFaces 2.0 takes a different – and better – approach to adding fuctionality to JSF. This article describes the older version AngularFaces 1.0. Have a look at the tutorial at AngularFaces.com if you’re interested in AngularFaces 2.0 and above.

Setting up your IDE

At first, you have to download the AngularFaces.jar from the AngularFaces project’s GitHub repository. It suffices to put it in your JSF projects library folder. You also have to use Primefaces 4 and either Mojarra 2.2+ or Apache MyFaces 2.2+.

At the time of writing, it may be better to simple clone the GitHub project or to download the zip file. Doing so you get an Eclipse 4.2 project including compatible libraries. Mind you, Primefaces 4 hasn’t been released yet, so you had to build it from source otherwise. If you start by cloning my project, you either have to install the Groovy plugin or to convert the controller class to Java. That’s not a big deal; it suffices to rename the file, add missing semicolons (if any) and generate the getters and setters. I prefer to use Groovy in this blog because it allows for showing more concise code to you. After all, this web site is BeyondJava.net, not Java.net :).

The project is a Tomcat project. Add it to your Tomcat server and start the file WebContent/AngularFaces-2/index.xhtml. Don’t be confused by the error message: Most likely, Eclipse will fail to run the application properly. The integrated browser has some difficulties with the Javascript code. Open the URL1 in a browser like IE 9+, Firefox or Chrome. Now you should see the small calculator application:


(Have a look at the AngularFaces showcase to see the live demo).

The JSF controller

I wrote the controller class in Groovy to reduce the amount of code I have to show to you. If you aren’t familiar with Groovy, simply add the getters and setters mentally.

@ManagedBean
@ViewScoped
public class CalculatorBean implements Serializable {
   @Min(7L)
   @Max(50L)
   int number1 = 42;

   @Max(100L)
   @Min(10L)
   int number2 = 65;

   int result = 0;

   public void add() {
      result = number1 + number2;
   }
}

The controller class contains two values bearing Bean Validation API annotations. JSF ensures the two fields to contain numbers in a certain range (7 through 50 and 10 through 100, respectively). The third bean attribute is calculated by the controller’s action method add().

The XHTML page definition

The XHTML file is more interesting. It starts by defining the AngularFaces namespace:

<f:view  xmlns="http://www.w3c.org/1999/xhtml"
         xmlns:f="http://java.sun.com/jsf/core"
         xmlns:h="http://java.sun.com/jsf/html"
         xmlns:prime="http://primefaces.org/ui"
         xmlns:ng="http://xmlns.jcp.org/jsf/passthrough"
         xmlns:a="http://beyondjava.net/angularFaces">

Apart from declaring the Primefaces namespace as prime: instead of p:, the first four lines should be familiar to you. The fifth line declares the new JSF 2.2 pass-through attributes. Again, I chose to ignore the common naming conventions. In my examples, pass-through attributes have to be preceded by ng: instead of p: indicating those attributes are used by Angular. Of course, you are free to change this in your own programs.

The last line defines the AngularFaces namespace as a:.

<f:view ...>
  <a:body ng-app="calculatorApp" ng-controller="calculatorController">
    <h:form ng:name="myform">
      ...
     <h:messages />
  </a:body>
</f:view>

AngularFaces pages use a special body tag to include the AngularJS library and to activate it. The <a:body> tag takes two attributes: The Angular ng-app and the Angular ng-controller. The latter is also used to load your controller class. It’s expected to be in a file bearing the same name as the controller attribute – in our case, “calculatorController.js”.

In many cases you’ll want to give the HTML form a name (it’s needed by some AngularJS expressions). To do so, you have to use a JSF 2.2 pass-through attribute: <h:form ng:name="myform">. I didn’t bother to define a dedicated AngularFaces tag since I expect the form’s name to be the only attribute beyond standard HTML.

Input fields

&amp;amp;amp;amp;lt;a:inputText label=&amp;amp;amp;amp;quot;Second number&amp;amp;amp;amp;quot; value=&amp;amp;amp;amp;quot;#{calculatorBean.number2}&amp;amp;amp;amp;quot; /&amp;amp;amp;amp;gt;

That’s a simple input field. It as simple as can be. And that’s why it’s exciting.

AngularFaces automatically adds the label and the error messages. It also reads the controller’s attributes to learn about the validation constraints and the data type. If it’s an integer, this information is passed to AngularJS, enabling client side validations. The same applies to the minimal (@Min) and maximal (@Max) values. As the project evolves, I intend to add more JSR 303 annotations.

There are two annotations not shown in the example that are also supported by AngularFaces:

  • @Size (setting the JSF attributes maxLength and size)
  • @NotNull (to indicate a field is required).

AngularFaces input fields extend Primefaces input fields. In other words, you can use every attribute Primefaces offers, and you can use the same CSS classes to adapt the look and feel of your application.

At the same time, AngularFaces input fields are also accessible by the AngularJS controller we defined above. By default, the ng-model attribute is the JSF bean’s variable name. More precisely, it’s the string succeeding the last period of the value attribute. In our case, the value is #{calculatorBean.number2}, hence the ng-model is number2.

Input fields without AngularFaces

Just to show the advantage of AngularFaces, I’ll show the standard JSF equivalent of the line:

&amp;amp;amp;amp;lt;h:outputLabel value=&amp;amp;amp;amp;quot;Second number&amp;amp;amp;amp;quot; /&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;h:inputText ng:integer=&amp;amp;amp;amp;quot;&amp;amp;amp;amp;quot; ng:type=&amp;amp;amp;amp;quot;number&amp;amp;amp;amp;quot; ng:ng-model=&amp;amp;amp;amp;quot;firstnumber&amp;amp;amp;amp;quot;
             label=&amp;amp;amp;amp;quot;second number&amp;amp;amp;amp;quot; value=&amp;amp;amp;amp;quot;#{calculatorBean.number1}&amp;amp;amp;amp;quot;
             ng:min=&amp;amp;amp;amp;quot;10&amp;amp;amp;amp;quot; ng:max=&amp;amp;amp;amp;quot;100&amp;amp;amp;amp;quot;
             id=&amp;amp;amp;amp;quot;secondnumber&amp;amp;amp;amp;quot; /&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;div&amp;amp;amp;amp;gt;
   &amp;amp;amp;amp;lt;div ng-show=&amp;amp;amp;amp;quot;myform.j_idt40secondnumber.$error.integer&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;This is not an integer.&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
   &amp;amp;amp;amp;lt;div ng-show=&amp;amp;amp;amp;quot;myform.j_idt40secondnumber.$error.min&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;must be greater than or equal to 10&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
   &amp;amp;amp;amp;lt;div ng-show=&amp;amp;amp;amp;quot;myform.j_idt40secondnumber.$error.max&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;must be less or equal to 100.&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
   &amp;amp;amp;amp;lt;div ng-show=&amp;amp;amp;amp;quot;myform.j_idt40secondnumber.$error.required&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;Value is required.&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;h:message for=&amp;amp;amp;amp;quot;secondnumber&amp;amp;amp;amp;quot; /&amp;amp;amp;amp;gt;

This source code exhibits another problem with a pure standard JSF approach: it requires a modification of the web.xml, and it may break in future. First of all, JSF uses colons to make ids unique (“j_idt4:secondnumber”). You can change this behaviour by adding

&amp;amp;amp;amp;lt;context-param&amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;lt;param-name&amp;amp;amp;amp;gt;javax.faces.SEPARATOR_CHAR&amp;amp;amp;amp;lt;/param-name&amp;amp;amp;amp;gt;
	&amp;amp;amp;amp;lt;param-value&amp;amp;amp;amp;gt;0&amp;amp;amp;amp;lt;/param-value&amp;amp;amp;amp;gt;
&amp;amp;amp;amp;lt;/context-param&amp;amp;amp;amp;gt;

to the web.xml, but this approach may break compatibility with other JSF libraries. Even worse, you have to use JSF’s client id in many AngularJS expressions. This can be done, but it’s tedious. The approach I showed above – simply writing the id as a string constant – can hardly be recommended.

Command buttons

AngularFaces command buttons extend and slightly simplify Primefaces command buttons:

&amp;amp;amp;amp;lt;a:commandButton type=&amp;amp;amp;amp;quot;submit&amp;amp;amp;amp;quot; value=&amp;amp;amp;amp;quot;add&amp;amp;amp;amp;quot; action=&amp;amp;amp;amp;quot;#{calculatorBean.add}&amp;amp;amp;amp;quot;/&amp;amp;amp;amp;gt;

Please note this is an AJAX button. I don’t see any point in forbidding AJAX while using AngularJS, thereby enforcing a modern browser. Even Internet Explorer 8 will do only with tricks. So we can enforce AJAX just as well.

AngularFaces adds the attributes update="@form" and process="@form" by default. As always, you are free to specify the attributes if you need more control.

By the way, the command button is the most difficult part when it comes to integrate AngularJS into JSF. You have to re-initialize AngularJS after every AJAX request. AngularFaces include the corresponding Javascript code in the onComplete attribute. But don’t worry, it’s clever enough to let you use the attribute as well. It simply executes both.

Calling AngularJS controller functions

In general, AngularJS controller functions are called exactly the same way they are called in any other AngularJS application. All you have to know is the Javascript file defining the controller should be in the same folder as the JSF file, and its file name should be the controller’s name, plus the “.js” suffix2.

        &amp;amp;amp;amp;lt;h:outputText value=&amp;amp;amp;amp;quot;Angular's calculation: 
             {{toString(number1)}} + {{toString(number2)}} = {{add()}}&amp;amp;amp;amp;quot; /&amp;amp;amp;amp;gt;

The example uses two functions defined in the controller: toString() and add(). As you can see, it’s just plain vanilla code. Chances are you can already imagine what the controller function looks like (at least if you’re an experienced AngularJS programmer):

function calculatorController($scope) {
    $scope.add = function() {
	if ($scope.number1 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; $scope.number2)
	    $scope.result = parseInt($scope.number1) + parseInt($scope.number2);
	else
	    $scope.result = &amp;amp;amp;amp;quot;(undefined)&amp;amp;amp;amp;quot;;
	return $scope.result;
    };
    $scope.toString = function(number)	{
	if (number)
	    return number;
        else
	   return &amp;amp;amp;amp;quot;(empty)&amp;amp;amp;amp;quot;;
    }
}

What about ng-submit?

At this point, experienced AngularJS programmers have to learn something new. While technically it’s possible to use the ng-submit atttribute, it’s a bad idea to do so in a JSF environment. So this code may cause difficulties:

&amp;amp;amp;amp;lt;form ng-submit=&amp;amp;amp;amp;quot;addTodo()&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt; // discouraged!
    &amp;amp;amp;amp;lt;input class=&amp;amp;amp;amp;quot;btn-primary&amp;amp;amp;amp;quot; 
           type=&amp;amp;amp;amp;quot;submit&amp;amp;amp;amp;quot; 
           value=&amp;amp;amp;amp;quot;add&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt; 
&amp;amp;amp;amp;lt;/form&amp;amp;amp;amp;gt;

AngularFaces introduces a dedicated button:

    &amp;amp;amp;amp;lt;a:angularButton value=&amp;amp;amp;amp;quot;label&amp;amp;amp;amp;quot; ng-function=&amp;amp;amp;amp;quot;angularFunction()&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;

I’ll describe in more detail in my next blog entry. Stay tuned!

Conclusion

That’s all you need to dive into AngularFaces. At the time of writing, the project is at a very early stage. Only <a:body>, <a:inputText> and <a:commandButton> have been implemented yet. But I guess it’s enough to get the gist of it. Maybe it’s also useful, even at this early stage.

Now I’d like to hear from you. How do you like the idea of AngularFaces?


  1. depending on your configuration it will probably be http://127.0.0.1:8080/AngularFaces/AngularFaces-2/index.jsf
  2. As always, you can override the default if you insist.

3 thoughts on “Getting Started with AngularFaces

  1. Pingback: Getting Started with AngularFaces | Java EE 6 D...

  2. Pingback: Getting Started with AngularFaces | Development...

  3. Pingback: Getting Started with AngularFaces | Juanmi.Rua ...

Leave a Reply

Your email address will not be published.

CAPTCHA Image

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>