AngularJS example MotoAds more advanced than the tutorial on angularjs.org
I have just been learning AngularJS and decided to build demo application that cover more techniques than the tutorial on angularjs.org. This application is only demo so it do not have complete server side, some features have the todos and there is not any test.
This demo application is some kind of automotive adverts portal, so I called it MotoAds. It has two main features:
Root file
In
We define
In
We add to This demo application is some kind of automotive adverts portal, so I called it MotoAds. It has two main features:
- List of adverts – includes an advanced filtering and sorting.
- Add advert – a form with some client side field validations.
MotoAds application looks like this: | Application folders tree: |
Root file
index.html
included external resource:
bootstrap.css
(2.3.2)angular.js, angular-resource.js
(1.0.8)ui-bootstrap-tpls-0.6.0.js
(0.6.0)
app.css
app.js
services.js
controllers.js
Bootstrap angular application, add navigation and route templates
Inindex.html
we auto-bootstrap the angular application by defining directive ng-app
:
app.js
we define new angular module motaAdsApp
(name must be the same as value of ng-app
):
var motoAdsApp = angular.module('motoAdsApp', ['ui.bootstrap', 'motoAdsServices']);In
index.html
we use Navbar component from the bootstrap library:
NavbarController
with function routeIs
(used in ng-class
). It allows us to highlight link which is active.
motoAdsApp.controller('NavbarController', function NavbarController($scope, $location) { $scope.routeIs = function(routeName) { return $location.path() === routeName; }; });We add directive
ng-view
which renders the proper template into index.html
in case of the route definition:
Url routes are defined in
app.js
:
motoAdsApp.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', { controller: 'AdvertsController', templateUrl: 'views/adverts.html' }). when('/addAdvert', { controller: 'AddAdvertController', templateUrl: 'views/addAdvert.html' }); }]);
Adverts - list, filtering, sorting
Inadverts.html
we define the left filtering panel with brands and models. We use the ui.bootstrap.accordion component:
controller.js
we write AdvertsController
in which we using method Brand.query()
to fill $scope.brands
:
motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 'Country', 'Advert', function($scope, Brand, Country, Advert) { $scope.oneAtATime = true; $scope.brands = Brand.query(); // ... }]);Definition of the
Brand
service is in service.js
- it is the simple service which reads brands.json
:
motoAdsServices.factory('Brand', ['$resource', function($resource) { return $resource('data/:id.json', {}, { query: { method: 'GET', params: { id: 'brands' }, isArray: true } }); }]);Next in
adverts.html
we write filters for country, region and year (from-to):
adverts.html
the panel with information which filters are active and the options of removing them:
Filters:
{{filter.brandName}} {{filter.modelName}}
{{filter.country.name}}
{{filter.region.name}}
{{filter.yearFrom}}
{{filter.yearTo}}
Remove all
controller.js
we have to fill angular models, define variables and functions which are used by the filters:
motoAdsApp.controller('AdvertsController', ['$scope', 'Brand', 'Country', 'Advert', function($scope, Brand, Country, Advert) { $scope.oneAtATime = true; $scope.brands = Brand.query(); $scope.countries = Country.query(); $scope.sortByCols = [{ "key": "year", "name": "Year" }, { "key": "price", "name": "Price" }]; var allAdverts = Advert.query(filterAdverts); $scope.filter = { brandName: null, modelName: null, country: null, region: null, yearFrom: null, yearTo: null }; $scope.isAnyFilter = function() { var f = $scope.filter; if (f.brandName || f.modelName || f.country || f.region || f.yearFrom || f.yearTo) { return true; } return false; }; $scope.removeAllFilter = function() { $scope.filter = { brandName: null, modelName: null, country: null, region: null, yearFrom: null, yearTo: null }; }; $scope.addBrandModelFilter = function(brand, model) { $scope.filter.brandName = brand.name; $scope.filter.modelName = model.name; }; $scope.$watch('filter', filterAdverts, true); function filterAdverts() { $scope.adverts = []; angular.forEach(allAdverts, function(row) { if (!$scope.filter.country) { $scope.filter.region = null; } if ($scope.filter.brandName && $scope.filter.brandName !== row.brandName) { return; } if ($scope.filter.modelName && $scope.filter.modelName !== row.modelName) { return; } if ($scope.filter.country && $scope.filter.country.name !== row.countryName) { return; } if ($scope.filter.region && $scope.filter.region.name !== row.regionName) { return; } if ($scope.filter.yearFrom && $scope.filter.yearFrom > row.year) { return; } if ($scope.filter.yearTo && $scope.filter.yearTo < row.year) { return; } $scope.adverts.push(row); }); }; }]);We define the
Country
service in service.js
:
motoAdsServices.factory('Country', ['$resource', function($resource) { return $resource('data/:id.json', {}, { query: { method: 'GET', params: { id: 'countries' }, isArray: true } }); }]);Now we add the sorting option and the table containing the list of adverts:
controller.js
in this lines:
var allAdverts = Advert.query(filterAdverts); function filterAdverts() { $scope.adverts = []; angular.forEach(allAdverts, function(row) { // ... $scope.adverts.push(row); }); };The
Advert
service is defined in services.js
- it reads adverts.json
:
motoAdsServices.factory('Advert', ['$resource', function($resource) { return $resource('data/:id.json', {}, { query: { method: 'GET', params: { id: 'adverts' }, isArray: true } }); }]);
Add advert - validation and currency directive
We define the adding advert form in
addAdverts.html
:
AddAdvertController
in controllers.js
:
motoAdsApp.controller('AddAdvertController', ['$scope', 'Brand', 'Country', 'Advert', function($scope, Brand, Country) { $scope.brands = Brand.query(); $scope.countries = Country.query(); $scope.emptyAdvert = { brand: null, model: null, year: 2010, price: 10000, country: null, region: null }; $scope.add = function() { alert('User added!'); // TODO: Store it! $scope.reset(); }; $scope.reset = function() { $scope.newAdvert = angular.copy($scope.emptyAdvert); if ($scope.advertForm) { // TODO Uncomment in angular 1.1.1 or higher //$scope.advertForm.$setPristne(); } }; $scope.isUnchanged = function() { return angular.equals($scope.newAdvert, $scope.emptyAdvert); }; $scope.reset(); }]);Last thing is custom directive
ma-currency
used in addAdvert.html
: