Sunday, 1 December 2013

AngularPrime Enterprise: A proof of concept

Introduction

As explained in the StatelessPrime announcement, I was trying to create a front end with HTML5, CSS and JavaScript which was as easy as creating one with JSF (for me it is easy, I know a lot of people don’t find that easy).
And with the progress I made with the AngularPrime widgets, the look and feel of a PrimeFaces and AngularPrime application are almost identical.  But there are a few easy things in PrimeFaces /JSF that are still missing in the JavaScript based application.
And that was the goal of my AngularPrime Enterprise experiment, allow the creation of an application with the same ease and power as with PrimeFaces.

Why the name Enterprise

For me, JSF is at his best when you use it for administrative applications.  With his lifecycle containing converters, validators and action events, it is ideal for data input type of application that need some business logic checks before the data can be stored in a database.
Making this type of applications, which I refer to as Enterprise type, easier with AngularJS and AngularPrime, lead me to the, not so creative, name of AngularPrime Enterprise.

Messages

One thing which is very easy is the display of messages that you specify within the code.

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("..."));

By decoupling the ability to set messages from the framework you display them, you can specify in a generic fashion some messages for the screen using CDI as explained in GenericMessage for DeltaSpike supporting JSF and REST
The messages are now available in a thread local variable and ready to be sent to the browser together with the response.  The ContainerResponseFilter I explained in the blog Even easier JAX-RS for Java EE 7 can be used for this purpose.

With AngularPrime Enterprise, the response from the REST response it automatically wrapped within a Transfer structure like this:

    @JsonSerialize(using = JsonPayloadSerializer.class)
    private JsonPayload data = new JsonPayload();
    private List<Message> messages = new ArrayList<>();

This structure can be extended to include also some security info or session info. (like name of logged in user).  Within AngularJS, this enriched response object can be used to automatically display the messages.  The current implementation looks something like this:

$httpProvider.responseInterceptors.push(function ($q, puiMessages, puiGrowl) {
        return function (promise) {
            var resolve = function (value) {

                if (('boolean' === typeof value.data.data )) {
                    puiMessages.clear();
                }

                if (value.data.messages && value.data.messages.length > 0) {
                    puiMessages.show(value.data.messages.filter(function (msg) {
                        return 'INFO' !== msg.severity;
                    }));
                }

                // Interceptor is also called for loading partials.  Then value.data is a String.  When loading from backed, it is always an object
                if (angular.isObject(value.data)) {
                    value.data = value.data.data;

                }

            };

            var reject = function (reason) {
                console.log("rejected because: ", reason);
            };

            // attach our actions
            promise.then(resolve, reject);

            // return the original promise
            return promise;
        }
    });


The puiMessages services is a prototype that I created based on the messages component of PrimeFaces to display the messages set by the backend. The interceptor also takes out the values in the data attribute of the Transfer object. 

So the transfer of additional information, like the messages, is done transparently and without the need of any code written by the developer.

Validation

Validation is also a key feature of AngularJS.  There are directives like ng-required and also custom validation rules can be created and used. So the implementation of an automatic validation process which shows the error messages, isn’t a difficult task.

puiClientValidation is a service in AngularPrime Enterprise which has a function validateForm, which takes a reference to a form element.

It checks with AngularJS the errors in this form and shows the error message in the same message widget we used to display the messages we saw in previous section.

For the input fields that have an error, it try to finds the label for this element (<label for=”” >) to show a ‘personalised’ error message like:

First name is required.

And the last thing the service method does, at this moment, is touching the field model values so that the field can be shown in red for example to indicate the place of the error.

Conclusion

With this first test, I came pretty close to some features which are available in PrimeFaces and JSF.  I was able to define some message in the CDI bean and show it on the screen. Without any intervention of the developer (no code required).

Also the client side validation possibilities of PrimeFaces can be recreated with AngularJS by using a custom validation service.  It should even be easier when I override the ngClick directive of AngularJS and define the call there so that there is even no need in your JavaScript code to do the call.

This how it can look like

angularPrimeEnterprise

The code can be found on GitHub and is tested on Glassfish 4 and WildFly 8 beta 1.

Thursday, 14 November 2013

3 ways of selecting from dropdown with AngularPrime 0.5

Introduction

