AngularJS Cookbook () => a couple of recipes;

Wednesday, March 15, 2017

AngularJS enables you to extend HTML vocabulary. Develop awesome Single Page Applications, quicker, more readable and expressive.

Create Awesome Single Page Applications!

Building Blocks of an Angular Application ( (ng) => harder, better, faster, stronger;):

  • Template: HTML with additional markup.
  • Directive: extend HTML with custom attributes and elements.
  • Model: the data shown to the user in a view and with which the user interacts.
  • Scope: context where the model is stored so that controllers, directives and expressions can access it.
  • Expressions: access variables and functions from the scope.
  • Compiler: parses the template and instantiates directives and expressions.
  • Filter: formats the value of an expression for display to the user.
  • View: what the user sees (the DOM).
  • Data Binding: sync data between the model and the view.
  • Controller: the business logic behind the views.
  • Dependency Injection: creates and wires objects and functions.
  • Injector: dependency injection container.
  • Module: a container for different parts of an app including controllers, services, filters, directives which configures the Injector.
  • Service: reusable business logic independent of views.



attitude, facts and mission ...

we are fearless, ruthless and honest, the goal is progress. we are constantly focused on our goal, produce quality working software as fast as possible. we are open source. we are the angular open source crisis team.

joy




simple element directive, templateurl's template is added to templatecache using ng-template

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <script type="text/ng-template" id="my-template.html"> <div ng-repeat="num in [0,1,2,3,4,5,6,7,8,9]"> {{num + 1}}</div> </script> <my-directive></my-directive> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('myDirective', function() { return { restrict: 'E', templateUrl: 'my-template.html' }; }); </script> </body> </html>


element directive: link function defines how directive instance will interact with DOM it is attached to, link function has three parameters by default: the directives scope, the relevant DOM element, and the element's attributes as key-value pairs

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <element-directive some-attr="MyValue"></element-directive> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('elementDirective', ['$log', function($log) { return { restrict: 'E', template: '<p>The element directives template</p>', link: function(scope, el, attrs) { $log.log(el.html()); $log.log(attrs.someAttr); } }; }]); </script> </body> </html>


to replace the directive tag entirely with the content, set the replace option to true

angular.module('myApp', []).directive('elementDirective', ['$log', function($log) { return { restrict: 'E', replace: true, template: '<p>The element directives template</p>', link: function(scope, el, attrs) { $log.log(el.html()); $log.log(attrs.someAttr); } }; }]);


attribute directive: can be added as stand alone attributes, unlimited amount, attribute directives attached to same HTML element are able to communicate with each other

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <div attribute-directive="AValue" some-attr="MyValue"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('attributeDirective', ['$log', function($log) { return { restrict: 'A', template: '<p>The attribute directives template</p>', link: function(scope, el, attrs) { $log.log(el.html()); $log.log(attrs.attributeDirective); $log.log(attrs.someAttr); } }; }]); </script> </body> </html>


class directive: not that different from attribute directive, multiple directive assignments, unrestricted local variable access, local directive communication

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <div class="class-directive: CValue; normal-class" some-attr="MyValue"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('classDirective', ['$log', function($log) { return { restrict: 'C', template: '<p>The class directives template</p>', link: function(scope, el, attrs) { $log.log(el.html()); $log.log(el.hasClass('normal-class')); $log.log(attrs.classDirective); $log.log(attrs.someAttr); } }; }]); </script> </body> </html>


comment directives: the runt of the group, infrequently required, useful to know that they are available

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <!-- directive: comment-directive value1 value2 value3 valueFunction --> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('commentDirective', ['$log', function($log) { return { restrict: 'M', replace: true, template: '<p>The comment directives template</p>', link: function(scope, el, attrs) { $log.log(el.html()); $log.log(attrs.commentDirective); } }; }]); </script> </body> </html>


