Wednesday, May 21, 2014

Angular JS - Another Tool in your XPages Toolbox - Part 2

In my previous post, I shared my reason for wanting to try to learn how to use Angular within an XPage.  In this post, I will show you how I used Angular to duplicate the functionality of a Dojo data grid on the same page.

My Existing XPage

In my existing XPage, I use the Extension Library REST service control to return data based on what the current user has rights to see.  The REST service use a formula for "keys" which filters the data based on the first column.  The REST service outputs JSON which is read by the Dojo Data Grid.
Dojo DataGrid 
There are two thing that have always bugged me about the Dojo grid that I created.  The first was that I could never get column sorting to work.  It seemed to have a conflict with the user of the keys property that I could not overcome.  The second thing that bugged me was that I could not get the grid to behave in a responsive manner.  When I shrink the screen, the Dojo grid would not shrink with it. I accept that it is possible that in both cases I was doing something wrong there, but I did spend a lot of time trying to get those things to work.

Grid using Angular

Since I duplicating what I did with Dojo, I used an Angular plug-in called ng-grid.  I used the very same JSON data to display the grid inside a <div>.
Grid using Angular
The Angular Grid not only looks good, but the column sorting works as well.  This grid is naturally responsive and solves my two big gripes with the Dojo grid. 

Look, I'm responsive

The 'How To' Section

Before I go through my steps, let me say that this is not a beginners guide to Angular, to really understand it.
There is a lot of information out on the web on Angular. I highly recommend Mark Roden's latest series on Angular which takes a methodical approach that is easy to follow.

1)  First you have to load the library on your page.  After downloading Angular from Google, I copied the library in a folder I created under the "Web Content" subdirectory.

2)  I then referenced the library using a <script> tag in only the page where I used Angular.  Use Firebug to check that you loaded everything correctly.
3) I then create a Controller file and call it grid-controller and place it is a subdirectory under the "Angular" folder under "Web Content".   Repeat step 2 for the controller file, making sure to account for the subdirectory in your script tag.

4) Normally for a page using Angular, you will add an attribute to the <html> tag of "ng-app" telling Angular that you are using it on the whole page.   In my case, I added the "ng-app" attribute to a <div> on my page.  I actually used a <xp:panel>, and set the tagName to render as a <div>. I did it this way because I wanted to show how you would use an XPage control where you also decide whether to render the grid based on certain conditions.  The easiest route though, is to pass HTML through like in the second example below.

This is all the code needed on the custom control.  Note: Once div is nested in the other.
This is how it would look if you pass the HTML straight through

5) Angular also needs you to specify the name of the Controller to use for a specific element.  A normal Angular application might use several controllers throughout the page to connect the data to the display.  You tell Angular which one for a specific section by using the ng-controller attribute. In my case, I am only using a single controller that I set in the same <div>.  Besides setting the style, that is all I have on the custom control.

6)  In my controller, I need to tell where to get the model (data) to send to the view (XPage).  As I stated above, I am using the same JSON data as the Dojo Grid.  To access the JSON, I use $http.get() method to read the URL of my REST Service.  Remember, you can the pathInfo attribute in your REST service, which allows you to see the JSON in a URL. I set my pathInfo to "restData".  The result is set to a variable called $scope, which acts as your return value of the controller.

The Controller which in Angular connects the data and the display
From line 8 to the end is specific to the ng-grid plug-in which I explain below. Everything outlined up to this point is all you need to test out Angular in your XPage.  Before I added the grid to my demo, I was able to display the whole list using ng-repeat. I was also able to reference the data is $scope using direct references like this {poDoc[0].Status}}  The controller returns an array in this case. I could have done anything you can do in Angular to the data. I encourage you to give it a try.

The last part of the code refines the $scope to sets options and format for the grid.  In order to get the grid to work it had to be in its own <div> that was a child of the <div> where I set the ng-app and ng-controller.  The grid is not part of core Angular so in order to use it I did had to download and a separate javascript and css file. To find ng-grid look here, note that it has a dependency on jQuery. It gets a thumbs up in my book.

Where to from here

I am really intrigued by Angular, so I will continue to experiment with it.  Next, I would like to enhance the example here to allow the grid to launch documents and perform searching/filtering.  If the result is worth sharing then I will make a part 3 of this series.

Sunday, May 18, 2014

Angular JS - Another Tool in your XPages Toolbox - Part 1

Around this time last year Twitter Bootstrap was becoming the big thing in the XPage Community, and a year later it is widely adopted and has become another tool in your XPages toolbox.  Not that they are that similar but it seems that Angular.JS is now becoming the next big thing for 2014.

For the last several months I have observed with high interest as Mark Roden, Mark Barton, Jeff Byrd and perhaps others from the community have discussed Angular and other noun.js frameworks (backbone, ember, etc).  One common theme that I have noticed is the enthusiasm of eliminating everything front end that XPages provides and only using Domino for the security model and to serve up pages and JSON data.

I must admit that I am a little bothered inside when I try to understand what they are advocating. What bothers me is that I like XPages and what it brings to the table.  I like my XPages toolbox, and while I am always interested in a shiny new tool, I am not interested in trading it for another toolbox.

I totally respect those guys reasons for advocating their approach to front end javascript frameworks, and I am glad they are pushing the envelope in that area, and grateful they are sharing their knowledge.  When I say I am bothered it has more to do with my opinion that you can have both.  I would be lying if I didn't say the investment in time I have made to learning the whole XPages platform didn't have something to do with it.

To be clear, Marky is not saying everyone should follow his path, but as one of the leading bloggers in our community there is a certain pressure to follow the leader.  Speaking of leaders in our community, there is tangible vacancy as we all mourn the loss of Tim Tripcony.  It saddens me that I won't see Tim comment on this post as he sometimes did with others I wrote.

Given this background, I have set out to learn Angular.JS by creating a proof of concept for using it within an XPage.  I have decided to duplicate the functionality of a Dojo Data Grid using Angular.  In this two part blog series, I will show you how I used an Angular.JS within an existing Xpage.

Disclaimer:  

There is always a chance that after time passes, and I become more comfortable with the Angular framework and what all it can do, that I will agree and even advocate with what Marky and others have proposed.  I reserve the right to change my mind.

Learning Angular:

I really can't say that I know Angular that well, as I write it is only 7 days since I first dug into it.

Here is what I did to get up to speed:
  • First I read Marky Roden's blog series, which inspired me to dig deeper.  
  • I next turned to one of favorite resources, lynda.com and watched the course "Up and Running with Angular.JS" by Ray Villalobos.  Ray is one of the my favorite instructors on lynda.com and has a great website with the most awesome URL for a web developer - iviewsource.com
  • After I finished the course, I read Marky's blog post again, as well as those from Mark Barton and Jeff Byrd
With this background, and the assurance from Marky that is was possible, I dove right in my goal of making Angular work within a <div> of an existing XPage.  In part 2, I will share how and what I did.  I will even show how what I added was better than what I used before.