With the newest release of AngularPrime v0.5, there are now 3 ways you can select values from a list. And they are all based on the same html element <select>.
In the figure below they are shown, from left to right, the dropdown, the listbox and the picklist.

dropdowns
These widgets have a few features in common but there are also things specific for a certain representation.

Common functionality

The first important functionality they have in common is that they can be styled according the theme you have selected. So for instance, when you hover over an element from the list, the background colour of the item changes to indicate the selection you are about to make.

Another feature they share is typical for AngularJS but require some specific code in case of these widgets.  They have the 2-way binding capabilities you are familiar with in AngularJS.  Whenever you select an option in the widget, the selected value is stored in the JavaScript variable (within the scope). But the other way around is also implemented. Whenever you change the variable ‘attached’ to the widget, the visual representation is updated.

The third feature they have in common is the possibility to assign a callback function to the selection event.  There is the possibility to assign a JavaScript function to the selection of an option event, in case you want to perform some additional processing when the user makes a selection.

And the last feature I want to mention here is that all widgets can be disabled in case the state of the screen doesn’t allow a selection at the moment.

Dropdown

This is the classic representation of the selection from a list.  But with AngularPrime you can have some extra functionality.
This is the code to have the AngularPrime dropdown in your page:
<select id="dropdown" pui-dropdown ng-model="selectedCars">
            <option value="1">Volkswagen</option>
            <option value="2">Ford</option>
            <option value="3">Mercedes</option>
            <option value="4">Audi</option>
            <option value="5">BMW</option>
            <option value="6">Honda</option>
            <option value="7">Porsche</option>
            <option value="8">Chevrolet</option>
            <option value="9">Jaguar</option>
        </select>

The additional features are
  • Possibility to filter the options which are shown. By default there are 3 filtering types supported, the start-with, contains and ends-with. But you can write your custom one and use it.
  • The dropdown field van be made editable. In this case the option list is a suggestion list but another value can be accepted.

Listbox

This alternative representation of the selection from the list, is especially handy to allow multiple selections.

This is the code to have the AngularPrime listbox in your page:
<select id="picklist" pui-listbox ng-model="selectedCars">
            <option value="1">Volkswagen</option>
            <option value="2">Ford</option>
            <option value="3">Mercedes</option>
            <option value="4">Audi</option>
            <option value="5">BMW</option>
            <option value="6">Honda</option>
            <option value="7">Porsche</option>
            <option value="8">Chevrolet</option>
            <option value="9">Jaguar</option>
        </select>

Multiple selections can be performed by pressing the Ctrl button when you select or unselect an option with the mouse.

Picklist

With this representation, you not only have the possibility to select multiple options but you can also specify the order of the selected options.

Within the code you have the following markup:
 <select id="picklist" pui-picklist ng-model="selectedCars">
            <option value="1">Volkswagen</option>
            <option value="2">Ford</option>
            <option value="3">Mercedes</option>
            <option value="4">Audi</option>
            <option value="5">BMW</option>
            <option value="6">Honda</option>
            <option value="7">Porsche</option>
            <option value="8">Chevrolet</option>
            <option value="9">Jaguar</option>
        </select>

The additional features are in this case
  • With this widget, there is also the possibility to filter the source and/or the target list of options. Again there are 3 predefined filtering types available, start-with, contains and ends-with but a custom one can also be specified.
  • The selection and de-selection of the options is not only supported with button click but can also be performed by drag and drop.  This makes the user interface very intuitive for the user.

Future

There are other features planned for these widgets in the next or future release.

PrimeUI allows you to specify a template for the ‘rendering of the options.  If you go to the showcase you can see that there is the possibility to include images in the options for example.  That feature will be integrated in the next release of AngularPrime.

For the moment it is only possible to disable the widget completely. In a future version of AngularPrime, there will be the possibility to show the options individually as disabled or enabled.

And the last thing you can expect is that the options are linked to a JavaScript variable so that you can update the list op options which are shown.

Conclusion

With the AngularPrime version 0.5, you now have 3 ways to present the user the selection from a list input type. The encoding in the HTMl is nearly identically, except the directive name. They have some nice features in common like the 2 way binding and the integration with the theme.  And each of it has its specific use case where they can be used at there best.

There are also some nice features planned that will improve the user and developer experience.