manipulate the DOM with attribute directive, always modify the DOM in a directive

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <button counter>Click Me</button> <button counter increment="8">Click Me</button> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('counter', [ function() { return { restrict: 'A', link: function(scope, el, attrs) { let value = 0; let increment = parseInt(attrs.increment || 1); el.bind('click', () => { el.html(value += increment); }); } }; }]); </script> </body> </html>


directives linking: bulk of heavy lifting done inside directive's link function, this function is returned from preceding compile function, has ability to manipulate DOM in and around it

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <div vector-text buffer="300"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('vectorText', ['$document', function($document) { return { template: '<span>{{ heading }}</span>', link: function(scope, el, attrs) { el.css({ 'float': 'left', 'padding': attrs.buffer+'px' }); scope.heading = ''; $document.on('mousemove', (event) => { //mousemove event does not start $digest //scope.$apply does this manually scope.$apply(function () { if (event.pageY< 300) { scope.heading = 'N'; } else { scope.heading = 'S'; } if (event.pageX < 300) { scope.heading += 'W'; } else { scope.heading += 'E'; } }); }); } }; }]); </script> </body> </html>


isolate scope: if directive is not instructed to provide scope for itself, it will inherit parent scope, in the case this is not desirable behavior, create an isolate scope for the directive and inside isolate scope you can define a whitelist of parent scope elements the directive will consume, pass read-only value to the directive use @ inside isolate scope

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <div>Outer: {{outerVal}}</div> <div iso myattr="{{outerVal}}"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', ['$log', '$scope', function($log, $scope) { $scope.outerVal = 'iwannadata'; }]).directive('iso', function() { return { scope: { innerVal: '@myattr' }, template: 'Inner: {{ innerVal }}', }; }); </script> </body> </html>


use the = definition for full data-binding, the child directive scope examines parent controller scope and the parent outerVal attribute is bound inside the child scope, aliased as innerVal attribute

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <div>Outer: {{outerVal}}</div> <div iso myattr="outerVal"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', ['$log', '$scope', function($log, $scope) { $scope.outerVal = 'iwannadata'; }]).directive('iso', function() { return { scope: { innerVal: '=myattr' }, template: 'Inner: {{ innerVal }}', }; }); </script> </body> </html>


methods can also be pulled down from parent scope for use in the directive, same way model variable can be boundto child scope, alias methods that are defined in parent scope to be invoked from child scope but are still in parent scope context, do this with & definition

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <div>Outer: {{outerVal}}</div> <div iso myattr="func()"></div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', ['$log', '$scope', function($log, $scope) { $scope.outerVal = 'iwannadata'; $scope.func = () => { $log.log('func invoked!'); }; }]).directive('iso', function() { return { scope: { innerVal: '&myattr' }, link: function(scope) { scope.innerVal(); } }; }); </script> </body> </html>


interaction between nested directives, channels of communication between directive siblings (within same HTML element) or parents in same DOM ancestry without having to rely on events, inter-directive communication is accomplished with require attribute

!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <div parent-directive> <div child-directive sibling-directive></div> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('parentDirective', ['$log', function($log) { return { controller: function() { this.identify = () => { $log.log('Parent!'); }; } }; }]).directive('siblingDirective', ['$log', function($log) { return { controller: function() { this.identify = () => { $log.log('Sibling!'); }; } }; }]).directive('childDirective', ['$log', function($log) { return { require: ['^parentDirective', '^siblingDirective'], link: function(scope, el, attrs, ctrls) { ctrls[0].identify(); ctrls[1].identify(); } }; }]); </script> </body> </html>


optional nested directive controllers, a ? prefixed to require array element denotes an optional controller directive

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body> <div parent-directive> <div child-directive sibling-directive></div> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).directive('parentDirective', ['$log', function($log) { return { controller: function() { this.identify = () => { $log.log('Parent!'); }; } }; }]).directive('siblingDirective', ['$log', function($log) { return { controller: function() { this.identify = () => { $log.log('Sibling!'); }; } }; }]).directive('childDirective', ['$log', function($log) { return { require: ['^parentDirective', '^siblingDirective', '^?missingDirective'], link: function(scope, el, attrs, ctrls) { ctrls[0].identify(); ctrls[1].identify(); $log.log(ctrls[2]); } }; }]); </script> </body> </html>


directive scope inheritance, if not specified otherwise, directive inherits scope of whatever scope it exists inside, link function is last to modify the scope and it overwrites the original values set up in the parent controller

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <my-directive> <p>HTML template</p> <p>Scope from {{origin}}</p> <p>Overwritten? {{overwrite}}</p> </my-directive> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.origin = 'parent controller'; $scope.overwrite = false; }]).directive('myDirective', function() { return { restrict: 'E', link: function(scope) { scope.origin = 'link function'; scope.overwrite = !!scope.origin; } }; }); </script> </body> </html>


directive templating

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <my-directive> contents of mydirective </my-directive> <script type="text/ng-template" id="my-directive.html"> <div> <p>directive template</p> <p>scope from {{origin}}</p> <p>overwritten? {{overwrite}}</p> </div> </script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.origin = 'parent controller'; $scope.overwrite = false; }]).directive('myDirective', function() { return { restrict: 'E', replace: true, templateUrl: 'my-directive.html', link: function(scope) { scope.origin = 'link function'; scope.overwrite = !!scope.origin; } }; }); </script> </body> </html>


