Monday, February 17, 2014

AngularJS CRUD Grid

Hi,

      I created a sample web application which showcases how to do CRUD operations + search + sort + page on a Table (lets call it DataGrid) using AngularJS, Bootstrap for standalone version and angular-notifications, NodeJS, MySql for servercode version.

What I learned:
    While am doing edit functionality for this application, i tried to get the edit textboxes values (DOM code) into the controller, after i learned somewhere the good practice - "DOM code should not be used in controller" - i wanted to try mapping bindings to these textboxes.
    First i approached with adding edit option (property) in each item instance, later i realized its just a waste of code repetition, so i came with edit option on $scope which maintains just ID of item instance in edit-mode. Later i refined it as 'updateItem' object on $scope, it maps binding to these textboxes in edit-mode and maintains values and error statuses. This object is also reused in insert operation.

While developing, i faced a challenge, how can i track 'records count' when angularjs built-in filter is used for search?
I found a way, i tracked it in 'paging' filter (which i created for page navigation on grid). To get access of 'records count' property of $scope into filter, there is no easy way, of course we can pass scope from UI into filter as parameter, but that's not good practice, so i had to create a service (SharedObject) which contains properties shared between controller and filter.

I created another service (HelperService), so that scope related logic should not get mixed-up with unrelated (reusable, independent) code blocks.

Javascript coding has:

1 Controller - appCtrl
2 Services:

  • RecordCount - which tracks total records count used between controller and paging filter.
  • HelperService - provides generic functionalities: validation operation, deletes a record from set of records, parses error object.

1 Filter:
paging - to support page navigation on the grid.


You can find both standalone (html), and restful supported versions for download below.
I haven't created test-cases for unit-testing the angular code.


RESTful support:

       Javascript code is implemented slightly different here than standalone version.

For restful support i have used:
at serverside:

  • node.js with express package used as restful server.
  • for database, i have used mysql.

at clientside:
  • ngResource - angularjs directive which is useful in restful coding.
  • ng-notification - is a third-party angularjs module, used as notification service.


Why MySql?
         I used mysql because my system (Ubuntu) already has it as part of LAMP stack. I don't want to install another DB (like, MongoDB) just because for this Application. Of course you can change app code to use MongoDB with minor changes if you like.
I used Phpmyadmin to create DB and Table, you can find the scripts in sql file in download Zip.

What i learned:
Mysql returns date with GMT time, but not with serverside local time (here IST).
It creates problem, it returns date with one day less with GMT time, because it converts serverside local time to GMT time while returning json. To resolve it, i did convert json date string to date object then manually create correct date string. (browser by default coverts GMT date to local (here IST: +5:30) date). If you think there is a better solution, you can share in comments.

I modified CSS, js code of ng-notification, to suit our purpose and to support bootstrap for icons.

For testing the restful server, i have used 'Postman' plugin for Chrome. (you can find 'postman_dump' file in downloads for your local import and test). Application development done in Ubuntu OS with sublime text editor.

In download Zip file, i haven't included node.js dependencies - express, mysql npm packages - you have to add them manually into unzipped folder (TestOne) or, since the Zip file has package.json, you can try running "npm install" using CLI pointing to the unzipped folder to install dependencies for the restful server (WebSqlRest.js).

How to Execute:
Run server from CLI pointing to the unzipped folder:

$ node WebSqlRest.js

Now open browser and type the url:
http://localhost:8800/product.html


References:
http://net.tutsplus.com/tutorials/javascript-ajax/introduction-to-express/
http://blog.modulus.io/nodejs-and-express-create-rest-api
https://github.com/felixge/node-mysql
http://derekries.github.io/angular-notifications/
https://kuler.adobe.com/explore/newest/   (for color themes)


Download and Demo:
Check the Demo here (and save locally)!
Download the Zip file here (restful)!