Have fun with AngularPrime.

Sunday, 3 November 2013

Even easier JAX-RS for Java EE7

Introduction

About a year ago, I started with my project StatelessPrime where the Java EE is the universal backend system for a lot of web technologies.  See also this blog post for more information about the ideas behind the project.
In that year, I did a lot of experimenting to check some ideas and also a lot of work is done in bringing the JSF and PrimeFaces experience to other technologies like HTML5.
In that same timeframe, Java EE 7 was launched which gave us easier ways to achieve the ideas expressed in the StatelessPrime announcement blog.
This is the first blog to give an overview of my first year of work.

JAX-RS 2.0

With the release of Java EE 7 system, there is also a new version of the JAX-RS framework. And it has the new concept of interceptors and filters.
There is the ContainerResponseFilter interface to define a filter just before the response is marshalled to the client. This is a very handy extension point in many ways:
  1. You can wrap the response in some generic response object that contains next to the data also some other information like messages, security keys and so on.
  2. It also removes the need to annotate the POJO’s that you like to send, in a marshalled form, to the client.
I can understand that you foresee the possibility to configure the way how the marshalling will be performed. But if you only want some standard behaviour, marshalling al the fields with their default options, why do you need some annotations?  It is the perfect example for convention over configuration principle.
So assume we have the following code:
@Path("registration")
public class RegistrationController {

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/all")
    public Person getList() {
        return new Person("Rudy");
    }

    private class Person {
        private String name;

        private Person(String someName) {
            name = someName;
        }

        public String getName() {
            return name;
        }

    }
}

This fails because the Person class isn’t annotated with @XmlRootElement. This is another confusing thing, I need it to annotate it with some JAXB annotation to get JSON output.

ContainerResponseFilter

But with the ContainerResponseFilter in combination with Jackson, there is an elegant solution. When you define a response filter as this, the objects returned by your methods are converted to strings (containing JSON) which are recognized without annotations.
@Provider
public class WrapPayloadFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

        Object entity = responseContext.getEntity();
        ObjectMapper mapper = new ObjectMapper();
        String payload = mapper.writeValueAsString(entity);

        responseContext.setEntity(payload);
    }
}

In another post I’ll explain another usecase for this filter.

Configuration

But the convention over configuration principle allows you to make some configuration in case you need it. The above described solution allows this also.

Suppose the Person object you want to marshal has also a date field, like his birthday.  Dates are one of those field types you like to configure the string representation of.  By using the JsonFormat annotation from Jackson, we are able to specify the format of the date representation.
        @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
        private Date date ;

Conclusion

Although it is already very easy to create some JAX-RS endpoint to provide the data in JSON format to your application, it can even more simple since we now have the ContainerResponseFilter in Java EE 7 / JAX-RS 2.0.

As a first example, I demonstrated how you no longer need to annotate the POJOs which you are returning. But the ContainerResponseFilter will show his best features in the next post where we will wrap the response in another object.

The next post will be on the JSF Corner blog as I will present you an extension to the JsfMessage DeltaSpike feature which you can use in JSF and Rest environments.

Tuesday, 8 October 2013

Send Logging and Exceptions to server in AngularJS application

Introduction

AngularJS has some services for the logging ($log) and the exception handling ($exceptionHandler).  These services can be decorated, just as the services that you write, to extend the handling by sending the info the to backend server.
This kind of functionality can be very handy to get a log of all the messages and errors which occurred in the browser during testing of your app by the test team.
Those developers with a Java background, as I’m, are probably familiar with the Log4J framework to handle the logging in your application. There exists also a JavaScript version of it, log4javascript, and the cool thing is that they provide an AJAXAppender out of the box so that you can send logging info to the server.
This post shows you the necessary steps to setup the log4javascript framework together with AngularJS.

Set up

The log4javascript framework consist of a single javascript file that has all the required objects and functions to allow an increased experience. Add this file to your HTML, preferably before the creation of the AngularJS module as we will make a reference to a global variable which contains the entry points of log4javascript in the module configuration.
<head>
    <title>Angular - Log4js - Logging</title>

    <script src="js/libs/log4js/log4javascript.js"></script>
    <script src="js/libs/angular/angular.js"></script>
    <script src="js/app.js"></script>
    <script src="js/controller.js"></script>
