Front Page

Welcome to the front page

Anonymous Functions and Closures – the ‘use’ Keyword

Anonymous Functions
PHP 5.3 supports the use of anonymous functions. An unnamed function can be created and assigned to a variable and then the variable can be used like an actual function. Consider the following example:

1
2
3
4
5
6
7
8
<?php
$mult = function($x)
    {
    return $x * 5;
    };
 echo $mult(2);  // 10

?>

Closures
Closures are anonymous functions that have access to variables not defined within themselves. A closure can be created using the ‘use’ keyword. Consider the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

$multiply = function($multiplier)
{
    return function($x) use ($multiplier)  // 'use' gives access to multiplier
    {
        return $x * $multiplier;
    };
};
 
// $mul5 now contains a function that returns a number multiplied by 5
$mult5 = $multiply(5);
 
// $mul7 contains a function that returns a number multiplied by 7
$mult7 = $multiply(7);
 
echo $mult5(5);  // 25
echo $mult7(5);  // 35
 
?>

This is a little different to closures in JavaScript that automatically have access to variables outside their scope.

There are other ways to pass variables to the anonymous functions shown above. The variables could be passed as arguments or the variables could have been declared as global. The latter case can be become quite messy, however. Using the ‘use’ keyword is an elegant alternative to both methods.

The Java paint() Method

This is a very simple example of Java’s paint() method. The paint() method takes an instance of the Graphics class. The Graphics class contain methods which are used for graphics operations. The following code paint a blue rectangle onto a JPanel component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Paint extends JPanel {

   public static void main(String[] a) {
      JFrame f = new JFrame();
      f.setSize(400, 400);
      Paint p = new Paint();
      f.add(p);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
   }
   @Override
   public void paint(Graphics g) {
       g.setColor(Color.blue);
       g.fillRect (5, 15, 50, 75);
     
   }
}

Single Page Applications with Backbone.js and AngularJS