isolate scope, prevent inheritance and create blank slate scope, isolate scope is used

//in DDO set scope option scope: {}


directive transclusion, in the directive's template the location og ng-transclude informs $compile that the directive's original HTML contents are to replace the contents of the specified element

<head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <my-directive> <p>HTML template</p> <p>scope from {{origin}}</p> <p>overwritten? {{overwrite}}</p> </my-directive> <script type="text/ng-template" id="my-directive.html"> <ng-transclude></ng-transclude> </script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.origin = 'parent controller'; $scope.overwrite = false; }]).directive('myDirective', function() { return { restrict: 'E', transclude: true, templateUrl: 'my-directive.html', scope: {}, link: function(scope) { scope.origin = 'link function'; scope.overwrite = !!scope.origin; } }; }); </script> </body> </html>


see the main reason to use transclusion more clearly, view modified my-directive.html, view the results side by side

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <my-directive> <p>HTML template</p> <p>scope from {{origin}}</p> <p>overwritten? {{overwrite}}</p> </my-directive> <script type="text/ng-template" id="my-directive.html"> <ng-transclude></ng-transclude> <hr> <p>Directive template</p> <p>scope from {{origin}}</p> <p>overwritten? {{overwrite}}</p> </script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.origin = 'parent controller'; $scope.overwrite = false; }]).directive('myDirective', function() { return { restrict: 'E', transclude: true, templateUrl: 'my-directive.html', scope: {}, link: function(scope) { scope.origin = 'link function'; scope.overwrite = !!scope.origin; } }; }); </script> </body> </html>