</head>
<body ng-app="ng-logging">

AngularJS services can be decorate to override or add additional functionality with the configuration of your module.  This is the template that you can use for this purpose
var demo = angular.module('ng-logging', [ ]);

demo.config(function($provide) {
    $provide.decorator('$log', function($delegate, $myService) {
        // extend functionality or add functions to $delegate
        // Use additional code from the $myService service 
        return $delegate;
    });
});


Log4javascript

On the site of the framework, there is a pretty good description how you can use the framework and the different appenders.

The idea is that you supply some logging messages to the framework, and the, active at that moment, appenders handle the log message in some way.  In our case we are interested in sending the message to a server (AJAXAppender) but there exists also appenders for the console, a popup, an inline block, etc.. The additional functionality that an appender executes is the formatting of the message according to a certain ‘layout’ (date/time information, …)

The following lines prepares you a logger that sends the messages to a servlet listening on the loggingServlet URL.

        var log = log4javascript.getLogger();
        var ajaxAppender = new log4javascript.AjaxAppender("loggingServlet");
        ajaxAppender.setThreshold(log4javascript.Level.ALL);
        log.addAppender(ajaxAppender);


Extending AngularJS logger.

Since we have seen all the individual aspects, lets integrate them so that we can send logging messages to the servlet.

This is the code we have to use in our application to makes it happen.

demo.config(function($provide) {
    $provide.decorator('$log', function($delegate, $sniffer) {

        var _info = $delegate.info; //Saving the original behavior
        var _error = $delegate.error; //Saving the original behavior

        var log = log4javascript.getLogger();
        var ajaxAppender = new log4javascript.AjaxAppender("loggingServlet");
        ajaxAppender.setThreshold(log4javascript.Level.ALL);
        log.addAppender(ajaxAppender);

        $delegate.info = function(msg){
            _info(msg);
            log.info(msg);
        };

        $delegate.error = function(msg){
            _error(msg);
            log.error(msg);
        };

        return $delegate;
    });
});


We start by storing the reference to the original behaviour, the AngularJS default one, for info and error.
The next 4 lines are the one we need for having the Log4javascript framework initialized and a logger available that we can use.

And then we overwrite the info and error methods in the original implementation with custom ones where we handover the message to the logger and also call the saved, original behaviour.

Since it is a decorator, we need to return something. In this case the enhanced log service which gets injected in our code when we request the $log service.

LoggingServlet

On the server side, we know also need a servlet which captures the log messages and do something useful with it.  The capturing code looks like this:

@WebServlet(urlPatterns = "/loggingServlet")
public class LoggingServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String timestamp = req.getParameter("timestamp");
        String level = req.getParameter("level");
        String message = req.getParameter("message");

        Date clientTime = new Date(Long.valueOf(timestamp));
        System.out.println(clientTime + " - " + level + " - " + message);
    }
}


Of course, the above code doesn’t do anything useful but it is your starting point to save the data for example to a database when such a class is placed in a servlet 3.0 complaint container.

Capturing exceptions

For the capturing of exceptions, we can follow the same route as described above for the logging.

When we add an additional method to the logging services in the decorator, we can easily call this when there is an exception captured by the decorated $exceptionHandler.
        $delegate.fatal = function(msg, exception){ //Adding additional method
            _error(msg);
            log.error(msg, exception);
        };

The decoration of the $exceptionHandler is simpler as we just want to call our newly added fatal method of the log service.
demo.config(function($provide) {
    $provide.decorator('$exceptionHandler', function($delegate, $log) {
        return function(exception, cause) {
            $log.fatal(exception, cause);
            $delegate(cause, exception);

        };
    });
});

Conclusion

Due to the excellent modular structure of AngularJS and the ability to decorate services, we can create easily a system that sends any log and exception to the backend server with the help of Log4javascript.

The code for this post can be found on google code.

Thursday, 12 September 2013

Extending jQlite with new functions

Introduction

If you are using AngularJS, you should not rely on jQuery. An exception can be when your are integrating some jQuery plugin through directives into your application.
Why you should not use it? jQuery is geared toward the manipulation of DOM elements. But all that is hidden for you by the AngularJS framework, and has his own philosophy. This framework lets you concentrate on what you want to achieve by implementing only your business code and declarative indicate how the views are build.