Hash Tags
The hash tag (#) is used when linking to anchors within a current web page. The use of anchors allows the user to navigate to different parts of the page without going to a new URL. For example,

navigates to the part of the page with anchor

Both Backbone and AngularJS make use of # for routing application URLs in single page applications. In both cases, all links in the application should target “#/action” or “#action”. e.g. http://example.com/#/user. When the user clicks on different links within the application, instead of going to a different place on the page, different portions of the JavaScript in the code get executed.

Backbone.js Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
</head>
<body>

<ul>
<li><a href="#">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/contact">Contact</a></li>
<li><a href="#/redirect">Redirect</a></li>
</ul>

<div class="content"></div>
 
<script type="text/template" id="home-template">
<p><%= value %></p>
</script>

<script type="text/template" id="about-template">
<p><%= value %></p>
</script>

<script type="text/template" id="contact-template">
<p><%= value %></p>
</script>

<script type="text/template" id="redirect-template">
<p>This illustrates the use of backbone's router.navigate('nav', {trigger:true})
which automatically redirects to other locations in the application.  For example,
after saving, updating or deleting data from a database, you might might want to
show some kind of 'success' page.</p>
</script>


<script type="text/javascript">

var Router = Backbone.Router.extend({
   routes: {
    "": "homeview", // url:event that fires
    "about": "aboutview",
    "contact": "contactview",
    "redirect":"redirectview"
  },

// the 'home' view
homeview: function() {
    var content = "welcome to the home page";
    var template = _.template($('#home-template').html(), {value: content});
    $(".content").html(template);
    var HomeView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var hmview = new HomeView();
},

// the 'about' view
aboutview: function() {
    var content = "welcome to the about page";
    var template = _.template($('#about-template').html(), {value: content});
    $(".content").html(template);
    var AboutView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var abtview = new AboutView();
},

// the 'contact us' view
contactview: function() {
    var content = "welcome to the contact us page";
    var template = _.template($('#contact-template').html(), {value: content});
    $(".content").html(template);
    var ContactView = Backbone.View.extend({
    el: '.content',    
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var conview = new ContactView();
},

// demonstrates the automatic redirect functionality
redirectview: function() {
    alert('On closure this we will automatically redirect to another location in the application.');
    router.navigate('redirect', {trigger:true});
    var template = _.template($('#redirect-template').html(), {});
    $(".content").html(template);
    var RedirectView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var rdview = new RedirectView();
}
});
var router = new Router;

/*
This is an alternative syntax  to the above that uses JQuery's "on" method
 
router.on('route:homeview', function() {
   ...
 }
*/

// Start Backbone history
Backbone.history.start();
</script>

</body>
</html>

See the live demo here

The equivalent of the above using AngularJS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>
</head>
<body>

<div ng-app="myApp">

<ul>
<li><a href="#">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/contact">Contact</a></li>
<li><a href="#/redirect">Redirect</a></li>
</ul>

<div ng-view></div>

</div>

<script>
// create a new module
// also include ngRoute for all our routing needs
   
var myApp = angular.module('myApp', ['ngRoute']);

// configure the routes
   
myApp.config(function($routeProvider) {
/*
AngularJS's $routeProvider has a very basic api for defining application's routes.
$routeProvider.when() is used to match a url pattern to a view while
$routeProvider.otherwise() is used to render a view when there is no
match to a url pattern.
*/


$routeProvider

// route for the home page
  .when('/', {
         templateUrl : 'pages/home.html',
         controller  : 'homeController'
        })

// route for the about page
.when('/about', {
                 templateUrl : 'pages/about.html',
                 controller  : 'aboutController'
              })

// route for the contact page
.when('/contact', {
                   templateUrl : 'pages/contact.html',
                   controller  : 'contactController',
                })

// route for the redirect page
.when('/redirect', {
                    templateUrl : 'pages/redirect.html',
                    controller  : 'redirectController',
                    // automatically redirect
                    redirectTo: '/redirect'
                });
    });
   
// create the controller and inject Angular's $scope
myApp.controller('homeController', function($scope) {
// create a message to display in the view
$scope.message = 'welcome to the home page';
    });

myApp.controller('aboutController', function($scope) {
    $scope.message = 'welcome to the about page.';
    });

myApp.controller('contactController', function($scope) {
    $scope.message = 'welcome to the contact us page.';
    });

myApp.controller('redirectController', function($scope) {
    $scope.message = 'This illustrates the use of AngularJS\'s  redirectTo method which automatically redirects to other locations in the application.  For example, after saving, updating or deleting data from a database, you might might want to show some kind of \'success\' page.';
    alert('On closure this we will automatically redirect to another location in the application.');
    });

</script>

</body>
</html>

Directory Structure

index.html
pages
|_ home.html
|_ about.html
|_ contact.html
|_ redirct.html

home.html/about.html/contact.html/redirect.html

1
2
3
<div>
<p>{{ message }}</p>
</div>

See the live demo here

JavaScript Prototype Property

With the prototype property it is possible to add properties and methods to an object. In a similar manner to other languages such as PHP and Java, prototyping allows objects to inherit, override, and extend functionality. Prototyping is best illustrated with an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE HTML>
<html lang="en-US">
<head></head>
 
<script>
// add a base object (functions are objects in JavaScript)
var base = function() {}

//Add a multiply function to base using prototype
base.prototype.multiply = function(a,b){
return a*b;}

/* we could also write this using object literal notation
base.prototype = {
multiply: function(a,b){
return a* b;
}
}
*/


//Add a property to base
base.prototype.message = "hello from base";

/* we could do this in object literal notation but we need
to use __proto__.  However, this may not be supported in all
browsers.
base.__proto__ = {
message:  'hello from base'
}
*/


var obj = new base();
alert(obj.multiply(3,5));  // 15

//Access message property added to base
alert(obj.message); // hello from base

Inheritance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//  Inherit from base by doing the following:

//create a new object with a variable 'constant'
var calc = function(){
this.constant = 10;
}

/*
allow calc to access all of base's properties and methods by
assigning a new base instance to calc's prototype property
*/

calc.prototype = new base();  

var c = new calc();
alert(c.multiply(10,10));  // 100

Overriding

1
2
3
4
5
6
7
8
9
10
11
/*
override the existing multiply function by defining a new multiply
function assigning it calc's prototype property.
*/

calc.prototype.multiply = function(a,b){
return a*b - this.constant;
}

var co = new calc();
alert(co.multiply(10,10)); // 90
alert(co.constant); // 10

The ‘static’ Keyword

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can). Also, a static variable within a function will not lose its value when the function exits and will still hold that value should the function be called again. All of this is illustrated in the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

class A {

 // Class property
static $counter = 0;

 // Class method
public static function keep_track() {
   static $count = 0;
   $count++;
   self::$counter++;
   echo "count = " . $count . " : counter =  " . self::$counter . "<br />";
}
}

//Access through instantiation of the class.
$obj = new A();
$obj->keep_track();  
//$obj->counter;  // Error!

//Access without needing an instantiation of the class.
A::keep_track();  
A::keep_track();  
//echo A::$count;  // Error!
echo "class property: " . A::$counter;  

?>

The code outputs:

1
2
3
4
count = 1 : counter = 1
count = 2 : counter = 2
count = 3 : counter = 3
class property: 3

Using Backbone.js with Underscore.js and Handlebars.js

Underscore.js is the default templating engine for Backbone.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
</head>
<body>
 
<div class="content"></div>
 
<script type="text/template" id="person-list-template">
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    <% _.each(value, function(person) { %>
      <tr>
        <td><%= person.get('name') %></td>
        <td><%= person.get('email') %></td>
      </tr>
    <% }); %>
  </tbody>
</table>
</script>

<script type="text/javascript">

var Person = Backbone.Model.extend({
    defaults: {
        name: 'Dave Smith',
        email: 'dave@bb.com'
    }
});
 
var doe = new Person({ id: 1, name: 'John Doe', email: 'johndoe@bb.com' });
var hancock = new Person({ id: 2, name: 'John Hancock', email: 'johnhancock@bb.com' });
var jefferson = new Person({ id: 3, name: 'Thomas Jefferson', email: 'thomasjefferson@bb.com'});


var Persons = Backbone.Collection.extend({
    model: Person
});
 
var personArray = [doe, hancock, jefferson];
var persons = new Persons(personArray);  


var template = _.template($('#person-list-template').html(), {value: persons.models});
/*
At this point we could use:
var template = _.template($('#person-list-template').html(), {value: persons.toJSON()});
If we do then the iterator becomes
<% _.each(value, function(person) { %>
      <tr>
        <td><%= person.name %></td>
        <td><%= person.email %></td>
      </tr>
    <% }); %>
*/


$(".content").html(template);

var PersonsListView = Backbone.View.extend({
    el: '.content',
     
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var personslistview = new PersonsListView();


</script>

</body>
</html>

However, some people prefer other options. Handlebars is very popular and uses the mustache style syntax which involves the use of {{ brackets }} to indicate dynamic values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src ="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.4/handlebars.js"></script>
</head>
<body>
 
<div class="content"></div>
 
<script id="person-list-template" type="text/x-handlebars-template">
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
     {{#each []}}
      <tr>
        <td>{{ this.name }}</td>
        <td>{{ this.email }}</td>
      </tr>
     {{/each}}
  </tbody>
</table>
</script>
 
 
<script type="text/javascript">

var Person = Backbone.Model.extend({
    defaults: {
        name: 'Dave Smith',
        email: 'dave@bb.com'
    }
});
 
var doe = new Person({ id: 1, name: 'John Doe', email: 'johndoe@bb.com' });
var hancock = new Person({ id: 2, name: 'John Hancock', email: 'johnhancock@bb.com' });
var jefferson = new Person({ id: 3, name: 'Thomas Jefferson', email: 'thomasjefferson@bb.com'});


var Persons = Backbone.Collection.extend({
    model: Person
});
 
var personArray = [doe, hancock, jefferson];
var persons = new Persons(personArray);  

var PersonsListView = Backbone.View.extend({
    el: '.content',
    initialize:function(){
        this.render();
    },
    render: function () {
        var source = $('#person-list-template').html();
        var template = Handlebars.compile(source);
        var html = template(persons.toJSON());
        this.$el.html(html);
    }
});
var personslistview = new PersonsListView();
</script>
</body>
</html>

Simple AngularJS REST Example

This is a simple AngularJS example that uses the Bootstrap framework for styling.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<div ng-app="myApp" ng-controller="formController">
<div class = "container">

<h3>PUT Request</h3>

<script type="text/ng-template" id="tableTemplate.html">
<div class="table-responsive">
<table ng-show="formSubmitted" class="table table-striped">
  <thead>
    <tr>
      <th class="col-md-2">id</th>
      <th class="col-md-5">name</th>
      <th class="col-md-5">email</th>
    </tr>
  </thead>
  <tbody>
  <tr ng-repeat="x in names">  <!-- iterate through [{...},{...}, ...] -->
    <td>{{ x.id }}</td>
    <td>{{ x.name }}</td>
    <td>{{ x.email }}</td>
    <tr>
  </tbody>
</table>
</div>
</script>

<form class="form-horizontal" ng-submit = "processForm()" role = "form">
<div class="form-group">
<label class="col-sm-2 control-label">id:</label>
<div class="col-sm-10">
<input type = "text"  name = "id" ng-model = "formData.id">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">name:</label>
<div class="col-sm-10">
<input type = "text" name = "name" ng-model = "formData.name">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">email:</label>
<div class="col-sm-10">
<input type = "email" name = "email" ng-model = "formData.email">
</div>
</div>

<button class="btn btn-success" ng-disabled="error || incomplete">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</form>

<div ng-include="'tableTemplate.html'"></div>

</div>
</div>

<script>
var app = angular.module('myApp',[]);
app.controller("formController", function($scope,$http){
    $scope.formData = {};
    $scope.processForm = function()
    {
   
   // PUT /users/id
    var url = 'http://localhost/angular/users/' + $scope.formData.id;
    var data = '{"name": "' + $scope.formData.name  + '", "email":"' + $scope.formData.email + '"}';
    $http({method: 'PUT', url: url, data: data}).success(function(response)    
    {
     $scope.names = response;
     // display the table when the form is submitted
     $scope.formSubmitted = true;
    });

 /*
     // GET /users
    $http({method: 'GET', url: 'http://localhost/angular/users'}).success(function(response)    
    {$scope.names = response;});

    // GET /users/id
    var url = 'http://localhost/users/' + $scope.formData.id;
    $http({method: 'GET', url: url}).success(function(response)    
    {$scope.names = response;});

    // POST /users
    var data = '{"name": "' + $scope.formData.name  + '", "email":"' + $scope.formData.email + '"}';
    $http({method: 'POST', url: 'http://localhost/users', data: data}).success(function(response)    
    {$scope.names = response;});

    // DELETE /users/id
    var url = 'http://localhost/users/' + $scope.formData.id;
    $http({method: 'DELETE', url: url}).success(function(response)    
    {$scope.names = response;});
*/

   }
 
});
</script>
</body>
</html>

Route all requests to index.php
.htaccess:

1
2
3
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

index.php:
On the server side we use the Slim PHP micro framework for handling the REST requests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
header('Content-Type: application/json');
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

$app->get('/users', 'getnames');
$app->get('/users/:id', 'getname');
$app->post('/users', 'addname');
$app->put('/users/:id', 'updatename');
$app->delete('/users/:id', 'deletename');

$app->run();

function getnames() {
$out = array();
$out[0]['id'] = 1;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@angular.com';
$out[1]['id'] = 2;
$out[1]['name'] = 'John Hancock';
$out[1]['email'] = 'johnhancock@angular.com';
echo json_encode($out);
}

function getname($id) {
$out = array();
if ($id == 1 || $id == 'tom'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@angular.com';
}
if ($id == 2 || $id == 'dick'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Hancock';
$out[0]['email'] = 'johnhancock@angular.com';
}
echo json_encode($out);
}

function addname() {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());  
$out = array();
$out[0]['name'] = $message->name . " has been added";
$out[0]['email'] = $message->email . " has been added";
echo json_encode($out);
}

function updatename($id) {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());
$out = array();
$out[0]['id'] = $id;
$out[0]['name'] = "updated to: " . $message->name;
$out[0]['email'] = "updated to: " . $message->email;
echo json_encode($out);
}

function deletename($id) {
$out = array();
$out[0]['id'] = $id;
$out[0]['name'] = $message->name . " has been deleted";
$out[0]['email'] = $message->email . " has been deleted";
echo json_encode($out);
}
?>

Slim returns the following JSON response for a GET request.

1
[{"id":1,"name":"John Doe","email":"johndoe@angular.com"},{"id":2,"name":"John Hancock","email":"johnhancock@angular.com"}]

AngularJS Custom Directives

An alternative to using the built-in directive

1
<div ng-include="'tableTemplate.html'"></div>

is to place the data binding expression into a custom directive as follows:

1
2
3
4
5
6
7
app.directive('myDirective', function() {
    return {
        replace: true,
        restrict: 'AE',  //E = element, A = attribute, C = class, M = comment
        templateUrl: 'tableTemplate.html'
          }
});

and replace the ng-include directive with

1
<div my-directive></div>

AngularJS automatically makes the connection between the my-directive directive and the directive name myDirective by removing the dash and converting the result to camelCase syntax.

There are many other properties that can be used in directives. Some of the key ones are shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
template: '<div>{{ myVal }}</div>',  // Use this template
controller: controllerFunction, //Embed a custom controller
link: function ($scope, element, attrs) { // DOM manipulation
      element.bind('click', function () {
          element.html('You clicked me!');
           });
      element.bind('mouseenter', function () {
          element.css('background-color', 'yellow')
           });
      element.bind('mouseleave', function () {
          element.css('background-color', 'white');
           });
      }

Server Events

With SSEs a web app “subscribes” to a stream of updates generated by a server. When communicating using SSEs, a server can push data to your application whenever it wants, without the need to make an initial request In other words, updates can be streamed from server to client as they happen. SSEs open a single unidirectional channel between server and client. They are sent over traditional HTTP which means they do not require a special protocol or server implementation to work. This is a basic example. The default situation is for the browser to attempt to reconnect to the source roughly 3 seconds after each connection is closed. In this example the timeout limit has been changed to 10 seconds by including a line beginning with “retry:”, followed by the number of milliseconds (10000) to wait before trying to reconnect.

Client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
//check for browser support
if(typeof(EventSource)!=="undefined") {
    /*
          create an object, passing it the name and location of
          the server side script
        */

    var eSource = new EventSource("ssebasic.php");
    //detect message receipt
    eSource.onmessage = function(event) {
        //write the received data to the page
        document.getElementById("serverData").innerHTML = event.data;
    };
}
else {
    document.getElementById("serverdata").innerHTML="Your browser doesn't receive server-sent events.";
}
</script>
<div id = serverdata"></div>

Server (ssebasic.php):

1
2
3
4
5
6
7
8
9
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$time = date('r');
echo "retry: 10000" . PHP_EOL;
echo "data: The server time is: $time" . PHP_EOL;
flush(); // flush the output buffer
?>

Basic Backbone.js CRUD Example

This is a simple Backbone.js example that uses the Bootstrap framework for styling.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<div class = "container">

<h3>PUT Request</h3>

<script type="text/template" id="form_template">

<form class="form-horizontal" role = "form">
<div class="form-group">
<label class="col-sm-2 control-label">id:</label>
<div class="col-sm-10">
<input type = "text" id = "id">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">name:</label>
<div class="col-sm-10">
<input type = "text" id = "name">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">email:</label>
<div class="col-sm-10">
<input type = "email" id = "email">
</div>
</div>
</form>

<button class="btn btn-success">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</script>


<script type="text/template" id="iterator_template">

<div class="table-responsive">
<table  class="table table-striped">
  <thead>
    <tr>
      <th class="col-md-2">id</th>
      <th class="col-md-5">name</th>
      <th class="col-md-5">email</th>
    </tr>
  </thead>
  <tbody>
<% _.each(value, function(user)  { %>
   <tr>
   <td><%= user.get('id') %></td>
   <td><%= user.get('name') %></td>
   <td><%= user.get('email') %></td>
   </tr>
<% }); %>
</tr>
</tbody>
</table>
</div>
</script>

<div id="form_container"></div>
<div id ="iterator_container"></div>

</div>  <!-- container -->

<script type="text/javascript">

var UserModel = Backbone.Model.extend({
        urlRoot: 'http://localhost/backbone/users',
        /*
        In the case of a GET user/id, POST user/, PUT user/id or DELETE user/id
        request our server returns a single model as an array with a single
        element,[{...}].  In order to display this data in our iterator we need
        to extract just the {...} add it to the collections using the .add()
        method.  The extraction is accomplished by overriding the default BB
        parse operation (no-op) on the 'response' object, with the following
        function. In the case of a GET users/ or GET users/name where one of
        more users is loaded directly in the collection, we do not need this
        function.
        */

        parse: function(response){
        if(response && response.length) return response[0];
    }
});

var UserModels = Backbone.Collection.extend({
        url: 'http://localhost/backbone/users',
        model: UserModel
});

var UserModelsWhere = Backbone.Collection.extend({
        url: 'http://localhost/backbone/users/tom',
        model: UserModel
});

FormView = Backbone.View.extend({
        el: '#form_container',
         initialize: function(){
            this.render();
        },
        render: function(){
            var template = _.template( $("#form_template").html(), {} );
            this.$el.html( template );
        },
        events: {
            "click .btn": "go"
        },
        go: function( event ){
        var iterator_view = new IteratorView();  // instantiate the view
       }
 });

IteratorView = Backbone.View.extend({
         el: '#iterator_container',
         initialize: function(){
         var self = this;  // allows 'this' to be used in the sub-function.

       // PUT users/id
         var id =  $("#id").val();
         var name = $("#name").val();
         var email = $("#email").val();
         var userDetails = {id: id, name: name, email: email};
         self.users = new UserModels();  // create a collection
         self.user= new UserModel();
         self.user.save(userDetails, {
         success: function (user) {
            self.users.add(user);  // add the model to the collection
            self.render();
        }
           
         /*
         //GET users/id
         var userDetails = {id:1};
         self.users = new UserModels();  // create a collection
         self.user = new UserModel(userDetails);
         self.user.fetch({
         success: function (user) {
            self.users.add(user);  // add the model to the collection
            self.render();
        }
         */


         /* GET users/
         self.users = new UserModels();  // create a collection
         self.users.fetch({
         success: function (users) {
            self.render();
         }
        */


         /*  POST
         var userDetails = {name: 'Thomas Jefferson', email: 'thomasjefferson@backbone.com'};
         self.users = new UserModels();  // create a collection
         self.user= new UserModel();
         self.user.save(userDetails, {
         success: function (user) {
            self.users.add(user);  // add the model to the collection
            self.render();
        }
        */


        /* GET users/name
         self.users = new UserModelsWhere();  // create a collection
         self.users.fetch({
         success: function (users) {
            self.render();
        }
       */

 
       /* DELETE users/id
         var userDetails = {id: 1, name: 'has been deleted!'};
         self.users = new UserModels();  // create a collection
         self.user= new UserModel(userDetails);
         self.user.destroy({
         success: function (user) {
         self.users.add(user);  // add the model to the collection
         self.render(); // shows 1 has been deleted!
        }
       */


        });
        },
        render: function(){
            var template = _.template( $("#iterator_template").html(), {value: this.users.models} );
            this.$el.html( template );
        },
       });

    var form_view = new FormView();

</script>
</body>
</html>

Route all requests to index.php
.htaccess:

1
2
3
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

On the server side we use the Slim PHP micro framework for handling the REST requests.
index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
header('Content-Type: application/json');
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

$app->get('/users', 'getnames');
$app->get('/users/:id', 'getname');
$app->post('/users', 'addname');
$app->put('/users/:id', 'updatename');
$app->delete('/users/:id', 'deletename');

$app->run();

function getnames() {
$out = array();
$out[0]['id'] = 1;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@backbone.com';
$out[1]['id'] = 2;
$out[1]['name'] = 'John Hancock';
$out[1]['email'] = 'johnhancock@backbone.com';
echo json_encode($out);
}

function getname($id) {
$out = array();
if ($id == 1 || $id == 'tom'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@backbone.com';
}
if ($id == 2 || $id == 'dick'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Hancock';
$out[0]['email'] = 'johnhancock@backbone.com';
echo json_encode($out);
}

function addname() {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());  
$out = array();
$out[0]['name'] = $message->name . " has been added";
$out[0]['email'] = $message->email . " has been added";
echo json_encode($out);
}

function updatename($id) {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());
$out = array();
$out[0]['id'] = $id;
$out[0]['name'] = "updated to: " . $message->name;
$out[0]['email'] = "updated to: " . $message->email;
echo json_encode($out);
}

function deletename($id) {
// delete the record with id = $id
}
?>

Slim returns the following JSON response for a GET request.

1
[{"id":1,"name":"John Doe","email":"johndoe@angular.com"},{"id":2,"name":"John Hancock","email":"johnhancock@angular.com"}]