Sunday, July 10, 2016

Alphasoftware and AngularJS - part 4

Alphasoftware and AngularJS - part 4.


Date: July 10th 2016.

Good morning everyone.
Last week we built main menu successfully, today we will redirect to the contents of at least one page to show you the fundamentals how it is done.
If you remember hello gandhi post where I sent a http call to the alpha server which provided a message "hello gandhi" and angular js posted that message on the html page, we will be using the same method to get the data from alpha server.  The alpha server will query a mysql backend database and execute the query and fashion the output as json object.  And angular js will get the output to display, we will modify with bootstrap to look beautiful

So here is the xbasic code that runs in  alpha server to fetch the items from inventory table.

<%a5
Response.headers.set("Access-Control-Allow-Origin", "*")
dim cn as sql::Connection
dim result as l = .f.
dim args as sql::Arguments
dim rs as sql::ResultSet
dim msg as c
dim sqlSelect as c
result = cn.Open("::Name::alpha_blog")
if result then
sqlSelect = "SELECT id, brand, description, unit_price FROM inventory ORDER BY brand"
result = cn.Execute(sqlSelect)
if result then
rs = cn.ResultSet
msg = rs.ToJSONObjectSyntax()
msg = "{\"items\":["+strtran(msg,crlf(),",")+"]}"
msg = strtran(msg,"'","\"")
else
msg = "\"items\":([\"msg\" : \"unable to get records\"])"
end if
cn.Close()
else
msg = "\"items\":([\"msg\" : \"unable to get connection\"])"
end if
?msg
%>

As you can see the alpha a5w page contains nothing but xbasic code and puts out the data as json formatted data.  (I am using version 11 and in that version I do need to convert the json to format properly with double quotes).

So when a call to this a5w page happens alpha serves up the data to the call.
And now back in the angularJs to harvest the data and show it on the page.

If you remember in the app.js we had a route 
.when('/items', {
        templateUrl: 'partials/items.html',
        controller: 'itemsCtrl'
        })
that redirects to the items page and uses the itemsCtrl controller as content director.
Now we will build that controller.

'use strict';
var SERVER = "http://xx.xx.xx.xx:port/";

alphaBlog.controller('itemsCtrl', function($scope, $http) {
    $http.get(SERVER + "alpha_blog/itemsCallback.a5w")
            .success(function(response) {$scope.items = response.items;});
                             });

As you can see the response.items is now assigned to $scope.items.
If you just leave it alone you will see page full of items, not pleasing.  So now we are going to use angularJs directive ng-repeat to go thru each item an display nicely, something for n next n loop in alpha.
So replace the items.html to 
<div>
<h1>Items</h1>
    <table>
    <thead>
        <td>Brand</td>
        <td>Description</td>
        </thead>
    <tr ng-repeat = "x in items">
        <td>{{x.brand}}</td>
        <td>{{x.description}}</td>
        </tr>
    </table>
    
</div>
Here we are using ngRepeat directive ( note when we state, we state ng-repeat in the html, since the directive will be interpreted by angularJs for proper camelCase since css can also be included in the HTML markup).  The ngRepeat cycles thru the items and displays the content in a tabular form.  You can use table to <li> </li> construct to display.

Okay if you notice that i am pulling only few fields from the inventory table and yet again I am only displaying fewer fields, right.  Unlike alpha I am not calling large amount of data once and keep playing with that data, I make repeated calls to the server and display as needed.  This makes loading time shorter and make the user experience better. Should you decide to use local storage to feed the data it will be even faster and not dependent on the internet connection.

So for so good, now we will apply bootstrap css to make it look better with alternate coloring and panels. And we will be adding a back button to get back to the home - main menu panel. We will also add search feature to search the list to show only the item we need to see.
So here is the next version of the items html with css and back button:

<div>
 <div class="container-fluid"> 
            <a href="#/" class="btn btn-info btn-md">
            Back to Home
            </a>
    