As Pawel Kozlowski and Peter Darwin says in there book "Mastering Web Application Development with AngularJS . PACKT PUBLISHING"
AngularJS' model-centric and jQuery's DOM-centric paradigms are radically different. Seasoned jQuery developers new to AngularJS might fall into a trap of using AngularJS with the jQuery paradigms in mind. This results in code that "fights AngularJS" rather than unleashing its full potential.

No jQuery?

jQuery is a bunch of, very good, functions to manipulate your DOM elements and also the AngularJS framework needs to do those kind of operations.
But instead of integrating it completely, they have implemented a basic set of functions into the framework and called it jQlite. And when jQuery is loaded before the AngularJS files, it uses the full version instead of the AngularJS subset.
But since a lot of people know the jQuery functionality, they can be disorientated if they need to implement a directive, this is where the DOM manipulation needs to go, in plain AngularJS.
The good thing is that you can add yourself some additional functions to the jQlite implementation. So you can move the jQuery functionality you like and use it in an AngularJS way of working.

Extending jQlite

This snippet shows you how you can add the hover function which defines the functionality when an element is hovered by the mouse

angular.forEach({
    hover: function hoverFn(element, fnEnter, fnLeave) {
        angular.element(element).bind('mouseenter', fnEnter).bind('mouseleave', fnLeave ||fnEnter);
    }
    // We can have here more extension functions

}, function(fn, name){
    var jqLite = angular.element;
    jqLite.prototype[name] = function(arg1, arg2) {
        var value;
        for(var i=0; i < this.length; i++) {
            if (value == undefined) {
                value = fn(this[i], arg1, arg2);
                if (value !== undefined) {
                    // any function which returns a value needs to be wrapped
                    value = jqLite(value);
                }
            } else {
                JQLiteAddNodes(value, fn(this[i], arg1, arg2));
            }
        }
        return value == undefined ? this : value;
    }
});


Future down, I'll explain a bit more the code, but first I like you to show the usage of it in a directive.

var demo = angular.module('extension', []);

demo.directive('hover', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.hover(function() {
                element.toggleClass('ui-state-hover');
            })
        }
    }
});


In this directive link function, we see that we call the hover function on the element that is passed as parameter by AngularJS. This is a jQlite wrapped version of the DOM element. Although, standard AngularJS doesn't provide you with a hover function, we can call it because we have added that function when the first snippet is executed.

The code structure of adding functions is taken, more or less, directly from the AngularJS code.  It defines a forEach call where the first parameter is an object with the functions we want to add.
Important is that each function has the element as a first parameter. The second parameter of the loop, is a function that 'register' our new functions to jQlite by using the prototype object.

When the function returns something, it is wrapped in a jQlite object, otherwise the 'element' itself is returned so that we can use 'chaining'.


The code can be viewed in action with this plunker.

Which functions?

What are good candidate functions to add like this? Well, each function that operates on a DOM element can be expressed in this way. However, you don't need to do it.  You can also create some 'standalone' function that takes the element as parameter and perform the needed tasks.
What functions have I already registered this way? The hover and some other event related functions is one of group of them. I also have a function that retrieves all siblings of an element and another I like to mention is my position function, based on the jQuery UI position plugin, to position a certain element next to another like this.


element.position({
                my: 'left top'
                ,at: 'right bottom'
                ,of: target
            });


Conclusion

When you have a function that operates on a DOM element, you can add it very easily to the jQlite system as described above.
You can even use it for some jQuery functionality you find essential to complete the directive. But as many authors say, you should try AngularJS without jQuery and use it only as a last resort and always in the AngularJS way.

Tuesday, 27 August 2013

Inheritance for JavaScript when writing widget libraries

Introduction

On the last day that I worked on the AngularPrime widget library for AngularJS, I was creating some kind of inheritance between JavaScript objects. As I'm coming from a Java background, I'm trying to keep some of the principles of Java to feel me more at home in the other language.
Although strictly speaking, JavaScript doesn't has a inheritance mechanism, there are some possibilities with the prototype object.
In the AngularPrime code, I had several snippets of code that was used for several widgets. And thus I liked to define them only once, as a good practice habit.

Problem description

