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"}]

Leave a Reply