Skip to main content

The Conversion: Lay of the Landing Page - Part 2

In Part 1 of developing the landing page for the new travel application, we set up the landing controller and created the the CF function to get the trips relevant to the user. The next step is to begin developing the UI, the landing.html template, so we can actually see the trips.

Just a quick refresher - the landing controller code is a follows:
 angular.module('core').controller('LandingController',['$scope','dataService', function($scope,dataService){  
   $scope.trips = [];  
   dataService.call('getTrips').then(function(data){  
     $scope.trips = data.data;  
   })  
 }]);  
And the landing template is empty at the moment.
 <div ng-controller="LandingController as ctrlLanding">  
   <h3>TRIPS</h3>  
 </div>  
The first step for the landing template is to create the table. This includes setting up the columns and looping through the $scope.trips array and generating the rows.
 <div ng-controller="LandingController as ctrlLanding">  
   <h3>TRIPS</h3>  
   <table class="table">  
     <tr><th>Trip Name</th>  
       <th>Destination</th>  
       <th>Type</th>  
       <th>Departure</th>  
       <th>Arrival</th>  
     </tr>  
     <tr ng-repeat="trip in trips">  
       <td>{{trip.NAME}}</td>  
       <td>{{trip.DESTINATION}}</td>  
       <td>{{trip.TYPE}}</td>  
       <td>{{trip.OUTBOUNDDEPARTURE}}</td>  
       <td>{{trip.INBOUNDARRIVAL}}</td>  
     </tr>  
   </table>  
 </div>  
This is some pretty basic not so exciting stuff which yields:
In thinking about this, there are few things to add to the page. The total number of participates would be helpful to the user contrasted with the total number that filled out the required documentation. The page also needs a filter by trip name. Most users have many trips, so a filter can help them access a particular trip quickly.  I've also thought about adding pagination, but in this case, it's not necessary since the list of active trips won't be large. That said, for administrative users who see all trips, pagination may be a valuable tool. The organization of the data will dictate if paging is necessary.

For the filter, we are going to use the AngularJS filter system. Our ng-repeat="trip in trips" in the template will change to ng-repeat="trip in trips | filter: filterTrips. This simple change will cause the filterTrips to be applied to each trip. Next, the controller is updated with a filterTrips function.
 angular.module('core').controller('LandingController',['$scope','dataService', function($scope,dataService){  
   $scope.trips = [];  
   $scope.tripFilter = '';  
   dataService.call('getTrips').then(function(data){  
     $scope.trips = data.data;  
   })  
   $scope.filterTrips = function(_item){  
     var _r = false;  
     if (  _item.NAME.toLowerCase().indexOf($scope.tripFilter.toLowerCase()) > -1 ||  
         _item.DESTINATION.toLowerCase().indexOf($scope.tripFilter.toLowerCase()) > -1 ||  
         $scope.tripFilter.length == 0 ) {  
       _r = true;  
     }  
     return _r;  
   }  
 }]);  
The $scope.filterTrips function takes one parameter which is the item in the ng-repeat.  If the function returns true, the item is included in the repeat.  If the item is false, it will not be included. The if statement is doing the work where it's looking at name and destination, switching everything to lowercase, and testing to see if $scope.tripFilter is part of the text.  The landing template has been updated with the filter input.
 <div ng-controller="LandingController as ctrlLanding">  
   <h3>TRIPS</h3>  
   <div class="alert alert-info">Welcome to the Travel Resource Information Planning System (TRIPS).</div>  
   <div class="input-group">  
     <span class="input-group-addon">Filter</span>  
     <input class="form-control" ng-model="tripFilter"></input>  
   </div>  
   <table class="table">  
     <tr><th>Trip Name</th>  
       <th>Destination</th>  
       <th>Type</th>  
       <th>Departure</th>  
       <th>Arrival</th>  
     </tr>  
     <tr ng-repeat="trip in trips | filter: filterTrips">  
       <td>{{trip.NAME}}</td>  
       <td>{{trip.DESTINATION}}</td>  
       <td>{{trip.TYPE}}</td>  
       <td>{{trip.OUTBOUNDDEPARTURE}}</td>  
       <td>{{trip.INBOUNDARRIVAL}}</td>  
     </tr>  
   </table>  
 </div>  
Since I only have a single trip assigned to me, it would be nice to see a more practical use case.

Now lets filter on "land" and see what happens.  Anywhere "land" exists in the Trip Name or Destination field, that trip will be displayed.
That's some pretty decent functionality with very little code.  But there still is more work to be done on the landing page.  Column sorting is always a big feature with users.  Also, there needs to be a way to delineate between current and old trips.  In the Flex-based TRIPS application, users are able to archive trips which pushed them out of their main folder and into another.  But that requires the user to initiate the process. I am thinking for this system we can separate trips by whether the trip has occurred, is occurring or is going to occur.  We also should display the participant count as described earlier in the post. And finally, we need some navigation to the next route which will be trip details.  So I guess there will be a Part 3.

Hope you are enjoying the posts so far.  Feedback is always welcome as it usually makes be a better developer.

Cheers!

Comments

Popular posts from this blog

The Conversion: MAIN.CFM

Within the current development pattern I have for our portal system, the main.cfm is the starting point for an application. For the most part, this is really boilerplate and serves to get the application off the ground. The way the portal works is that the user lands on the main menu page and provide with a menu of options. Each option is called a function and is assigned a unique id. When the user clicks on a menu option, the page is reloaded with the function id. The process checks to see if the user is actually allowed to have access to the function. It then accordingly looks up the path and displays the page via a . In the case of the TRIPS application, the included file is the main.cfm page for the application. So far the project looks like this: we have the folder structure defined with no files aside from the main.cfm. The main.cfm contains a few javascript includes, the overarching controller for the application as well as the route viewer. The next blog post will foc...

The Conversion: Lay of the Landing Page - Part 1

In the last post  the groundwork has been laid for real development to begin. The data service, router, and landing pages have been created and are ready for code. The last thing to add for this part of the process is the Coldfusion component. A data folder has been added to store any cfcs relevant to the TRIPS application. The first is to write the CFFUNCTION that will return the list of trips. My development pattern for creating CF functions is fairly routine.  First, decide on a name, parameters and return type.  Sometimes the naming of a function is the hardest part.  I've settled on actionDataObject.  So in this case, the function will be named: getTrips.    At moment, the landing controller (landing.js) is empty. angular.module('core').controller('LandingController',['$scope','dataService', function($scope,dataService){ }]); The basic task of this controller is getting the list of trips.  First is the establishment of an empty tr...

Dynamically Loading an AngularJS UI.Router

When starting out on my AngularJS journey, I couldn't get a good handle on the router native to the framework. So I adopted the use of the wonderful angular-ui / ui-router.  During the past few years of development, I've honed in (for better or worse) my paradigm for setting new applications and nearly every AngularJS app has a routes.js file. Without going into background, I wanted a way to load the ui-router dynamically. Typically, the routes gets defined in a .js file and typically looks something like this: angular.module('core').config(function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise("/landing/201820"); $stateProvider .state('landing', {url: "/landing/:term", templateUrl: "apps/noted/templates/landing.html"}) .state('uploadCalendar', {url: "/uploadCalendar", templateUrl: "apps/noted/templates/uploadCalendar.html"}) .state('noteTakers...