<!DOCTYPE html> <html> <head> <script src="angular.js"></script> <script src="script.js"></script> </head> <body ng-app="mainModule"> <div ng-controller="mainController"> <h3>1. Simple filter</h3> <strong>Original data:</strong> {{stringData}}<br /> <strong>Filtered data:</strong> {{stringData | uppercase}}<br /> <br /> <h3>2. Chained filters</h3> <strong>Original data:</strong> {{stringData}}<br /> <strong>Filtered data:</strong> {{stringData | lowercase | limitTo:7}}<br /> <br /> <h3>3. Filter in JavaScript</h3> <strong>Original data:</strong> {{dateData}}<br /> <strong>Filtered data (HTML):</strong> {{dateData | date:"dd MMM yyyy"}}<br /> <strong>Filtered data (JavaScript - alternative 1):</strong> {{formatDate1(dateData, "dd MMM yyyy")}}<br /> <strong>Filtered data (JavaScript - alternative 2):</strong> {{formatDate2(dateData, "dd MMM yyyy")}}<br /> <br /> <h3>4. Custom filter</h3> <label><strong>Original data:</strong> <input type="text" ng-model="numberData" /></label><br /> <strong>Filtered data (default):</strong> {{numberData | customCurrency}}<br /> <strong>Filtered data (with parameters):</strong> {{numberData | customCurrency:"&euro;":",":".":2}}<br /> </div> </body> </html>
angular.module("mainModule", []) .controller("mainController", function ($scope, $filter, dateFilter) { // Initialization $scope.stringData = "Example string"; $scope.dateData = new Date(); $scope.numberData = 1350620.547; // Utility functions $scope.formatDate1 = function (date, format) { return $filter("date")(date, format); }; $scope.formatDate2 = function (date, format) { return dateFilter(date, format); }; }) .filter("customCurrency", function (numberFilter) { function isNumeric(value) { return (!isNaN(parseFloat(value)) && isFinite(value)); } return function (inputNumber, currencySymbol, decimalSeparator, thousandsSeparator, decimalDigits) { if (isNumeric(inputNumber)) { // Default values for the optional arguments currencySymbol = (typeof currencySymbol === "undefined") ? "$" : currencySymbol; decimalSeparator = (typeof decimalSeparator === "undefined") ? "." : decimalSeparator; thousandsSeparator = (typeof thousandsSeparator === "undefined") ? "," : thousandsSeparator; decimalDigits = (typeof decimalDigits === "undefined" || !isNumeric(decimalDigits)) ? 2 : decimalDigits; if (decimalDigits < 0) decimalDigits = 0; // Format the input number through the number filter // The resulting number will have "," as a thousands separator // and "." as a decimal separator. var formattedNumber = numberFilter(inputNumber, decimalDigits); // Extract the integral and the decimal parts var numberParts = formattedNumber.split("."); // Replace the "," symbol in the integral part // with the specified thousands separator. numberParts[0] = numberParts[0].split(",").join(thousandsSeparator); // Compose the final result var result = currencySymbol + numberParts[0]; if (numberParts.length == 2) { result += decimalSeparator + numberParts[1]; } return result; } else { return inputNumber; } }; });



AngularJS lets us format data or manipulate array collections through filters. In this example we'll take a look at the formatting filters.

To specify a filter in the HTML template, we can use the common data biding notation {{expression}} and add a pipe (|) after the expression to format its result, so we'll have something like this {{expression | filter}}. If the filter accepts some parameters, we can specify them in sequence with the colon (:) character {{expression | filter:param1:param2}}.

In point 1 we see a simple filter. It's the built-in uppercase formatting filter that formats the content of stringData turning it to uppercase.

In point 2 we show that we can chain multiple filters together. Each time a pipe character is encountered, the preceding result will be processed by the filter specified after the pipe. So, in the example, stringData is first turned to lowercase and then the limitTo filter trims the lowercase string. The limitTo filter accepts a parameter that in this case says that we want to keep the first 7 characters of the string.

If we prefer to apply our filter in JavaScript, point 3 shows how it can be done. We see that we can apply the date filter in three different ways, the first one with the usual syntax for the HTML template and the other two directly in JavaScript. Let's take a look at the two JavaScript filter functions. formatDate1 retrieves the date filter using the $filter variable. That variable is available for us using Dependency Injection and allows to retrieve any available filter. In the example we're saying: give me the date filter function and apply the date and format parameters to the function. formatDate2 is a different way to achieve the same result. We can retrieve the date filter through Dependecy Injection also specifying as a module function argument (the controller function in this case) the name of the filter with a Filter suffix. Here we've written dateFilter as a function argument because we want the filter named date. In formatDate2 then we simply apply to the dateFilter function the parameters that the filter needs (the date and a string representing the desired output format).

There might be cases where the built-in filters are not enough for us of course, but there's a solution. Point 4 shows how we can write a custom formatting filter. At the time of writing, the built-in currency filter is pretty useless since it has very limited options, so it's a good time to write our own custom currency formatting filter and we're going to call it customCurrency. We can register a custom filter with the module function named filter. The parameter of filter is a function that returns the actual filtering function. In this example we specify also the numberFilter argument because we want to retrieve the built-in number filter that is going to be useful in our formatting function. Our filter function accepts 5 parameters: the first one is the data that has to be formatted, while the others are easy to understand just reading their names. We've made all the parameters optional so at the beginning of the filter function we provide some default values in case the parameters are not specified in input. The description of the inner workings of the function is available in the comments inside the code. We also have an isNumeric utility function that helps us to check if a variable is actually a number or not. In the HTML template we can then use the customCurrency formatting filter with the default parameter values or specify our own separating them with the colon character.