Angular JS Integration

Previous Next

For those of you who do not know Angular, it is among the most promising JavaScript application development frameworks. It is sponsored by Google, and has been witnessing explosive growth in the Enterprise space, where most of our customers are. For our Flex customers moving to JavaScript, angular will be a breath of fresh air. In fact, the feature set provided by angular are so similar to the Flex features, you would be pleasantly surprised by the number of concepts that Flex had that also exist in Angular. Data Binding, MVVM, Templates, Form Validation, to name a few.


The purpose of this topic is not to go into details of Angular JS, but there are some excellent resources on line that do this. There is also a book written by Jeffrey Houser, Life After Flex which is a good read if you are a Flex Developer moving to Angular JS : https://www.lifeafterflex.com/


AngularJSForFlexDevelopers/ In this topic, we are going to focus on the work that we have been doing make use of Angular JS features to make the lives of our customers easier. For Flex developers, the concept of MXML within view is second nature. Angular directives bring this same power to HTML developers. Seeing is believing , so let's take a look at a quick example of what this means:


Let's quickly look at the steps involved:




There are two key advantages of using Angular directive for HTMLTreeGrid.

  1. You get to use the excellent modularization of the grid markup, and keep it separate from scripting logic. This makes code organization a lot cleaner, since markup for the grid usually becomes quite verbose, and mixing it with callback functions, event handlers tends to get bulky.
  2. You get to define callback functions on your scope, because the scope automatically becomes the delegate for the grid. So the functions need not be added to the flexicious namespace (or have a custom namespace - like myCompanyNameSpace used in many of our examples). For example, you can do something like :$scope.onGridCreationComplete = function (evt), and use it in the markup as  xicreation-complete="onGridCreationComplete", and the scope will be inspected for that function name first.

                   


That said, lets take a look at an example:


<!DOCTYPE html>

<html lang="en">

<head>

   <title>Tree Grid Sample</title>


   <!--These are jquery and plugins that we use from jquery-->

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery-1.8.2.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery-ui-1.9.1.custom.min.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.maskedinput-1.3.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.watermarkinput.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.ui.menu.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.toaster.js"></script>

   <!--End-->


   <!--These are specific to htmltreegrid-->

   <script type="text/javascript" src="http://htmltreegrid.com/demo/minified-compiled-jquery.js"></script>

   <script type="text/javascript" src="http://htmltreegrid.com/demo/examples/js/Configuration.js"></script>

   <script type="text/javascript" src="http://htmltreegrid.com/demo/themes.js"></script>


   <!--End-->


   <!--css imports-->

   <link rel="stylesheet" href="http://htmltreegrid.com/demo/flexicious/css/flexicious.css" type="text/css"/>

   <link rel="stylesheet"

         href="http://htmltreegrid.com/demo/external/css/adapter/jquery/jquery-ui-1.9.1.custom.min.css"

         type="text/css"/>

   <!--End-->


   <!--AngularJs -->

   <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>

   <script type="text/javascript"            src="http://htmltreegrid.com/demo/flexicious/js/htmltreegrid-angular-directive.js"></script>

                           

   <!--End-->


   <script>


       angular.module('app', ['fdGrid'])

               .factory('localStorage',function(){

                   return {};

               })

               .controller('myCtrl', function ($scope) {


                   $scope.gridOptions = {


                       dataProvider: [

                           { "id": "5001", "type": "None" },

                           { "id": "5002", "type": "Glazed" },

                           { "id": "5005", "type": "Sugar" },

                           { "id": "5007", "type": "Powdered Sugar" },

                           { "id": "5006", "type": "Chocolate with Sprinkles" },

                           { "id": "5003", "type": "Chocolate" },

                           { "id": "5004", "type": "Maple" }

                       ]   ,

                       delegate: $scope


                   };


                   $scope.onGridCreationComplete = function (evt) {

                       var grid = evt.target;

                       grid.validateNow();

                       alert(grid.getDataProvider().length);

                   };


               })

   </script>

</head>

<body>

<div ng-app="app">

   <div ng-controller="myCtrl">


       <!-- Tree Grid -->

       <div id="gridContainer" fd-grid="" ng-model="gridOptions" style="height: 400px;width: 100%;" xicreation-complete="onGridCreationComplete"

            xienable-Print="true" xienable-Preference-Persistence="true" xienable-Export="true" xiforce-PagerRow="true"

            xipage-Size="50" xienable-Filters="true" xienable-Footers="true">

           <level>

               <columns>

                   <!-- Don't forget <column xidata-Field="id" xiheader-Text="ID"> will not work -->

                   <column xidata-Field="id" xiheader-Text="ID"></column>

                   <column xidata-Field="type" xiheader-Text="Type"></column>

               </columns>

           </level>

       </div>


   </div>