recursive directive

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <my-tree value="data"></my-tree> <script type="text/ng-template" id="recursive.html"> <span>{{ value.text }}</span> <button ng-click="deleteSubtree()">delete</button> <ul ng-if="isParent" style="margin-left:30px"> <li ng-repeat="item in value.items"> <my-tree value="item" parent-data="value.items"></my-tree> </li> </ul> </script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.data = { text: 'Operating Systems', items: [ { text: 'Debian', items: [ { text: 'Android' }, { text: 'Ubuntu', items: [ { text: 'Kubuntu', items: [ { text: 'Zorin OS' }, { text: 'Linux Mint' }, { text: 'Trisquel' } ] }, { text: 'Elementary OS' } ] } ] }, { text: 'Google Chrome OS' }, { text: 'Mac OS X' }, { text: 'Windows' //trash this! } ] }; }]).directive('myTree', function($compile, $templateCache) { return { restrict: 'E', scope: { value: '=', parentData: '=' }, link: function(scope, el, attrs) { scope.isParent = angular.isArray(scope.value.items); scope.deleteSubtree = () => { if (scope.parentData) { scope.parentData.splice(scope.parentData.indexOf(scope.value), 1); } scope.value = {}; } el.replaceWith($compile($templateCache.get('recursive.html'))(scope)); } }; }); </script> </body> </html>


filters: uppercase and lowercase filter

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <h3>Uppercase Filter</h3> <p>{{ data.text | uppercase}}</p> <p>{{ data.numbers | uppercase}}</p> <p>{{ data.specialChars | uppercase}}</p> <p>{{ data.whiteSpace | uppercase}}</p> <hr> <h3>Lowercase Filter</h3> <p>{{ data.text | lowercase}}</p> <p>{{ data.numbers | lowercase}}</p> <p>{{ data.specialChars | lowercase}}</p> <p>{{ data.whiteSpace | lowercase}}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.data = { text: 'a SMALL heart for the BIG web, animated ascii heart POLYMER element <ascii-heart>foryou</ascii-heart>', numbers: '0123456789', specialChars: '!@#$%^&*()', whiteSpace: ' ' }; }]); </script> </body> </html>


number filter

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <p>{{ data.bigNumber | number}}</p> <p>{{ data.number | number}}</p> <p>{{ data.smallNumber | number}}</p> <p>{{ data.tinyNumber | number}}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.data = { bigNumber: 1000000, number: 1.0, smallNumber: 0.9999, tinyNumber: 0.001 }; }]); </script> </body> </html>


number filter takes a fractionsize argument which defines how many decimal places it will round to, defaulting to 3

<!doctype html> <html ng-app="myApp"> <head> <title>we honor angular</title> </head> <body ng-controller="MainCtrl"> <p>{{ data.bigNumber | number}}</p> <p>{{ data.number | number}}</p> <p>{{ data.smallNumber | number : 2}}</p> <p>{{ data.tinyNumber | number : 4}}</p> <p>{{ 012345.6789 | number : 2}}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MainCtrl', [ '$scope', function($scope) { $scope.data = { bigNumber: 1000000, number: 1.0, smallNumber: 0.9999, tinyNumber: 0.0000001 }; }]); </script> </body> </html>


curreny filter takes an optional argument, symbol

<!doctype html> <html ng-app> <head> <title>we honor angular</title> </head> <body> <p>{{ 1234.567 | currency}}</p> <p>{{ 0.03 | currency }}</p> <p>{{ 33717.18 | currency : '€' }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> </body> </html>


date filter

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <p>{{ data.unix * 1000 | date }}</p> <p>{{ data.iso | date }}</p> <p>{{ data.date | date }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.data = { unix: 1489527704, iso: '2017-03-14T21:35:24Z', date: new Date(2017, 2, 14, 21, 35, 24, 535) }; }]); </script> </body> </html>


date filter is heavily customizable

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <p>{{ data.unix * 1000 | date : "EEEE 'at' H:mma"}}</p> <p>{{ data.iso | date : "longDate" }}</p> <p>{{ data.date | date : "M/d H:m:s.sss" }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.data = { unix: 1489527704, iso: '2017-03-14T21:35:24Z', date: new Date(2017, 2, 14, 21, 35, 24, 535) }; }]); </script> </body> </html>


json filter for debugging purposes

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <pre>{{ user | json }}</pre> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.user = { id: 123, name: { first: 'Sierra', last: 'El Capitan' }, username: 'Ubunta', friendIds: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55], //properties prefixed with $$ are excluded $$no_show: 'Hide me!' }; }]); </script> </body> </html>


