Flipboard is an app that presents news magazines, Facebook, Twitter, and blogs in a glossy magazine format. I’m a big fan and use it almost exclusively to look at news, twitter, and Facebook. Flipboard looks amazing on an iPad, Android Tablet, and Microsoft Surface Pro2. The surprising thing is how handy it is for the iPhone. The display is responsive, so it usually looks pretty good. Way better than just browsing on the iPhone’s native internet browser.

Beaglesong has several Flipboard magazines, mostly for web technology. Get Flipboad and subscribe to them. You will find the latest info and blog post on the topic as well as an in-depth dive into certain areas that are a result of searching for a particular answer on the web and stumbling across some great blogs.

In this example, the result from a speech recognition is returned and it would be nice if the results were formatted in a nice table. Because the speech recognition grammar supports multiple words and phases, the result is not the same every time, making building an static HTML table impossible. When building a table to house object, with an variable number of elements, ng-repeat is a powerful tool from Google’s Angularjs that can help.

Angularjs

In the code sample below, $scope.results is a speech recognition results object that contains the hypothesis, confidence scores for each word in the hypothesis, and some result tokens that are representative of the result. In this case, the result is a military grid location in MGRS format. A horizontal table, with the scores aligned with the words is needed to display the word scores, and a vertical table is more appropriate for the token pairs.

 $scope.results = {  
           "nbest": [{  
               "hypothesis": "one seven charlie romeo romeo one two three four five six",  
               "wordScores": {  
                 "score": [  
                   0.219999999,  
                   0.310000002,  
                   0.219999999,  
                   0.600000024,  
                   0.340000004,  
                   0.560000002,  
                   0.5,  
                   0.670000017,  
                   0.860000014,  
                   0.839999974,  
                   0.579999983  
                 ],  
                 "word": [  
                   "one",  
                   "seven",  
                   "charlie",  
                   "romeo",  
                   "romeo",  
                   "one",  
                   "two",  
                   "three",  
                   "four",  
                   "five",  
                   "six"  
                 ]  
               }  
             }],  
           "nlu-sisr": [{  
               "id": 0,  
               "interp": {  
                 "MGR": "17CRR123456",  
                 "MGRSAccuracy": "100m",  
                 "MGRSEasting": "123",  
                 "MGRSGridZone": "17C",  
                 "MGRSNorthing": "456",  
                 "MGRSNumerical": "123456",  
                 "MGRSSQID": "RR"  
               },  
               "time": 0.0122458935  
             }],  
         };  

The javaScript for the word score table. Angularjs evaluates the expression inside of {{‘expression’}}, replacing {{key}} and {{val}} with the token and it’s associated value, and ng-repeat loops through the object.

 <div class="row">  
   <div class="span8">  
     <!--create token:value table-->  
     <table border="1">  
       <tr>  
         <th colspan='2'>Tokens</th>  
       </tr>  
       <tr>  
         <th>Token</th>  
         <th>Value</th>  
       </tr>  
       <tr ng-repeat="(key,val) in results['nlu-sisr'][0].interp">  
         <td>{{key}}</td>  
         <td>{{val}}</td>  
       </tr>  
     </table>  
   </div>  
 </div>  

Makes a table that looks like this…

Tokens
Token Value
MGRS 17CRR123456
MGRSAccuracy 100m
MGRSEasting 123
MGRSGridZone 17C
MGRSNorthing 456
MGRSNumerical 123456
MGRSSQID RR

 

Going horizontal for the word confidence scores …

 <div class="row">  
   <div class="span8">  
     <table border="1">  
       <tr>  
         <th colspan="18">Word Confidence Scores</th>  
       </tr>  
       <tr>  
         <td ng-repeat="word in results.nbest[0].wordScores.word">{{word}}</td>  
       </tr>  
       <tr>  
         <td ng-repeat="score in results.nbest[0].wordScores.score">{{score.toFixed(2)}}</td>  
       </tr>  
     </table>  
   </div>  
 </div>  

 

Creates a table that looks like this

 

Word Confidence Scores
one seven charlie romeo romeo one two three four five six
0.22 0.31 0.22 0.60 0.34 0.56 0.50 0.67 0.86 0.84 0.58

 

All of the examples for Angularjs using partial.html files show simple links to change to these views. When I tried to change these to buttons to get a nicer looking page, i discovered that the buttons wouldn’t show which was the active button. To accomplish this task, I created a new controller called NavCrtl. The secret sauce for reaching out of the partial back to the navbar is located in that controller. As with all Angularjs applications, you need to add ng-controller to the div that contains the navbar ( ng-controller=”NavCtrl” ). ng-class=”{ active: activePath==’/view1′ }” links back to the controller to switch which button is active.


        <div class="navbar navbar-fixed-top" ng-controller="NavCtrl">
            <div class="navbar-inner">
                <div class="container-fluid">
                    <a href="#" class="brand">SR Demo</a>  
                    <div class="navbar-text pull-right">Logged in as <a href="#">username</a></div>
                    <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">Menu </a>
                    <div class="nav-collapse">
                            <div class="btn-toolbar">
                                <div class="btn-group">
                                    <a href="#/view1" class="btn btn-large" ng-class="{ active: activePath=='/view1' }">Overview</a>
                                    <a href="#/view2" class="btn btn-large" ng-class="{ active: activePath=='/view2' }">SR Input</a>
                                    <a href="#/view3" class="btn btn-large" ng-class="{ active: activePath=='/view3' }">SR Output</a>
                                    <a href="#/view4" class="btn btn-large" ng-class="{ active: activePath=='/view4' }">Map</a>
                                </div>
                            </div>
                    </div>
                    <!--/.nav-collapse -->
                </div>
            </div>
        </div>

the controllers.js file…

 angular.module('myApp.controllers', []).  
 controller('MyCtrl1', ['$scope', function($scope) {  
 }])  
 .controller('NavCtrl', ['$scope', '$location', '$route',function($scope, $location, $route) {  
 //NavCtrl to ensure that menu buttons stay pushed in ("active" ) when active in the menu nav bar  
 $scope.activePath = null;  
   $scope.$on('$routeChangeSuccess', function() {  
     $scope.activePath = $location.path();  
     console.log($location.path());  
   });  
 }])  
 ;