Monday, November 25, 2013

Use Angular Form module with JSF

Angular JS designs web page using client-side technology. The model-view-controller is established in client-side. JSF requires data-binding have to be on server side at minimum. Given an example like this

<div data-ng-app="jtest" data-ng-controller="IntsCtrl">
                <form >
                    <input data-ng-model="test" type="text" id="test" value="My Value" />
                    <input data-ng-model="ints" type="text" id="ints" value="[3,5,7]" />
                        <input type="text" data-ng-repeat="v in ints track by $index" data-ng-model="v" data-ng-change="changeValue(v)"/>

This is a piece of HTML supported by angular JS.  The value='My Value' is generated by JSF at server-side.  The issue is that default value will be discarded by angular after the template is processed since the initial value comes from model which is empty at the beginning.  So how can we ask angular to initialize value from element value attribute?

This post gives a brilliant idea:add a directive to initialize the model value from input attribute. I modifies the script a little bit to accept a mode for value initialization.

var app = angular.module('forms', []);

app.directive('ngInitial', function() {
  return {
    restrict: 'A',
    controller: [
      '$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
        var getter, setter, val, mode;
        if ("eval"==mode)

        getter = $parse($attrs.ngModel);
        setter = getter.assign;
        setter($scope, val);

You can modify this script and add more mode to suit your situation.
To load this directive, make you module depends on this one like this:
 angular.module('jtest', ['forms']);