-
-
Save edm00se/369294c9a2fe54e8c1ec to your computer and use it in GitHub Desktop.
Supporting code to the blog post of Building a Front-End: An App with AngularJS and HTTPServlet. src: http://edm00se.io/xpages-servlets/-building-a-front-end-pt2-an-app-with-angular/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// a self-invoking, anonymouse function to keep application code variables scoped anonymously | |
(function(){ | |
//defines the AngularJS app as a module | |
angular.module('houseApp', ['ui.router']) //'ngAnimate' | |
//ui-router config | |
.config( | |
function($stateProvider, $urlRouterProvider){ | |
$urlRouterProvider.otherwise('/houses'); | |
$stateProvider | |
.state('houses', { | |
url: '/houses', | |
templateUrl: 'partials/houseList.html', | |
controller: 'HouseListCtrl' | |
}) | |
.state('houses.item', { | |
url: '/:item', | |
templateUrl: 'partials/house.html', | |
controller: 'OneHouseCtrl' | |
}); | |
}) | |
// ... services/factories, controllers, filters, directives | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//...config,factories... | |
/* | |
* Controllers | |
*/ | |
//navigation controller | |
.controller('NavCtrl', function($scope, $location){ | |
$scope.isActive = function(route) { | |
return route === $location.path(); | |
} | |
}) | |
//provies the controller to the app, which handles the interaction of data (model) with the view (a la MVC) | |
.controller('HouseListCtrl', function($scope, $state, $http, $filter, houseCollectionFactory) { | |
//defines filter/search/etc. vars | |
$scope.pageQty = 5; //detectPhone() ? 10 : 30; | |
$scope.curPage = 0; | |
//calculates the number of results | |
$scope.numberOfPages = function() { | |
return Math.ceil($scope.housesOfWesteros.length / $scope.pageQty) || 0; | |
} | |
//defines a boolean var | |
$scope.showSearch = false; | |
$scope.housesOfWesteros = []; | |
//the factory is returning the promise of the $http, so handle success/error here | |
houseCollectionFactory | |
.success( function(data, status, headers, config) { | |
$scope.housesOfWesteros = data; | |
//$scope.predicate = "JobNum"; | |
//$scope.reverse = false; | |
}).error( function(data, status, headers, config) { | |
$scope.housesOfWesteros = null; | |
console.log("data: " + data); | |
console.log("status: " + status); | |
console.log("headers: " + headers); | |
console.log("config: " + JSON.parse(config)); | |
}) | |
.then( function(){ | |
//angular.element('div.screenMask').css('visibility','hidden'); | |
}); | |
$scope.removeHouse = function(unid){ | |
$http( { | |
method : 'DELETE', | |
url : 'houses/'+unid | |
}) | |
.success( function(data, status, headers, config){ | |
console.log("successfully deleted house with id: "+unid); | |
}) | |
.error( function(data, status, headers, config){ | |
//might as well say something | |
console.log("poop"); | |
}) | |
.then( function(){ | |
$state.go('houses',{reload: true}); | |
}); | |
}; | |
}) | |
.controller('OneHouseCtrl', function($scope, $state, $stateParams, $http, houseFactory){ | |
// check for empty ID | |
var tmpItm = $stateParams.item; | |
console.log("unid: "+tmpItm); | |
var re = /^[0-9A-Za-z]{32}$/; | |
//var re = /\d/; | |
if( tmpItm == null || tmpItm == undefined || (!tmpItm || !tmpItm.trim()) || !re.test(tmpItm) ){ | |
$state.go('houses'); | |
} | |
$scope.editForm = false; | |
$scope.canEditForm = false; | |
$scope.myHouse = {}; | |
var fieldNames = []; | |
houseFactory($stateParams.item) | |
.success(function(data, status, headers, config) { | |
$scope.myHouse = data; | |
$scope.canEditForm = true; | |
angular.forEach($scope.myHouse,function(value,key){ | |
if( key!="unid" ){ | |
fieldNames.push(key); | |
} | |
}); | |
}) | |
.error(function(data, status, headers, config) { | |
console.log("status: "+status); | |
console.log("data: "+data); | |
console.log("headers: "+headers); | |
console.log("config: "+JSON.parse(config)); | |
}); | |
$scope.setFormEditable = function() { | |
if( $scope.canEditForm == true ){ | |
$scope.editForm = true; | |
} | |
} | |
$scope.clearCancelForm = function() { | |
$state.go('houses'); | |
} | |
$scope.saveHouseForm = function(){ | |
var tmpOb = { "unid": $scope.myHouse.unid }; | |
//console.log("checking field names: "+fieldNames.toString()); | |
angular.forEach(fieldNames, function(fldNm){ | |
if( $scope.houseForm[fldNm].$dirty === true ){ | |
var tmpVal = $scope.myHouse[fldNm]; | |
//console.log("updated field: "+fldNm+" with value: "+tmpVal); | |
tmpOb[fldNm] = tmpVal; | |
} | |
}); | |
$http( { | |
method : 'PUT', | |
url : 'houses/'+$scope.myHouse.unid, | |
data: JSON.stringify(tmpOb) | |
}) | |
.success( function(data, status, headers, config){ | |
console.log("successfully updated house with unid: "+$scope.myHouse.unid); | |
}) | |
.error( function(data, status, headers, config){ | |
//might as well say something | |
console.log("poop"); | |
}) | |
.then( function(){ | |
$state.go('houses',{reload: true}); | |
}); | |
//console.log("Simulated PUT complete with object to send: "+JSON.stringify(tmpOb)); | |
} | |
}) | |
//...filters,directives... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//...config,factories,controllers,filters | |
/* | |
* Directives | |
*/ | |
//This directive allows us to pass a function in on an enter key to do what we want. | |
.directive('ngEnter', function () { | |
return function (scope, element, attrs) { | |
element.bind("keydown keypress", function (event) { | |
if(event.which === 13) { | |
scope.$apply(function (){ | |
scope.$eval(attrs.ngEnter); | |
}); | |
event.preventDefault(); | |
} | |
}); | |
}; | |
}) | |
/** | |
* A generic confirmation for risky actions. | |
* Usage: Add attributes: ng-really-message="Are you sure"? ng-really-click="takeAction()" function | |
*/ | |
.directive('ngReallyClick', [function() { | |
return { | |
restrict: 'A', | |
link: function(scope, element, attrs) { | |
element.bind('click', function() { | |
var message = attrs.ngReallyMessage; | |
if (message && confirm(message)) { | |
scope.$apply(attrs.ngReallyClick); | |
} | |
}); | |
} | |
} | |
}]); | |
//...nothing, just close the parenthesis to make the JS object complete then invoke with another set of paren |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//...config... | |
/* | |
* Factories | |
*/ | |
//defines the $HTTP factory, one of the 3 service types | |
.factory('houseCollectionFactory', [ '$http', function($http) { | |
return $http( { | |
method : 'GET', | |
url : 'houses' | |
}); | |
} ]) | |
.factory('houseFactory', [ '$http', function($http){ | |
return function(id){ | |
return $http( { | |
method : 'GET', | |
url : 'houses/'+id | |
}); | |
} | |
}]) | |
//...controllers,filters,directives... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//...config,factories,controllers... | |
/* | |
* Filters | |
*/ | |
// we already use the limitTo filter built-in to AngularJS, | |
// this is a custom filter for startFrom | |
.filter('startFrom', function() { | |
return function(input, start) { | |
start = +start; //parse to int | |
return input.slice(start); | |
} | |
}) | |
//...directives... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- ...head contents... --> | |
<!-- defining where to inject our app definition, using the body tag --> | |
<body ng-app="houseApp"> | |
<div class="navbar navbar-default navbar-fixed-top" role="navigation"> | |
<!-- ...navbar contents... --> | |
</div> | |
<!-- the magic! --> | |
<div ui-view></div> | |
<!-- CDN driven resources for Bootstrap and AngularJS JS resource files --> | |
<script type="text/javascript" src="js/houseApp.js"></script> | |
</body> | |
<!-- ... --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="panel panel-default"> | |
<div class="panel-heading"> | |
<h3 class="panel-title">House Details</h3> | |
</div> | |
<div class="panel-body"> | |
<form name="houseForm"> | |
<div class="form-group"> | |
<label | |
for="houseName"> | |
Name</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseName" | |
name="name" | |
ng-model="myHouse.name" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseDescription"> | |
Description</label> | |
<textarea | |
class="form-control" | |
id="houseDescription" | |
name="description" | |
ng-model="myHouse.description" | |
rows="3" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="coatOfArms"> | |
Coat of Arms</label> | |
<input | |
type="text" | |
class="form-control" | |
id="coatOfArms" | |
name="coatOfArms" | |
ng-model="myHouse.coatOfArms" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseWords"> | |
Words</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseWords" | |
name="words" | |
ng-model="myHouse.words" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseSeat"> | |
Seat</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseSeat" | |
name="seat" | |
ng-model="myHouse.seat" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseCurrentLord"> | |
Current Lord</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseCurrentLord" | |
name="currentLord" | |
ng-model="myHouse.currentLord" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseRegion"> | |
Region</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseRegion" | |
name="region" | |
ng-model="myHouse.region" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseTitle"> | |
Title</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseTitle" | |
name="title" | |
ng-model="myHouse.title" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseHeir"> | |
Heir</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseHeir" | |
name="heir" | |
ng-model="myHouse.heir" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="form-group"> | |
<label | |
for="houseOverlord"> | |
Overlord</label> | |
<input | |
type="text" | |
class="form-control" | |
id="houseOverlord" | |
name="overlord" | |
ng-model="myHouse.overlord" | |
ng-disabled="!editForm" /> | |
</div> | |
<div class="btn-list pull-right"> | |
<button | |
class="btn-default btn" | |
type="button" id="buttonCancelGotHouse" | |
ng-really-message="Are you sure?" | |
ng-really-click="clearCancelForm()"> | |
<i class="fa fa-lg fa-pencil"></i> Cancel</button> | |
<button | |
class="btn-success btn" | |
type="button" id="buttonSaveGotHouse" | |
ng-show="editForm" | |
ng-click="saveHouseForm()"> | |
<i class="fa fa-lg fa-save"></i> Save</button> | |
<button | |
class="btn-primary btn" | |
type="button" id="buttonEditGotHouse" | |
ng-disabled="!canEditForm" | |
ng-show="!editForm" | |
ng-click="setFormEditable()"> | |
<i class="fa fa-lg fa-pencil"></i> Edit</button> | |
</div> | |
</form> | |
</div> | |
<!-- <div class="panel-footer col-xs-12"></div> --> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="uiContainer" class="container"> | |
<div class="row"> | |
<div class="col-md-4"> | |
<div class="panel panel-default"> | |
<div class="panel-heading"> | |
<h3 class="panel-title">Houses of the Seven Kingdoms of Westeros</h3> | |
</div> | |
<ul class="list-group list-group-striped"> | |
<li class="list-group-item" | |
ng-repeat="house in housesOfWesteros | startFrom : curPage*pageQty | limitTo:pageQty"> | |
<a ng-href="#/houses/{{ house.unid }}" title="{{ house.unid }}">{{house.name}}</a> | |
<a href="#" | |
class="btn btn-danger pull-right" | |
ng-really-message="Are you sure you want to delete this house from Westeros?" | |
ng-really-click="removeHouse(house.unid)"><i class="fa fa-lg fa-trash-o"></i></a> | |
<br />{{house.words}} | |
</li> | |
</ul> | |
<div class="panel-footer col-xs-12"> | |
<nav> | |
<ul class="pager"> | |
<li class="previous" ng-class="{'disabled': curPage == 0}"> | |
<a ng-click="curPage = curPage - 1" href=""><span aria-hidden="true">←</span> Previous</a> | |
</li> | |
<span ng-bind="(curPage+1) + '/' + numberOfPages()"></span> | |
<li class="next" ng-class="{'disabled': curPage >= housesOfWesteros.length/pageQty-1}"> | |
<a ng-click="curPage = curPage + 1" href="">Next <span aria-hidden="true">→</span></a> | |
</li> | |
</ul> | |
</nav> | |
</div> | |
</div> | |
</div> | |
<!-- single house content --> | |
<div ui-view class="col-md-6 col-md-offset-2"></div> | |
</div> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment