by David Loo | Nov 22, 2014 | AngularJS
Here are some basics on how to create your own Angular custom filters. Below I have created a controller with an array of numbers starting from 1 to 10 and I am going to write a custom filter for filtering even numbers and one for odd numbers.
app.controller('AppController', ['$scope', function($scope) {
$scope.numbers = [1,2,3,4,5,6,7,8,9,10];
}
]);
To filter even numbers only I created a filter called EvenNumbersOnly which is a function that takes an array of numbers and check each value to see they are even numbers:
app.filter('EvenNumbersOnly', [function() {
return function(numbers) {
var evenNumbers = [];
for (idx in numbers)
{
if ((numbers[idx] % 2) == 0)
{
evenNumbers.push(numbers[idx]);
}
}
return evenNumbers;
}
}
]);
For filtering odd numbers I have done the same thing except it only check for odd numbers 🙂
app.filter('OddNumbersOnly', [function(){
return function(numbers) {
var oddNumbers = [];
for (idx in numbers)
{
if ((numbers[idx] % 2) == 1)
{
oddNumbers.push(numbers[idx]);
}
}
return oddNumbers;
}
}
]);
So now we have our filters ready to be used I will create a html page that will display the original complete set of numbers in the first div element, then I display a set of even numbers using the EvenNumbersOnly filter in the second div element, and then I display a set of odd numbers using the OddNumbersOnly filter in the third div element. Please note that the filter must be used with a pipe after the value you want to filter with:
<html ng-app="app.demo">
<head>
<title>Learn AngularJS - Filters</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="AppController">
<div>
Numbers: {{ numbers }}
</div>
<div>
Even Numbers: {{ numbers | EvenNumbersOnly }}
</div>
<div>
Odd Nimbers: {{ numbers | OddNumbersOnly }}
</div>
</body>
</html>
Download Source Code
by David Loo | Nov 22, 2014 | AngularJS
To create a controller function that can be use with an element’s event attribute, you need to define a function with it’s implementation in it and then attached it to the $scope.
Below I have created a new Javascript file called app.js with a controller called AppController. In the $scope I have a property for storing text and one for attaching a function called onClick. When the onClick function is invoked, the message property will be set with a message ‘Hello, World!’:
var app = angular.module('app.demo', []);
// Controllers
app.controller('AppController', ['$scope', function($scope) {
$scope.message = '';
$scope.onClick = function() {
$scope.message = 'Hello, World!';
}
}
]);
Below I create a html page with body that uses the AppController controller, I have a input element that is a button type and I use ng-click to bind the function that I have create in the controller. I have created a div that will display the message property every time the button is clicked:
<html ng-app="app.demo">
<head>
<title>Learn AngularJS - Functions</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="AppController">
<input type="button" ng-click="onClick()" value="Click Here" />
<div><h1>{{message}}</h1></div>
</body>
</html>
Download Source Code
by David Loo | Nov 16, 2014 | AngularJS
To share data between controllers, first create a service that will hold your data.
var myApp = angular.module("app.demo", []);
myApp.factory("Data", function(){
return {
message: "Hello, World"
};
});
Then you inject the factory into each controller.
myApp.controller("AppController1", ["$scope", "Data", function($scope, Data) {
$scope.data = Data;
}]);
myApp.controller("AppController2", ["$scope", "Data", function($scope, Data) {
$scope.data = Data;
}]);
Then create a html page with the following markup. You can see below there is two controllers receiving the input value and each one is bind to the same factory called Data.
<html ng-app="app.demo">
<head>
<title>Learn AngularJS - Sharing Data Between Controllers</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
<script src="SharingDataDemo.js"></script>
</head>
<body>
<div ng-controller="AppController1">
<input type="text" ng-model="data.message" />
<div>{{data.message}}</div>
</div>
<div ng-controller="AppController2">
<input type="text" ng-model="data.message" />
<div>{{data.message}}</div>
</div>
</body>
</html>
This demo can be downloaded from my GitHub repository: https://github.com/csharpguy76/LearnAngularJS
by David Loo | Nov 16, 2014 | AngularJS
In AngularJS data binding is very straight forward, you need to assign a model in the ng-model attribute and on your page you can read the model from anywhere on the page either by expressions or ng-model from another element.
<html ng-app="app.demo">
<head>
<title>Learn AngularJS - Data Binding</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script>
<script src="AppController.js"></script>
</head>
<body ng-controller="AppController">
<input type="text" ng-model="message" />
<div>{{message}}</div>
</body>
</html>
Above is an example of an input element taking a message as a model and then display the message result with double curly braces. The message model comes from the controller’s $scope eg. $scope.message.
angular.module("app.demo",[])
.controller("AppController", ["$scope", function($scope){
$scope.message="default message";
}]);
You can download the original source code from GitHub: https://github.com/csharpguy76/LearnAngularJS
by David Loo | Nov 11, 2014 | C#
Joining two Lists using Lambdas expression is very simple, lets say we have a inventory of computer products and we have a bunch of purchase orders to process.
So what I am going to do to demonstrate this is to create a class called Product that will have a string property for storing the product’s name and a decimal property for storing the unit price and a property for the product’s id.
public class Product
{
public int Id {
get;
set;
}
public string Name {
get;
set;
}
public decimal UnitPrice {
get;
set;
}
}
Then I create a class called Order that will have a property for the order number as a string, product id as an integer and quantity as a decimal.
public class Order
{
public int ProductId {
get;
set;
}
public string Number {
get;
set;
}
public int Quantity {
get;
set;
}
}
So now I have my classes created I will create a List of products and orders with values. For the Join to work, both lists must have a common reference, and that reference is the Product’s Id.
List<Product> products = new List<Product> {
new Product { Id = 1, Name = "1TB SSD Drive", UnitPrice = 99 },
new Product { Id = 2, Name = "Keyboard", UnitPrice = 39.95M },
new Product { Id = 3, Name = "24 inch Monitor", UnitPrice = 124.99M }
};
As you can see below each order has a referece to a Product Id and a product can 0 to many orders.
List<Order> orders = new List<Order> {
new Order { Number = "A100", ProductId = 2, Quantity = 100 },
new Order { Number = "QZ123", ProductId = 1, Quantity = 10 },
new Order { Number = "1234", ProductId = 2, Quantity = 55 }
};
To join these two list you would use the Lambdas Join expression. Below I query the orders list and join it with the products list by the order’s ProductId and the product’s Id. Then I return each result with a custom object with all the values in it.
var results = orders.Join (products, o => o.ProductId, p => p.Id, ((o, p) => new {
ProductName = p.Name,
UnitPrice = p.UnitPrice,
Number = o.Number,
Quantity = o.Quantity,
TotalCost = p.UnitPrice * o.Quantity
}));
To see the finishing result I write a foreach on the results and output the values to the console.
foreach (var order in results) {
Console.WriteLine ("Order No: {0}, Product: {1}, Qty: {2}, Unit Price: {3}, Total Cost: {4}", order.Number, order.ProductName, order.Quantity, order.UnitPrice, order.TotalCost);
}
by David Loo | Nov 9, 2014 | AngularJS
If you are using Kendo UI for your current project and require a string input box with auto complete, Kendo’s AutoComplete directive can do the trick. The AutoComplete can use a custom template to format the results. In this blog I am going to demonstrate how to use Kendo UI’s AutoComplete and let you know what to expect from it.
Below I have a HTML markup to define my controller and an input control that uses the kendo-auto-complete directive and k-options attribute for configuring the directive.
<div ng-controller="AppController">
<h4>Kendo UI AutoComplete</h4>
<p>Enter a country name that starts with the letter 'A'</p>
<input kendo-auto-complete ng-model="country" k-options="options" class="form-control"/>
<p>Your selection: {{ country }}</p>
</div>
Below in my JavaScript I am going to create an AngularJS module called “app” and include “kendo.directives” module. Then I create a controller called “AppController” and within this controller I am defining an array of country names and their codes. I have created a variable called $scope.country and this is where we are going to store the selected value from the AutoComplete.
angular.module('app', ['kendo.directives'])
.controller('AppController', ['$scope', function($scope) {
$scope.countries = [
{name: 'Afghanistan', code: 'AF'},
{name: 'Åland Islands', code: 'AX'},
{name: 'Albania', code: 'AL'},
{name: 'Algeria', code: 'DZ'},
{name: 'American Samoa', code: 'AS'},
{name: 'AndorrA', code: 'AD'},
{name: 'Angola', code: 'AO'},
{name: 'Anguilla', code: 'AI'},
{name: 'Antarctica', code: 'AQ'},
{name: 'Antigua and Barbuda', code: 'AG'},
{name: 'Argentina', code: 'AR'},
{name: 'Armenia', code: 'AM'},
{name: 'Aruba', code: 'AW'},
{name: 'Australia', code: 'AU'},
{name: 'Austria', code: 'AT'},
{name: 'Azerbaijan', code: 'AZ'}
];
$scope.country = '';
$scope.options = {
dataTextField: 'name',
dataSource: $scope.countries,
template: 'Code: #: code#<br>Name: #: name#',
}
}]);
Now the interesting part, I have created a $scope.options configuration object that will be used by Kendo’s AutoComplete directive. In the options I have dataTextField set as “name” which means that when we select a value from the AutoComplete the name property value from the array will be used to populate the model. Datasource will be the array of countries with their name and code, and template which is optional.
$scope.options = {
dataTextField: 'name',
dataSource: $scope.countries,
template: 'Code: #: code#<br>Name: #: name#',
}
The template I am using is a custom template for showing matching results. If you dont use it it will just show what ever you have specified in the dataTextField property. Here I have created a very simple template that will display the name and code of the country. Display property is a template you must wrap the property name with a hash character, and the first hash character must follow by a colon.
#: name#
Your can clone a copy of my source code from Git Hub: Learn AngularJS Repository
by David Loo | Aug 18, 2014 | AngularJS
AngularJS Service is very useful for providing repeated behavior, shared state, caches and factories. AngularJS Service are singleton for the scope of the application and each service is instantiated once and each part of your application gets access to the same instance of the service.
AngularJS Service is completely driven by the AngularJS dependency injection system and all internal services or your own create service can be injected into other service, directive or controller by specifying it as a dependency.
The $ prefix in AngularJS means they are internal services like $log, $http, $window and so on and it makes it easy to tell difference from your own custom service. (more…)
by David Loo | Jul 13, 2014 | PHP
Today I decided to customise my WordPress blog and I wanted add a Gravatar photo of myself on the side menu, so I decided to install PHP Code Widget and wrote the following code snippet.
If you don’t have a Gravatar account click here to create one for yourself.
How this works is that your gravatar image is associated with an email, and to access that image you need to convert an email address to a hash value using md5 function in PHP. With that hash value you need to append it to the end of the gravatar url like this:
http://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50
So the code below we are converting the email address to a hash value and append it to the gravatar url and you have an option to specify the image size by providing a parameter ?s=size, size has to be an numeric value eg. ?s=200. Then we echo an <img> with the src attribute pointing to the url address:
<?php
$hash = md5(strtolower(trim("name@email.com")));
$imgUrl = 'http://www.gravatar.com/avatar/' . $hash . '?s=200';
echo "<center><img id=\"gravatar\" style=\"border:1px solid black\" src=\"" . $imgUrl . "\" /></center>";
?>
by David Loo | Jul 12, 2014 | AngularJS
What is a Controller
If you are familiar with the MVC architectural pattern then controllers are nothing new to you. But to for those that are not, the controller’s job is to receive input from the view and updates the model or get data from the model and and update the view. For further information about Model View Controllers click here.
By using the ng-controller directive on your html page (view) allows you to associate AngularJS controller to a view.
<div ng-controller="HelloWorldController">
</div>
(more…)
by David Loo | Jul 8, 2014 | AngularJS
I came across a problem in Angular today with using ng-repeat directive.
For example if you have a list of numbers you want to iterate through and in that list you may have duplicate numbers, well ng-repeat will throw an error complaining about the duplicate value.
Here is an example code snippet of my html code with the problem:
<li ng-repeat="number in [1,2,3,4,1]">{{number}}</>
This is what I had to do to fix the problem:
<li ng-repeat="number in [1,2,3,4,1] track by $index">{{number}}</>
By telling ng-repeat to track each item by index each of the numbers in the list will be displayed.