data filters outside the template, use filter functions via an injection of $filter

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <p>{{ value | number : 4 }}</p> <p>{{ filteredValue }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', '$filter', function($scope, $filter) { $scope.value = 1234.56789; $scope.filteredValue = $filter('number')($scope.value, 4); }]); </script> </body> </html>


using built-in search filters

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <input type="text" ng-model="search.value"> <p ng-repeat="user in users | filter : search.value">{{ user }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.users = [ 'Carmelia Lioness', 'Jane Fox', 'Sophie Labelle', 'Maria Rentier', 'Barbie Doll', 'Caroline Tuwas', 'Becky Dosomething' ]; }]); </script> </body> </html>


chain multiple filters together

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <input type="text" ng-model="search.value"> <p ng-repeat="user in users | filter : search.value | orderBy: 'name' | limitTo: 2">{{ user.name }}</p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.users = [ { name: 'Carmelia Lioness'}, { name: 'Jane Fox'}, { name: 'Sophie Labelle'}, { name: 'Maria Rentier'}, { name: 'Barbie Doll'}, { name: 'Caroline Tuwas'}, { name: 'Becky Dosomething'} ]; }]); </script> </body> </html>


creating custom data filters, a simple data filter

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> {{ myText | simpletruncate }} <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.myText = 'somebody may beat me, but they are going to have to bleed to do it.'; }]).filter('simpletruncate', function() { return function(text) { let truncated = text.slice(0, 60); if (text.length > 60) { truncated += '...'; } return truncated; }; }); </script> </body> </html>


simple data filter enhanced

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> {{ myText | regextruncate: 60 : '***' }} <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.myText = 'somebody may beat me, but they are going to have to bleed to do it.'; }]).filter('regextruncate', function() { return function(text, limit, stoptext) { let regex = /\s/; if (!angular.isDefined(limit)) { limit = 100; } if (!angular.isDefined(stoptext)) { stoptext = '...'; } limit = Math.min(limit, text.length); for (let i = 0; i < limit; i++) { if (regex.exec(text[limit - i]) && !regex.exec(text[(limit - i) - 1])) { limit = limit - i; break; } } let truncated = text.slice(0, limit); if (text.length > limit) { truncated += stoptext; } return truncated; }; }); </script> </body> </html>


custom search filter, to compare against specific attributes of enumerable collection, set search object to have correlating attributes that should be matched against collection attributes

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <input ng-model="search.author"> <p ng-repeat="quote in quotes | filter:search"> {{quote.author}} : <strong>{{quote.text}}</strong> </p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.quotes = [ { author: 'Linus Torvalds', text: 'Microsoft isn\'t evil, they just make really crappy operating systems.' }, { author: 'Linus Torvalds', text: 'I think fundamentally, open source does tend to be more stable software. It\'s the right way to do things.' }, { author: 'Steve Jobs', text: 'Good artists copy; great artists steal.' }, { author: 'Steve Jobs', text: 'Your time is limited ... have the courage to follow your heart and intuition.' } ]; }]); </script> </body> </html>


filter with special property name that matches against any property, by default $

<!doctype html> <html ng-app="myApp"> <head> <title>a small heart for the big web</title> </head> <body ng-controller="MyCtrl"> <input ng-model="search.$"> <input ng-model="search.number"> <p ng-repeat="quote in quotes | filter:search"> {{quote.author}} : <strong>{{quote.text}}</strong> </p> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script> <script> angular.module('myApp', []).controller('MyCtrl', ['$scope', function($scope) { $scope.quotes = [ { author: 'Linus Torvalds', text: 'Microsoft isn\'t evil, they just make really crappy operating systems.', number: 1 }, { author: 'Linus Torvalds', text: 'I think fundamentally, open source does tend to be more stable software. It\'s the right way to do things.', number: 2 }, { author: 'Steve Jobs', text: 'Good artists copy; great artists steal.', number: 3 }, { author: 'Steve Jobs', text: 'Your time is limited ... have the courage to follow your heart and intuition.', number: 4 } ]; }]); </script> </body> </html>


Default Success Warning Important Info Inverse
B S W I ? O