<div class="panel panel-default">
        <div class="panel-heading">
           <h3 class="panel-title">Item List</h3>
        </div> 
</div>
            
    Search: <input id="searchID" type="text" ng-model="itemName">
        <table class="table table-striped table-condensed">
        <thead>
        <td>Name</td>
        <td>Description</td>
        </thead>
    
    <tr ng-repeat="x in items | filter:itemName">
        <td><a href="#/items/{{x.id}}">{{x.brand}}</a></td>
        <td>{{x.description}}</td>
    </tr>
     </table>
       
            </div>   
</div>

If you notice that I have added a link to id field, that will display the detailed information for that item corresponding to that id number.
Now we will build item detail html.  As you expect this will need a controller, itemsDetailCtrl which will call the server with the id number of the item and fetch the data and we will again use bootstrap css to make that look nicer.
So here is the detail page:

<div ng-controller="itemsDetailCtrl">
    <div class="container-fluid"> 
    <a href="#/items" class="btn btn-info btn-md">
     Back to item
    </a>
        <h2>Item Detail</h2>
   <div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">Item Detail For: {{item_detail[0].brand}}</h3>
  </div>
       
  <div class="panel-body">
    Item ID: {{item_detail[0].id}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Brand: {{item_detail[0].brand}}
  </div>
      <div class="panel-body">
    Description: {{item_detail[0].description}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Size: {{item_detail[0].size}}
  </div>
      <div class="panel-body">
    Price: {{item_detail[0].unit_price | currency}}
  </div>
      <div class="panel-body" style="background-color:#F0F0F0 ">
    Notes: {{item_detail[0].notes}}
  </div>
</div> 
    </div>
    
And to control the detail page here is the itemsDetailCtrl:
(add this right below the itemsCtrl, so it looks like this)

'use strict';
var SERVER = "http://xx.xx.xx.xx:port/";

alphaBlog.controller('itemsCtrl', function($scope, $http) {
    $http.get(SERVER + "alpha_blog/itemsCallback.a5w")
            .success(function(response) {$scope.items = response.items;});
                             });

alphaBlog.controller('itemsDetailCtrl', function($scope, $routeParams, $http) {
        $scope.item_id = $routeParams.item_id;
        $http.get(SERVER + "alpha_blog/item_DetailCallback.a5w",{params:{item:$scope.item_id}})
            .success(function(response) {$scope.item_detail = response.item;});
       });
and the server will process this http call and respond with the item in question as a json object, and here is the a5w page that does the trick:

<%a5
Response.headers.set("Access-Control-Allow-Origin", "*")
dim cn as sql::connection
dim result as l=.f.
dim args as sql::arguments
dim rs as sql::resultset
dim sqlSelect as c
dim msg as c
dim flag as l=.f.
dim item_id as n
dim item as c
'item=2008
item_id = convert_type(item,"N")
result = cn.Open("::Name::alpha_blog")
if result then
sqlSelect = "SELECT id, brand, description, size, unit_price, notes FROM inventory WHERE id = :newID"
args.Set("newID", item_id)
result = cn.Execute(sqlSelect,args)
if result then
rs = cn.ResultSet
msg = rs.ToJSONObjectSyntax()
msg = "{\"item\":["+strtran(msg,crlf(),",")+"]}"
msg = strtran(msg,"'","\"")
end if
cn.close()
else
msg = "{\"item\":\"unable to open connection to the database\""
end if
?msg
%>

So when the items page is listing all the items and when you click on the brand name, the link takes the item.id and passes as a parameter to the http call and returns the response object.
The detail page the uses the bootstrap to fashion it in a nice way and angularJs display the data as array object with elements that we need.

All the controllers are listed in the same page and that page is called blogController.js and the index.html lists the link to the source file for the script tags so the controllers are called in when the index.html is loaded.
So now so far we have seen how to model the scope object and use http to fetch data and implement search and show detail, isn't that cool todo with alpha and angularJs.

So we will see how this evolves:

Please post any comments, so that I can improve the presentation written or the video.
Thank you.