Skip to content

Instantly share code, notes, and snippets.

@ahmadfaizalbh
Forked from bennadel/after-directive.htm
Last active August 29, 2015 14:19
Show Gist options
  • Save ahmadfaizalbh/788c022e1f3969353f14 to your computer and use it in GitHub Desktop.
Save ahmadfaizalbh/788c022e1f3969353f14 to your computer and use it in GitHub Desktop.
<!doctype html>
<html ng-app="Demo" ng-controller="AppController">
<head>
<meta charset="utf-8" />
<title>
My Approach To Building AngularJS Directives
</title>
<style type="text/css">
div.viewport {
border: 1px dashed #FF9999 ;
bottom: 10px ;
left: 9px ;
padding: 10px 10px 3px 10px ;
position: fixed ;
top: 113px ;
}
ul.friends {
list-style-type: none ;
margin: 0px 0px 0px 0px ;
padding: 0px 0px 0px 0px ;
width: 400px ;
}
ul.friends li {
border: 1px solid #CCCCCC ;
margin: 0px 0px 7px 0px ;
padding: 10px 10px 10px 10px ;
position: relative ;
}
ul.friends a {
color: #CCCCCC ;
right: 10px ;
position: absolute ;
}
ul.friends a:hover {
color: #CC0000 ;
}
div.teaser {
color: #999999 ;
font-style: italic ;
margin: 12px 0px 7px 0px ;
}
</style>
</head>
<body>
<h1>
My Approach To Building AngularJS Directives
</h1>
<!-- BEGIN: New Friend Form. -->
<form ng-submit="addFriend()">
<p>
<input type="text" ng-model="newFriendName" size="30" />
<input type="submit" value="Add Friend" />
</p>
</form>
<!-- END: New Friend Form. -->
<!-- BEGIN: Friend List. -->
<div bn-viewport class="viewport">
<ul class="friends">
<li ng-repeat="friend in visibleFriends">
{{ friend.name }}
<a ng-click="removeFriend( friend )">Remove</a>
</li>
</ul>
<div ng-show="hiddenFriends.length" class="teaser">
... and {{ hiddenFriends.length }} friend(s) not shown.
</div>
</div>
<!-- END: Friend List. -->
<!-- Load jQuery and AngularJS from the CDN. -->
<script
type="text/javascript"
src="//code.jquery.com/jquery-2.0.0.min.js">
</script>
<script
type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js">
</script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// Define the root-level controller for the application.
app.controller(
"AppController",
function( $scope ) {
// I am the model for new friends.
$scope.newFriendName = "";
// Start off with a small set of default friends.
$scope.friends = [
{
id: 1,
name: "Tricia"
}
];
// I am the collection of visible friends, based on
// the current collection and the capacity of the
// current interface.
$scope.visibleFriends = [];
// I am the collection of hidden friends, not shown
// because they exceed the capacity of the current
// interface.
$scope.hiddenFriends = [];
// I define the number of friends that should be
// visible in the current state of the interface.
var friendCapacity = 3;
// Divide the friends up into the hidden / visible
// breakdown based on the currently-hard-coded
// render capacity.
applyFriendCapacity();
// --
// PUBLIC METHODS.
// --
// I add a new friend to the collection.
$scope.addFriend = function() {
if ( ! $scope.newFriendName ) {
return;
}
$scope.friends.push({
id: ( new Date() ).getTime(),
name: $scope.newFriendName
});
$scope.newFriendName = "";
// Whenever the collection changes, we have to
// update the visible / hidden breakdown.
applyFriendCapacity();
};
// I remove the given friend from the collection.
$scope.removeFriend = function( friend ) {
var index = $scope.friends.indexOf( friend );
if ( index === -1 ) {
return;
}
$scope.friends.splice( index, 1 );
// Whenever the collection changes, we have to
// update the visible / hidden breakdown.
applyFriendCapacity();
};
// I set the capacity of the current interface.
$scope.setFriendCapacity = function( newCapacity ) {
friendCapacity = newCapacity;
// Apply the new capacity to the collections.
applyFriendCapacity();
};
// --
// PRIVATE METHODS.
// --
// I apply the current capacity to the friends to
// update the visible/hidden breakdown.
function applyFriendCapacity() {
// If the current interface capacity can hold
// of the current friends, simply funnel them all
// into the visible friends.
if ( friendCapacity >= $scope.friends.length ) {
$scope.visibleFriends = $scope.friends;
$scope.hiddenFriends = [];
// If we have more friends that the interface can
// hold, funnel the overflow into the hidden
// friends collection.
} else {
$scope.visibleFriends = $scope.friends.slice( 0, friendCapacity );
$scope.hiddenFriends = $scope.friends.slice( friendCapacity );
}
}
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I pipe the changes in window size into the parent controller.
app.directive(
"bnViewport",
function() {
// I link the DOM events to the current scope.
function link( $scope, element, attributes ) {
// I detect the UI interface capacity and tell the
// parent controller about the dynamic value.
function updateFriendCapacity() {
// For the sake of the demo, the height of
// the items and the teaser are hard-coded
// and are not calculated on the fly.
var itemHeight = 46;
var teaserHeight = 36;
// Get the inner height of the viewport.
var viewportHeight = element.height();
// Again, for the sake of the demo, we'll just
// say that the available viewport is always
// taking the "teaser" into account, even if
// it is not going to be rendered.
var availableHeight = ( viewportHeight - teaserHeight );
// Add back the amount of "margin collapse"
// height that will take place between the
// list and the teaser.
availableHeight += 5;
// Then, the capacity is simply the number of
// items that will fit in the available height.
var capacity = Math.floor( availableHeight / itemHeight );
// Let the parent controller know about the
// new capacity of the viewport interface.
$scope.setFriendCapacity( capacity );
}
// Update the capacity of the interface.
updateFriendCapacity();
// NOTE: Since we are in the link function
// execution, we do not need to call the $apply()
// method - we are already in the middle of a
// monitored lifecycle.
// When the window resizes, the viewport will also
// be resized and capacity of the interface may be
// changed.
$( window ).on(
"resize.bnViewport",
function( event ) {
$scope.$apply( updateFriendCapacity );
}
);
// When the scope is destroyed, be sure to unbind
// event handler can cause issues.
$scope.$on(
"$destroy",
function() {
$( window ).off( "resize.bnViewport" );
}
);
}
// Return the directive configuration.
return({
link: link,
restrict: "A"
});
}
);
</script>
</body>
</html>
<!doctype html>
<html ng-app="Demo" ng-controller="AppController">
<head>
<meta charset="utf-8" />
<title>
My Approach To Building AngularJS Directives
</title>
<style type="text/css">
div.viewport {
border: 1px dashed #FF9999 ;
left: 9px ;
padding: 10px 10px 3px 10px ;
position: fixed ;
top: 113px ;
}
ul.friends {
list-style-type: none ;
margin: 0px 0px 0px 0px ;
padding: 0px 0px 0px 0px ;
width: 400px ;
}
ul.friends li {
border: 1px solid #CCCCCC ;
margin: 0px 0px 7px 0px ;
padding: 10px 10px 10px 10px ;
position: relative ;
}
ul.friends a {
color: #CCCCCC ;
right: 10px ;
position: absolute ;
}
ul.friends a:hover {
color: #CC0000 ;
}
div.teaser {
color: #999999 ;
font-style: italic ;
margin: 12px 0px 7px 0px ;
}
</style>
</head>
<body>
<h1>
My Approach To Building AngularJS Directives
</h1>
<!-- BEGIN: New Friend Form. -->
<form ng-submit="addFriend()">
<p>
<input type="text" ng-model="newFriendName" size="30" />
<input type="submit" value="Add Friend" />
</p>
</form>
<!-- END: New Friend Form. -->
<!-- BEGIN: Friend List. -->
<div class="viewport">
<ul class="friends">
<li ng-repeat="friend in visibleFriends">
{{ friend.name }}
<a ng-click="removeFriend( friend )">Remove</a>
</li>
</ul>
<div ng-show="hiddenFriends.length" class="teaser">
... and {{ hiddenFriends.length }} friend(s) not shown.
</div>
</div>
<!-- END: Friend List. -->
<!-- Load jQuery and AngularJS from the CDN. -->
<script
type="text/javascript"
src="//code.jquery.com/jquery-2.0.0.min.js">
</script>
<script
type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js">
</script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// Define the root-level controller for the application.
app.controller(
"AppController",
function( $scope ) {
// I am the model for new friends.
$scope.newFriendName = "";
// Start off with a small set of default friends.
$scope.friends = [
{
id: 1,
name: "Tricia"
}
];
// I am the collection of visible friends, based on
// the current collection and the capacity of the
// current interface.
$scope.visibleFriends = [];
// I am the collection of hidden friends, not shown
// because they exceed the capacity of the current
// interface.
$scope.hiddenFriends = [];
// I define the number of friends that should be
// visible in the current state of the interface.
var friendCapacity = 3;
// Divide the friends up into the hidden / visible
// breakdown based on the currently-hard-coded
// render capacity.
applyFriendCapacity();
// --
// PUBLIC METHODS.
// --
// I add a new friend to the collection.
$scope.addFriend = function() {
if ( ! $scope.newFriendName ) {
return;
}
$scope.friends.push({
id: ( new Date() ).getTime(),
name: $scope.newFriendName
});
$scope.newFriendName = "";
// Whenever the collection changes, we have to
// update the visible / hidden breakdown.
applyFriendCapacity();
};
// I remove the given friend from the collection.
$scope.removeFriend = function( friend ) {
var index = $scope.friends.indexOf( friend );
if ( index === -1 ) {
return;
}
$scope.friends.splice( index, 1 );
// Whenever the collection changes, we have to
// update the visible / hidden breakdown.
applyFriendCapacity();
};
// I set the capacity of the current interface.
$scope.setFriendCapacity = function( newCapacity ) {
friendCapacity = newCapacity;
// Apply the new capacity to the collections.
applyFriendCapacity();
};
// --
// PRIVATE METHODS.
// --
// I apply the current capacity to the friends to
// update the visible/hidden breakdown.
function applyFriendCapacity() {
// If the current interface capacity can hold
// of the current friends, simply funnel them all
// into the visible friends.
if ( friendCapacity >= $scope.friends.length ) {
$scope.visibleFriends = $scope.friends;
$scope.hiddenFriends = [];
// If we have more friends that the interface can
// hold, funnel the overflow into the hidden
// friends collection.
} else {
$scope.visibleFriends = $scope.friends.slice( 0, friendCapacity );
$scope.hiddenFriends = $scope.friends.slice( friendCapacity );
}
}
}
);
</script>
</body>
</html>
<!doctype html>
<html ng-app="Demo" ng-controller="AppController">
<head>
<meta charset="utf-8" />
<title>
My Approach To Building AngularJS Directives
</title>
<style type="text/css">
ul.friends {
list-style-type: none ;
margin: 0px 0px 0px 0px ;
padding: 0px 0px 0px 0px ;
width: 400px ;
}
ul.friends li {
border: 1px solid #CCCCCC ;
margin: 0px 0px 7px 0px ;
padding: 10px 10px 10px 10px ;
position: relative ;
}
ul.friends a {
color: #CCCCCC ;
right: 10px ;
position: absolute ;
}
ul.friends a:hover {
color: #CC0000 ;
}
</style>
</head>
<body>
<h1>
My Approach To Building AngularJS Directives
</h1>
<!-- BEGIN: New Friend Form. -->
<form ng-submit="addFriend()">
<p>
<input type="text" ng-model="newFriendName" size="30" />
<input type="submit" value="Add Friend" />
</p>
</form>
<!-- END: New Friend Form. -->
<!-- BEGIN: Friend List. -->
<ul class="friends">
<li ng-repeat="friend in friends">
{{ friend.name }}
<a ng-click="removeFriend( friend )">Remove</a>
</li>
</ul>
<!-- END: Friend List. -->
<!-- Load jQuery and AngularJS from the CDN. -->
<script
type="text/javascript"
src="//code.jquery.com/jquery-2.0.0.min.js">
</script>
<script
type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js">
</script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// Define the root-level controller for the application.
app.controller(
"AppController",
function( $scope ) {
// I am the model for new friends.
$scope.newFriendName = "";
// Start off with a small set of default friends.
$scope.friends = [
{
id: 1,
name: "Tricia"
}
];
// --
// PUBLIC METHODS.
// --
// I add a new friend to the collection.
$scope.addFriend = function() {
if ( ! $scope.newFriendName ) {
return;
}
$scope.friends.push({
id: ( new Date() ).getTime(),
name: $scope.newFriendName
});
$scope.newFriendName = "";
};
// I remove the given friend from the collection.
$scope.removeFriend = function( friend ) {
var index = $scope.friends.indexOf( friend );
if ( index === -1 ) {
return;
}
$scope.friends.splice( index, 1 );
};
}
);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment