Thursday, 2 October 2014

Nashorn and Avatar, or bring JavaScript and Node.js to the JVM

Introduction

There is a lot of attention lately for the server side javascript possibilities.  This in response to increased popularity of the language during the last years.

And I’m not going to judge here if it is a bad or good move, javascript on the server. It became a platform and probably the best feature is the non-blocking style of actions.

But what if you are a Java developer for a long time, are very confident programming in it?  Should you thow it all away and start over again in JavaScript?

Or how can you integrate your JavaScript code with enterprise services?

Nashorn

With the release of Java 8, not only the lambdas, stream and all those other goodies are added to the JVM, there is also something that is called Nashorn.

Nashorn is a JavaScript engine which complies to the JSR-292 specification, the support for the dynamically typed languages. And it allows you to run some JavaScript on the JVM.

There are various possibilities. From executing a few lines of JavaScript which are placed in a String from within Java to a full blown JavaScript file which is started with the jss command from the command line.

In each case, the javascript is compiled to run on the JVM.  And since it is running on the JVM, why not foresee some interoperability with Java.  
And that is why I find Nashorn interesting.  It allows you easily to call some Java method you have written or which are defined in some library.

You can write something like 

var LinkedList = Java.type("java.util.LinkedList");
var list = new LinkedList;
list.add(1);
list.add(2);
print(list);
print(list instanceof LinkedList);

And you are using the Java LinkedList object from within JavaScript. You can interpret Java.type as an import statement. 

So the end result is a very transparently interaction between the two.  You can pass JavaScript variables to Java Methods and Java variables to JavaScript functions.  There is no distinction.

You can even mix calls, like a Java method as the JavaScrip callback function.

avatar.js

node.js is one of the popular JavaScript server side solutions today.  So there are a lot of modules created for this platform.
So in the same philosophy that you want to bring JavaScript to the JVM, avatar.js brings the node programming model (API and modules) to the JVM.

Of course, not every node.js module can be run by avatar.js and the JVM. If it makes use of some V8 engine specific features, it will not run of course since they are not available on Nashorn.

But the site lists quite some of the most important modules which are tested and run smoothly.  They guess that up to 95% of the modules work.

Another addition is that with avatar-js, you can use the full power of your machine. node.js event loop runs in a single thread.  But with avatar.js you can easily spawn other threads and do some work over there. 
For example when you have a task which may take a while and for which you don’t need the result in the current request.
And you can even have multiple threads, each of them running the event loop and they are connected with an event bus to communicate between each other.

Avatar 2.0

There used to be also a project avatar.  It was an extension on top of avatar.js which had some kind of view layer and access points to Java EE technologies like JPA and JMS.
So there would be a strong integration with the Java EE stack and it should be deployed on Java EE Servers.

But at JavaOne 2014, they announced that they have abandoned this path.

Instead, they have now Avatar 2.0.  Which is the combination of avatar.js and a model store which allows you to store your data in a RDBMS or No-sql store. And it is highly inspired on JDBC and JPA but entirely written in JavaScript.

Based on some JSON schema dialect, you can define the mapping between the properties and the database fields.  You can even define some relations like foreign keys.

Why interesting ?

So maybe you ask yourself, why I find this interesting and place this text on the statelessprime blog?

Well, until now, I was always playing with some client side javascript frameworks like AngularJS which are talking to the backend using JAX-RS.

But if you want to split up a project, you put services, data access and model in one project.  And controller (like JAX-RS controllers) and view technology (if any) in another project.

So I’m playing now with the idea to move the RESTful services to server side javascript (using Avatar 2.0 and for example the express node module).  This javascript part can talk then to your Java EE business logic by using the Java interface.

And by using for example the BeanManagerProvider from DeltaSpike, it should theoretically be possible to call into the Java EE components.

BeanManager bm = BeanManagerProvider.getInstance().getBeanManager();

For now, it is maybe a wild idea, but I’m willing to give it a try.  In any case, the results will be posted here some day.



Monday, 25 August 2014

Differences between the new AngularWidgets and the old AngularPrime

Introduction


Beginning of June, I announced that the AngularPrime project will no longer be maintained. (see here http://statelessprime.blogspot.be/2014/06/angularprime-will-be-replaced-by.html)

No jQuery

The most important difference between the 2 libraries is the use of jQuery.  Since AngularPrime was build on top of the PrimeUI library, it was using jQuery and jQuery UI.

AngularJS can be used in combination with jQuery, but as one of the best practices, they always say that you should use AngularJS as is, and not trying to fallback to the old jQuery habits.

And although PrimeUI is a great library, AngularPrime no longer fulfilled the role that I had set for myself.  I wanted to learn more about AngularJS and how it was similar to JSF (see http://statelessprime.blogspot.com/2013/01/comparison-between-angularjs-and-jsf.html)
But I did spent more time with jQuery then with AngularJS, so I decided to start over again.  This time with pure AngularJS and to see if I could have the same developer experience with an AngularJS widget library as with PrimeFaces.

AngularJS 1.2.x with animations

When I started working on AngularPrime, only version 1.0.x of AngularJS was available.  So no animations were available ‘natively’ in AngularJS.  Of course, PrimeUI used the animations of jQuery.
Now AngularJS 1.2.x is available and thus AngularWidgets uses the animations which are available within AngularJS.
Some examples are the collapse and expand of a panel, or the  showing and hiding of the InputText of Button widget.

And I must admit, I’m not a CSS guru, ninja or whatever you may call it.  So things can be improved.

Row selection with data table

Another important difference is the row selection within the data table widget.  With AngularPrime (and PrimeUI) when a row is selected, the row number is stored internally in the list which keeps track of selection.
This of course gives problems when the data can be sorted by some column or new data is shown in the table.

AngularWidgets therefor uses the concept of some id to keep track of the selected row.  In order for the selection to work, the developer must indicate some property of the shown object which uniquely identifies each row (the famous id).  The value of this property is stored when a row is selected and thus within AngularWidgets, it is possible to sort the data according to some column AND keep the previous selected rows.

Testing

Automated testing for AngularPrime was not introduced immediately. And although almost all features where covered with a test at some point, the testing code became very ugly.  I used WebDriver to test but test code became very messy with a lot of Helper classes and not structured in an OO manner. (see http://statelessprime.blogspot.be/2014/02/widget-testing-with-arquillian-graphene.html)

In the mean time, Grafaces (https://github.com/rdebusscher/grafaces) is advanced far enough to be useful.  Grafaces is an extension to Arquillian Graphene which makes it even easier to test your component library.  And the good thing is that Arquillian Graphene and Grafaces is technology independent, as long as it outputs HTML.

So for the testing of the AngularWidgets components, Graphene elements are defined and used to test the correct behaviour in the browser.
For the 8 components which are already available, there are in total 56 tests written.

Use of templates

The widgets are defined with AngularJS directives and the choice was made to use as much as possible the template options.  Of course, template is not enough and some code is written and attached to the link phase of the directive.  But I tried to limit the adding of DOM elements with code and maximise the use of templates.

PrimeFaces alike

AngulerWidgets is also defined as HTML elements. So you can no longer use the attribute version. This is done mainly because of the following reasons
- The HTML becomes easier to read as you see now elements which indicate what kind of widget will be shown at that place.
- To be more PrimeFaces alike.  PrimeFaces uses also elements and also the naming of the attributes on the AngularWidgets elements is chosen, if possible, to be identical to PrimeFaces.

Missing things

Of course, AngularWidgets is still a lot of things missing in regards to AngularPrime.

The most eye-catching thing is that only 8 widgets are available for the moment.

They are not chosen randomly but each widget has been selected to test out a specific type of functionality. 
- There are of course the basic elements like input and button elements.
- Fieldset is chosen for the animation challenge.
- Tab view for the dynamic addition with included files
- Growl is a widget which is purely defined in an AngularJS service, there is no directive.
- data table uses inter directive communication.  You have the column and the data table directive.
- Autocomplete has the challenge of showing a list of suggestions when characters are typed.

etc

And there are so many other things which could be interesting in AngularWidgets like extending jQLite of AngularJS (define new functions,  see also http://statelessprime.blogspot.com/2013/09/extending-jqlite-with-new-functions.html) and so on.

Code and example

The code can be found on GitHub in the AngularWidgets repository and the demo is here.




Saturday, 7 June 2014

AngularPrime will be replaced by AngularWidgets

Introduction

This text will explain why I made the decision to replace the AngularPrime library with the new AngularWidget library.

How AngularPrime started?

When I was learning AngularJS about 1 year and half ago, I saw the similarities between JSF and AngularJS (see also here) which was very familiar for me.
At that same time, the Primefaces JSF widgets were ported to jQuery and made available as PrimeUI.  That led me to the idea to use the PrimeUI widgets in an AngularJS format. And so AngularPrime widget started.

The integration went quit smooth.  I could use the PrimeUI code in almost unaltered form and needed to write some integration code so that the widgets played well with AngularJS

What went wrong.

During the last year I realised a few things about my work that I did.
  1. I wanted to bring AngularPrime closer to PrimeFaces.  I did some test, some conclusions can you read here, and they went very well.  The problem I have is that all my AngularJS directives are defined as attributes. So transforming them into tags and use the naming of PrimeFaces, proved a lot of work.
  2. Most of the time, there was a small tweak needed in the code of the PrimeUI widgets. Updating the code when the PrimeUI code changed, took some time. And making the changes in the code of PrimeUI was not always an option as some code tweaks had nothing to do with the functionality of the PrimeUI widgets
  3. And most of all, the code was using jQuery and jQuery UI.  These frameworks are not always popular in the AngularJS community. And indeed, I did already a small test last year and it is perfectly possible to create almost identical looking widgets with the same functionality by just using AngularJS code alone. (here you can read how to extend jQueryLight of AngularJS for this purpose)

AngularWidgets

So for the last few months, I was considering starting al over again. I doubted for a long time, I had put a considerable amount of time in AngularPrime, but now the decision is made.  AngularPrime is stopped and AngularWidgets is started.

It will make maximum use of the tag and attributes names of PrimeFaces.

It will probably take some time before the first commit appears on GitHub as summer is started.  And I want to spent first some time with the family.

Code will be available on GitHub and will also be licensed under the Apache v2 License.



Saturday, 15 March 2014

Testing Radio button group with Arquillian Graphene


Introduction

In the last blog post, I showed you how you can use the Arquillian Graphene Page fragments.  It allows you create reusable test components for screen elements.  You can encapsulate the required test functionality nicely which result in readable and maintainable test code.

But the @Root annotation can only be placed on a single WebElement, so how can you test the radio button input group?

Radio button group.

There are various occasions where you can select one option out of a list where each option is shown with a radio button in front of it.



Within the HTML code, you have various input elements with the same name. 

So how can you create a page fragment which point to the whole set of input fields? This allows to test the radio button styled input fields when you have for instance custom selection indications like angularPrime has.

Manual search


Since the @Root annotation cannot be placed on a Collection, like List, of WebElements, I came up with the following solution.

I created the RadioButtonGroup class which acts as a page fragment.  So it has one attribute which is marked as the @Root.  Since it is a normal Page fragment, I can use it in my test class as.

    @FindBy(name = "rd") 
    private PuiRadiobuttonGroup puiRadiobuttonDefault;

Although there are more then one element on the page that fulfil the selection criterium, only the first one is taken.  Well I’m not interested that it is the first one, as long as I get one of them without any exception being thrown.

So how do I get then the list of all radio button input elements that have the same name?
Each method in the page fragment checks if the list is already filled, if not, the following code is executed.

            List<WebElement> elements = driver.findElements(By.name(root.getAttribute("name"))); 
 
            buttons = new ArrayList<PuiRadiobutton>(); 
            for (WebElement element : elements) { 
                PuiRadiobutton radiobutton = new PuiRadiobutton(); 
                radiobutton.initializeManually(element, this); 
                buttons.add(radiobutton); 
            }

By using the driver, we can search for all elements with the same name and then instantiate an instance of the object which keep the reference to one of the radio button input fields.

The idea is that we mimic the Page fragment within the PuiRadiobutton class.  Setting the root element is quit easy, as we got a reference to it from the findElements on the driver instance.  But I need also the initialisation of the other attributes which are marked with @Drone and @FindBy to have a ‘real’ Page fragment.

In the Graphene code itself, I found the code which is responsible for injecting the references under normal circumstances.  I was able to use this to initialise my radio button instance.  The important part of my code is as follows:

            List<Field> fields = ReflectionHelper.getFieldsWithAnnotation(getClass(), FindBy.class); 
            for (Field field : fields) { 
                By by = FindByUtilities.getCorrectBy(field, How.ID_OR_NAME); 
                // WebElement 
                if (field.getType().isAssignableFrom(WebElement.class)) { 
 
                    WebElement element = root.findElement(by); 
                    setValue(field, this, element); 
                    // List<WebElement> 
                } else if (field.getType().isAssignableFrom(List.class) && getListType(field) 
                        .isAssignableFrom(WebElement.class)) { 
                    List<WebElement> elements = root.findElements(by); 
                    setValue(field, this, elements); 
                } 
 
            }

Conclusion

With the above explained hack, I’m able to create a page widget which represents a group of elements which has no unique identifier in the DOM tree, like a radio button group.
Now i can easily write some test code like

        assertEquals(2, puiRadiobutton.getNumberOfButtons()); 
        puiRadiobutton.clickButton(0); 
        assertEquals("2", puiRadiobutton.getSelectedValue());

It would be nice if the framework could foresee a solution for these kind of situations out of the box.


Thursday, 20 February 2014

Widget testing with Arquillian Graphene

Introduction

Integration testing is important but also difficult.  With frameworks like WebDriver we can connect to any HTML element in the browser.  This is a huge step forward.  We are able to inspect what is available on the screen, in the browser.
But coding in it is error prone. Any small change in the page layout and your test will fail because the element isn’t found anymore.
Another challenge is to keep your test code object oriented and readable.  Since everything is a WebElement in your code, you must resort to encapsulation and page fragments to not end up with large test methods which are unreadable.

Testing PrimeUI

That was also the path I took when I started testing the AngularPrime widgets, now more then a year ago.
I created widgets wrappers, like PuiInput, PuiCheckbox and so on that knew the internal DOM structure of the widget in the browser. They all have high level methods like click() and isChecked() that shield the internal stuff away from the developer.
But I never came to the point I was satisfied with the code.  That is why the testing part of AngularPrime was never committed to GitHub. It had various helpers and things really got messy when I added more and more widgets. Carrying around the WebDriver instance to have connection to the browser was the ugliest thing.

And then I don’t mention the need for a custom testRunner so that I could run the same tests on the different Browsers.

Arquillian Graphene

Some time ago, I came in contact with the Arquillian Graphene. It is a framework on top of WebDriver that uses Arquillian and other subprojects as Arquillian Drone to have better integration testing capabilities. But in the beginning it was very confusing, because you have so many parts in  the equation. And setting the whole thing up, with all his different maven artifacts, failed more then once.

But about a month ago, I decided to do it the hard way and spend more time in investigating the option to write all integration tests using Arquillian Graphene. I found out that using the client mode testing, where Arquillian is not deploying any WAR artifact to a server, was the easiest.  And in my case also the best solution as almost all my sources are HTML and JavaScript.

And with the Page Fragment feature, it turned out that I could write beautiful structured tests where each widget is encapsulated by a page fragment. So now I’m in the process of rewriting my 100+ integration tests using Arquillian Graphene. But it goes amazingly fast.

Page Fragment

With a Graphene Page Fragment you can encapsulate a part of the page, but also a single widget.  And it turns into a reusable component. Ideal for testing the widgets of AngularPrime.
So this is the class for an easy widget like pui-input (partial code)

public class PuiInput {
    protected static final String PUI_DISABLED = "ui-state-disabled";

    @Root
    protected WebElement root;

    protected boolean containsClassName(WebElement element, String className) {
        return element.getAttribute("class").contains(className);
    }

    public void click() {
      root.click();
    }

    public boolean isDisabled() {
        return containsClassName(root, PUI_DISABLED);
    }

//...
}


So it is a simple POJO class where the encapsulating HTML element is injected in the property annotated with @Root.

This Page fragment can be used in a Page object (not needed for my tests but very recommended in the testing of real applications) or directly in a test class as follows.

@RunWith(Arquillian.class)
public class InputTest {

    @Drone
    private WebDriver driver;

    @FindBy(id = "default")
    private PuiInput puiInputDefault;

    @Test
    @RunAsClient
    public void testDefault() {
        driver.get("http://localhost ...");

        assertFalse(puiInputDefault.isDisabled());
    }

}


The special test runner Arquillian does all the magic. @RunAsClient indicates that we don’t want to deploy anything on the server and that the tests runs as a client, not on the server. The @Drone annotated field gets the object that connect to our browser. By default this is the PhantomJS (headless browser designed for testing) but we can also choose to use Chrome, Firefox or any other supported browser.

The puiInputDefault property gets populated by our page fragment, and the @Root annotated field, within our Page Fragment, will get a proxy to the HTML element with id default. Indeed a proxy as when our test class is instantiated and injected with all those objects, the browser isn't available yet and thus a real link to the HTML element is not yet possible. The proxy is resolved at the time we first access the real WebElement, in our little test case, this is at the time we call the isDisabled() method.

More advanced page fragments.

A widget like pui-checkbox has a more complex DOM structure but this is no problem for Arquillian Graphenes Page fragments.  This image shows the structure of the widget.

pui-checkbox-dom

In the case we make a Page Fragment, our root will point to the, now hidden, input field. And the most interesting parts are the divs with class pui-checkbox-box and pui-checkbox-icon.

But with a page fragment, we can reference also other WebElements then the root.  This is how the PuiCheckbox class could look like.

public class PuiCheckBox {

    @Root
    protected WebElement root;

    @FindBy(xpath = "../../div[contains(@class, 'pui-chkbox-box')]")
    private WebElement box;

    @FindBy(xpath = "../../div[2]/span[contains(@class, 'pui-chkbox-icon')]")
    private WebElement icon;

    protected boolean containsClassName(WebElement element, String className) {
        return element.getAttribute("class").contains(className);
    }

    public void click() {
       box.click();
    }

    public boolean isChecked() {
       return containsClassName(icon, "ui-icon-check");
    }
}


The difference with the PuiInput code, is that we now have additional properties annotated with @FindBy.  They refer to other WebElements but relative to the root.  According to the DOM structure of pui-checkbox widget, the box links to the visible area of the widget where you should click on. By using the icon element, we can determine if the widget appears checked or not.

Need for WebDriver ?

In the case you do need to access the WebDriver instance to perform any action on the browser, like for instance interacting with an alert, you can annotate a property with @Drone here also.  Then the WebDriver instance is also injected in to your Page Fragment.

Conclusion

With Arquillian Graphene, we are able to create object oriented tests where we can encapsulate some screen parts of the browsers. Due to the nice dependency injection, your code becomes clean and readable.

Next time, I’ll discuss some more advanced widgets like the radio button group and the solution I came up with for handling such cases.

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.