</div>

</body>

</html>




And here is one with support for hierarchy:




<!DOCTYPE html>

<html lang="en">

<head>

   <title>Tree Grid Sample</title>


   <!--These are jquery and plugins that we use from jquery-->

   <script src="//www.parsecdn.com/js/parse-1.3.0.min.js"></script>


   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery-1.8.2.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery-ui-1.9.1.custom.min.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.maskedinput-1.3.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.watermarkinput.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.ui.menu.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/external/js/adapters/jquery/jquery.toaster.js"></script>

   <!--End-->


   <!--These are specific to htmltreegrid-->

   <script type="text/javascript" src="http://htmltreegrid.com/demo/minified-compiled-jquery.js"></script>

   <script type="text/javascript" src="minified-compiled-jquery.js"></script>

   <script type="text/javascript" src="http://htmltreegrid.com/demo/examples/js/Configuration.js"></script>

   <script type="text/javascript" src="http://htmltreegrid.com/demo/themes.js"></script>


   <!--End-->


   <!--css imports-->

   <link rel="stylesheet" href="http://htmltreegrid.com/demo/flexicious/css/flexicious.css" type="text/css"/>

   <link rel="stylesheet"

         href="http://htmltreegrid.com/demo/external/css/adapter/jquery/jquery-ui-1.9.1.custom.min.css"

         type="text/css"/>

   <!--End-->


   <!--AngularJs -->

   <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>

   <script type="text/javascript"

           src="http://htmltreegrid.com/demo/flexicious/js/htmltreegrid-angular-directive.js"></script>


   <!--End-->


   <script>

       angular.module('app', ['fdGrid'])

               .factory('localStorage', function () {

                   return {};

               })

               .controller('myCtrl', function ($scope, gridService) {



                   var dummyServerPreferences = "";


                   $scope.gridOptions = {


                       dataProvider: [

                           { "id": "5001", "type": "None" },

                           { "id": "5002", "type": "Glazed" ,"sub":[

                               {"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}

                           ]},

                           { "id": "5005", "type": "Sugar" ,"sub":[{"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}]},

                           { "id": "5007", "type": "Powdered Sugar" ,"sub":[{"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}]},

                           { "id": "5006", "type": "Chocolate with Sprinkles" ,"sub":[{"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}]},

                           { "id": "5003", "type": "Chocolate" ,"sub":[{"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}]},

                           { "id": "5004", "type": "Maple" ,"sub":[{"id":"1","price":"10"},{"id":"2","price":"11"},{"id":"3","price":"9.5"},{"id":"4","price":"10"}]}

                       ],

                       delegate: $scope


                   };


                   $scope.onGridCreationComplete = function (event) {

                       var grid = event.target;

                       grid.validateNow();

                   };


               })

   </script>

</head>

<body>

<div ng-app="app">


   <div ng-controller="myCtrl">


       Tree Grid

       <div id="gridContainer" fd-grid="" ng-model="gridOptions" style="height: 400px;width: 100%;"

            xicreation-complete="onGridCreationComplete"

            xienable-Print="true" xienable-Preference-Persistence="true" xienable-Export="true" xiforce-PagerRow="true"

            xienable-Drill-Down="true"

            xipage-Size="50" xienable-Filters="true" xienable-Footers="true">

           <level xichildren-Field="sub">

               <columns>

                   <!-- Don't forget <column xidata-Field="id" xiheader-Text="ID"> will not work -->

                   <column xidata-Field="id" xiheader-Text="ID"></column>

                   <column xidata-Field="type" xiheader-Text="Type" xiheader-Align="middle"

                           xifilter-Control="MultiSelectComboBox" xifilter-Combo-Box-Build-From-Grid="true"

                           xienable-Filter-AutoComplete="true"></column>

               </columns>


               <next-Level>

                   <level >

                       <columns>


                           <column xidata-Field="id" xiheader-Text="ID" xihide-Header-Text="true"></column>

                           <column xidata-Field="price" xiheader-Text="Price" xihide-Header-Text="true"></column>

                       </columns>

                   </level>

               </next-Level>

           </level>


       </div>



   </div>

</div>

</body>

</html>


For hierarchical grids, we add a the next-level tag [next-level] after columns. The XML structure would be the same as any of our examples in the demo, just with angular-style property names.


You can download these files from http://blog.htmltreegrid.com/post/Angular-JS-Support.aspx