I was using object literals, as I only needed some functions and didn’t had a need to keep some state.  The main purpose was to keep the code readable in small chunks. And thus object literals seemed to me a very logic solution as you create singletons with them.

So my code looked like this
library.baseWidget = {};

library.baseWidget.common = function(element) {
  // The common functionality
};

library.widget1 = {};

library.widget1.constructWidget = function(element) {
   // Other code and fuction calls.
   this.eventRelated(element);
}

library.widget1.eventRelated = function(element) {
   // widget specific code
   library.baseWidget.common(element);
}

// Code for other widgets


Although this works well, I like to have the call to the common code also by using the this. reference. Just as in Java, that you can define methods in the super class and that all descendants inherited the functionality.

No constructor approach


As I'm not using a constructor for the object instantiation, the best described solution approach can't be used.
And as I searched further, I even found out that it wasn't even possible to assign a certain 'prototype' object to an object instance created by an object literal.

I came across a few StackOverflow messages of people that wanted to do the same and found some code that, adapted a little bit, looked perfect for me.

library.baseWidget = {};

library.baseWidget.common = function(element) {
  // The common functionality
};

library.widget1 = library.core.inheritedFrom(library.baseWidget);

library.widget1.constructWidget = function(element) {
   // Other code and fuction calls.
   this.eventRelated(element);
}

library.widget1.eventRelated = function(element) {
   // widget specific code
   this.common(element);
}

// Code for other widgets

I named the function inheritedFrom to make clear what is the purpose of the code.  By using that function, I'm able to call the common functions by using the this. reference.

The magic function is shown here:
    library.core.inheritedFrom = function (superClass) {

        var subclass = {}
            , F = function (instance) {};
        F.prototype = superClass;

        return new F(subclass);

    };

And as you have no choice then using a constructor approach so that you can assign the prototype object, the function thus this also.  But it is hided and the function nicely indicates what the purpose of the function is.

Conclusion


As you can’t assign a prototype object when you use object literals, I created a function that hides the creation of a new object based on a superclass (as prototype object).

Thursday, 25 July 2013

AngularPrime release 0.4

Introduction

This release contains 2 new functionalities
  • Support for the ng-show and ng-hide angular directive in combination with the pui-input directive on checkbox and radio type
  • Integration of the datatable widget of PrimeUI 0.9.5
This may seem not much since the latest release of the project 2 months ago, but there is a lot of work done behind the scenes which is not yet ready to release.
The most important tasks which are in progress are
  • Automated integration testing
  • Developers guide

New features

ng-show/ng-hide and pui-input on checkbox and radio type

Using the pui-input directive on an input tag of type checkbox or radio, gave a nice themed representation of a checkbox and radiobutton style input field.
 
<input type="checkbox" id="chk1" ng-model="checkboxSelectedValue1" pui-input/><label id="lblchk1" for="chk1">Option 1</label>

For this type of element, the DOM structure is restructured and as a consequence, the ng-show and ng-hide directives doesn’t have any effect anymore.  Well they do have an effect but they are working on a hidden element so it useless.

With the 0.3 version, the workaround was to use the ng-show and ng-hide on a surrounding element, but the issue is solved in this version by creating a specific directive for checkbox and radio buttons functionality, called pui-checkbox and pui-raduibutton.
These new directives are also used to incorporate the label declaration, so that you have to type a lot less.
 
<div id="chk1" pui-checkbox="Option 1" ng-model="checkboxSelectedValue1" >

How does these new directives work? Well, it generates the corresponding longer version with the input element and pui-input directive and then the Angular ‘compilation’ is called on this generated HTML.

For now, only the prefix of the id of the label element can customized. The id is created by putting the characters ‘lbl’ in front of the id that you have specified on the element with the pui-checkbox or pui-radiobutton directive.  If you want to change this prefix value, you can redefine it with an angular decorator as shown in the following code snippet.
 
demo.config(function($provide) {
    $provide.decorator('angular.prime.config', function($delegate) {
        $delegate.labelPrefix = 'rudy';

        return $delegate;
    });
});

But the main advantage of the new directives is that when you specify the ng-show or ng-hide directives on the element, they work as expected and you can use them to hide the element conditionally.

Datatable widget


In the PrimeUI 0.9.5 release, there is a new widget available for showing data in a tabular format. And it has support for selection of rows and sorting of columns.

This widget is now also integrated in AngularPrime and I tried to make the use of it as easy as possible. Meaning that for some basic functionality you should write as less code as possible.

In the case we have an array of objects with the data we like to show available in the scope, the table can be encoded with this single line.
 
<div pui-datatable="fixedData"></div>

And in the controller we can have the following lines:
 
 $scope.fixedData =  [
        {'brand':'Volkswagen','year': 2012, 'color':'White', 'vin':'dsad231ff'},
        {'brand':'Audi','year': 2011, 'color':'Black', 'vin':'gwregre345'},
        {'brand':'Renault','year': 2005, 'color':'Gray', 'vin':'h354htr'},
    ];

And the result is

datatable1

The code does an inspection on the properties it finds of the first object of the array. In this case it finds 4 properties (brand, year, color and vin) and thus 4 columns are shown in the table.

Instead of fixed data, you can also supply a function that is responsible for returning the data, possible retrieving it from a remote resource.

If you want to control which columns are shown, you can specify them with the pui-column directive.
 
<div pui-datatable="fixedData">
   <div pui-column="brand"></div>
   <div pui-column="year"></div>
</div>

With this directive it is also possible to specify if the user can sort the data based on a column and the column header value.

Another feature which is available is the row selection. The first possibility is that a function is called whenever a row is selected (or deselected). The rowSelect function has the following structure:
 
 $scope.carTableData = {
        tableData : $scope.fixedData
        , rowSelect: function(event, data) {
            puiGrowl.showInfoMessage('Row selection', 'Selected a '+data.color+ ' '+data.brand+ ' of '+data.year +' (id = '+data.vin+')');
        }
    };

And instead of referring to fixedData in the pui-datatable directive, we have to refer to carTableData and we have implemented the row selection feature. Of course you have to do some more useful stuff in the selection function then just displaying it in a growl.

The second possibility for having the row selection functionality is to have a selectedData property in the object
 
 $scope.progSelectTableData = {
        tableData : $scope.fixedData
        , selectedData : []
    };

Now all row selections that are made on the screen, are reflected in the array of integers property called selectedData (array as we can have multiple rows selected). You can even modify the contents of this property programmatically and the change in the property is propagated back to the screen.
The only problem with this second approach is that it isn’t sorting safe as we are working with row indices and not the actual data objects.

The last feature that I want to mention here briefly is the pagination feature. By specify the paginatorRows property in the object, the data is displayed in chunks of the specified number of rows.
 
 $scope.paginatedData = {
        tableData : $scope.fixedData
        , paginatorRows : 4
        , rowSelect: function(event, data) {
            puiGrowl.showInfoMessage('Row selection', 'Selected a '+data.color+ ' '+data.brand+ ' of '+data.year +' (id = '+data.vin+')');
        }
    };

This feature is compatible with the sorting of columns. So when a (or more) rows are selected and then the data is sorted based on a column value, the correct rows stays highlighted.

For more detailed examples of the widget and some more use cases, have a look at the online version of the demo application.

In preparation


As mentioned, besides this rather limited new features list, I’m preparing other material.

There are already 79 automated integration tests created. They are based on the Selenium Webdriver framework and I’m using the technique described in this blog post to run the tests on multiple browsers.

A lot more tests needs to be created as I’m only covering 10 of the 25 available widgets for now. And even for those, not all possible use cases are covered. So in the next months, this number of tests will be increased a lot.

The second thing I have started is the developers guide. For now, there is only the demo application where the code is shown to have a certain example.  But for some widgets, some explanation could be very useful as they can be rather complex.

So I was investigating the possibilities to use asciiDoc as it uses a plain text format and thus it is ideal to use in an source control environment.  I hope to have some first basic version of the guide when I release the next version.

Conclusion


This release is a small one in relation to the amount of new features.

You can find new directives for checkbox and radio button input style to make the encoding easier as label and ng-show/ng-hide directivescan be placed on the element itself.

Further there is an integration of the datatable widget of PrimeUI 0.9.5.  There are numerous scenarios to allow very basic but fast definition of data to show to a version with complete control of which data is shown and which features are activated.

Just as important as the code itself, the work on the automated integration tests and the developer guide has started.

And stay tuned for more new announcements to be made in the (near) future.