CRUD With Backbone.JS and PHP MySQL

CRUD With Backbone.JS and PHP MySQL

In this tutorial will discuss how to add data, view data, edit or update data and delete data using backbone.js and php mysql, CRUD operation is an stand for add data, view/read data, edit or update data and delete data. The way it works is almost the same as CRUD in php mysql but here it is emphasized using Backbone.js. The difference is only in the use of the framework only.

Backbone.js is a JavaScript MV * that supports routes, data bindings, and models, just like their rivals such as AngularJS and EmberJS, for AngularJS other articles will be created to discuss it. Backbone.js function is similar to ajax function that is post, get, put and delete but backbone.js has many features like routes and models, besides, backbone.js and ajax can be put together in one file or in the backbone code.

As in this tutorial, combine between backbone.js with ajax, ajax only handle data and update data only while others will be handled by backbone.js. How to create CRUD by using Backbone.JS and PHP MySQL as below.

Create Database

Creating a database for storing data, data will be input through input form and will be executed by backbone.js and php then then saved into the mysql database. For database and table names use the crud or mydata name or like the syntax code below.

CREATE DATABASE IF NOT EXISTS `mydata` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `mydata`;

CREATE TABLE `crud` (
  `id` int(11) NOT NULL PRIMARY KEY,
  `name` varchar(60) NOT NULL,
  `email` varchar(45) NOT NULL,
  `phone` varchar(20) NOT NULL,
  `address` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Basic Backbone

Basic backbone here means is a function that is often used on all backbone applications that are routers and models, below is the router and model syntax code.

Routers.js

"use strict";

window.APP = window.APP || {};
APP.crudRouter = Backbone.Router.extend({
  routes: {
    "crud/new": "create",
    "crud/index": "index",
    "crud/:id/edit": "edit",
    "crud/:id/delete": "delete"
  },

  $container: $('#primary-content'),

  initialize: function () {
    this.collection = new APP.crudCollection();
    this.collection.fetch({ajaxSync: false});
    APP.helpers.debug(this.collection);
    this.index();
    Backbone.history.start();
  },

  create: function () {
    var view = new APP.crudNewView({
      collection: this.collection, 
      model: new APP.crudModel()
    });
    this.$container.html(view.render().el);
    $('.myid').val(_.random(0, 10000));
  },

  delete: function (id) {
    var crud = this.collection.get(id);
    crud.destroy();
    $.get("crud.php?p=trash", { id: id }, function(data){
      Backbone.history.navigate("crud/index", {trigger: true});
    });
  },

  edit: function (id) {
    var view = new APP.crudEditView({model: this.collection.get(id)});
    this.$container.html(view.render().el);
  },

  index: function () {
    var view = new APP.crudIndexView({collection: this.collection});
    this.$container.html(view.render().el);
  }
});

Models.js

"use strict";
APP.crudModel = Backbone.Model.extend({
  defaults: {
    name: "",
    address: "",
    email: "",
    phone: "",
    id: ""
  },

  validate: function (attrs) {
    var errors = {};
    if (!attrs.name) errors.name = "Bèk tuwö nan droëkeuh";
    if (!attrs.address) errors.address = "Teumpat tinggai droëkeuh peu katuwö";
    if (!attrs.email) errors.email = "Surèl droëkeuh kapasoe beh";
    if (!attrs.phone) errors.phone = "Numboi hp kah bèk tuwö";
    if (!_.isEmpty(errors)) return errors;
  }
});

APP.crudCollection = Backbone.Collection.extend({
  model: APP.crudModel,
  url: 'crud.php'
});

Helpers.js

(function () {
  APP.helpers = {

    debug: function (collection) {
      collection.on('all', function () {
        $('#output').text(JSON.stringify(collection.toJSON(), null, 4));
      });
      collection.trigger('reset');
    },

    showErrors: function (note, errors) {
      $('.has-error').removeClass('has-error');
      $('.alert').html(_.values(errors).join('<br>')).show();

      _.each(_.keys(errors), function (key) {
        $('*[name=' + key + ']').parent().addClass('has-error');
      });
    }
  };
}());

Library Framework

Creating a cool layout can use the common framework Bootstrap, Awesome Fonts and others, For libraries like syntax code below.

<link href="assets/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/font-awesome.min.css" rel="stylesheet">

<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/backbone/underscore-min.js"></script>
<script src="assets/backbone/backbone-min.js"></script>
<script src="assets/backbone/backbone.localStorage.js"></script>
<script src="routers.js"></script>
<script src="models.js"></script>
<script src="views/view.js"></script>
<script src="views/add.js"></script>
<script src="views/edit.js"></script>
<script src="helpers.js"></script>
<script>
    var app = new APP.crudRouter();
</script>

Layout Design

The layout design here is the display using the html syntax code along with the class that will connect to the framework library like bootstrap.

<div class="container">
        <div class="page-header">
        <h1>CRUD BackboneJS PHP MySQL</h1>
        </div>

        <div class="panel panel-default">
            <div class="panel-body" id="primary-content">
                <!-- this is content -->
            </div>
        </div>
        <button style="margin:10px 0;" class="btn btn-warning" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample"><i class="fa fa-desktop"></i> Show Output JSON</button>
        <div class="collapse" id="collapseExample">
            <code id="output" style="display:block;white-space:pre-wrap;"></code>
        </div>
</div>

<script type="text/jst" id="formTemplate">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="alert alert-danger fade in" style="display:none;"></div>
                <form>
                    <h2><%= name %></h2>
                    <% if(_.isEmpty(id)==false){ %>
                    <div class="form-group">
                        <label>ID:</label>
                        <input type="text" class="form-control" name="id" value="<%= id %>" readonly />
                    </div>
                    <% } else{ %>
                    <div class="form-group">
                        <label>ID:</label>
                        <input type="text" class="form-control myid" name="id"/>
                    </div>
                    <% } %>
                    <div class="form-group">
                        <label>Name:</label>
                        <input type="text" class="form-control" name="name" value="<%= name %>" />
                    </div>
                    <div class="form-group">
                        <label>Email:</label>
                        <input type="text" class="form-control" name="email" value="<%= email %>" />
                    </div>
                    <div class="form-group">
                        <label>Phone:</label>
                        <input type="text" class="form-control" name="phone" value="<%= phone %>" />
                    </div>
                    <div class="form-group">
                        <label>Address:</label>
                        <textarea class="form-control" rows="5" name="address"><%= address %></textarea>
                    </div>
                    <button class="save btn btn-large btn-info" type="submit">Save</button>
                    <a href="#crud/index" class="btn btn-large btn-default">Cancel</a>
                </form>
            </div>
        </div>
</script>

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

        <a style="margin:10px 0px;" class="btn btn-large btn-info" href="#crud/new"><i class="fa fa-plus"></i> Create New Data</a>
        <a data-toggle="collapse" data-target="#collapseExample2" aria-expanded="false" aria-controls="collapseExample2" style="margin:10px 0px;" class="btn btn-large btn-success" href="#crud/index"><i class="fa fa-list"></i> View Data (Double Click)</a>

        <div class="collapse" id="collapseExample2">
        <% if (_.isEmpty(cruds)){ %>
        <div class="alert alert-warning">
            <p>There are currently no cruds. Try creating some.</p>
        </div>
        <% } %>

        <table class="table table-bordered table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Phone</th>
                    <th>Address</th>
                    <th width="140">Action</th>
                </tr>
            </thead>
            <tbody>
                <% _.each(cruds, function (crud) { %>
                <tr>
                    <td><%= crud.id %></td>
                    <td><%= crud.name %></td>
                    <td><%= crud.email %></td>
                    <td><%= crud.phone %></td>
                    <td><%= crud.address %></td>
                    <td class="text-center">
                        <a class="btn btn-xs btn-info" href="#crud/<%= crud.id %>/edit"><i class="fa fa-pencil"></i> Edit</a>
                        <a class="btn btn-xs btn-danger" href="#crud/<%= crud.id %>/delete"><i class="fa fa-trash"></i> Delete</a>
                    </td>
                </tr>
                <% }); %>
            </tbody>
        </table>
        </div>

</script>

View Data

View data is to display data from database into html table.

"use strict";
APP.crudIndexView = Backbone.View.extend({
  
  template: _.template($('#indexTemplate').html()),

  render: function () {
    this.$el.html(
    	this.template({cruds: this.collection.toJSON()})
    );
    return this;
  }
});

Add Data

Add data is process added data through input form then will be executed by backbone and php then saved to database.

"use strict";

APP.crudNewView = Backbone.View.extend({
  events: {
    "click button.save": "save",
    "keyup input": "validate",
    "keyup textarea": "validate"
  },
  
  template: _.template($('#formTemplate').html()),

  initialize: function (options) {
    this.model.bind('invalid', APP.helpers.showErrors, APP.helpers);
  },

  save: function (event) {
    event.stopPropagation();
    event.preventDefault();

    this.model.set({
      id: this.$el.find('input[name=id]').val(),
      name: this.$el.find('input[name=name]').val(),
      email: this.$el.find('input[name=email]').val(),
      phone: this.$el.find('input[name=phone]').val(),
      address: this.$el.find('textarea[name=address]').val()
    });
    
    if (this.model.isValid()) {
      this.collection.add(this.model);
      this.model.save();
      var id = this.$el.find('input[name=id]').val();
      var nm = this.$el.find('input[name=name]').val();
      var em = this.$el.find('input[name=email]').val();
      var hp = this.$el.find('input[name=phone]').val();
      var ad = this.$el.find('textarea[name=address]').val();
      $.post("crud.php?p=add", { id: id, name: nm, email: em, phone: hp, address: ad } , function(data){
        Backbone.history.navigate("crud/index", {trigger: true});
      });
    }
  },

  render: function () {
    this.$el.html(
    	this.template(this.model.toJSON())
    );
    return this;
  }
});

Edit Data

Edit or update data is the process change data that starts from reading data into input form by id then data in input form is updated when update button is clicked.

"use strict";
APP.crudEditView = Backbone.View.extend({
  events: {
    "click button.save": "save"
  },

  template: _.template($('#formTemplate').html()),

  initialize: function (options) {
    this.model.bind('invalid', APP.helpers.showErrors, APP.helpers);
    this.model.bind('invalid', this.invalid, this);
  },

  invalid: function () {
    this.$el.find('a.cancel').hide();
  },

  save: function (event) {
    event.stopPropagation();
    event.preventDefault();

    this.model.set({
      id: this.$el.find('input[name=id]').val(),
      name: this.$el.find('input[name=name]').val(),
      email: this.$el.find('input[name=email]').val(),
      phone: this.$el.find('input[name=phone]').val(),
      address: this.$el.find('textarea[name=address]').val()
    });

    if (this.model.isValid()) {
      this.model.save();
      var id = this.$el.find('input[name=id]').val();
      var nm = this.$el.find('input[name=name]').val();
      var em = this.$el.find('input[name=email]').val();
      var hp = this.$el.find('input[name=phone]').val();
      var ad = this.$el.find('textarea[name=address]').val();
      $.post("crud.php?p=edit", { id: id, name: nm, email: em, phone: hp, address: ad } , function(data){
        Backbone.history.navigate("crud/index", {trigger: true});
      });
    }
  },

  render: function () {
    this.$el.html(
      this.template(this.model.toJSON())
    );
    return this;
  }
});
$db = new PDO("mysql:host=localhost;dbname=mydata", "root", "");
$page = isset($_GET['p'])? $_GET['p'] : '';
if($page=='add'){
    $sql = "INSERT INTO crud values (:id,:nm,:em,:hp,:ad)";
    $query = $db->prepare($sql);
    $query->execute(array(":id"=>$_POST['id'],":nm"=>$_POST['name'],":em"=>$_POST['email'],":hp"=>$_POST['phone'],":ad"=>$_POST['address']));
} else if($page=='edit'){
    $sql = "UPDATE crud SET name= :nm, email= :em, phone= :hp, address= :ad WHERE id = :id";
    $query = $db->prepare($sql);
    $query->execute(array(":nm"=>$_POST['name'],":em"=>$_POST['email'],":hp"=>$_POST['phone'],":ad"=>$_POST['address'], ":id"=>$_POST['id']));
} else if($page=='trash'){
    $sql = "DELETE FROM crud WHERE id = :id";
    $query = $db->prepare($sql);
    $query->execute(array(":id"=>$_GET['id']));
} else{
    $statement = $db->query('SELECT * FROM crud');
    $statement->setFetchMode(PDO::FETCH_ASSOC);
    echo json_encode($statement->fetchAll());
}

Thank you for you visit my blog tutorial, hopeful useful, and you can download this source code below.

 

CRUD With Backbone.JS and PHP MySQL

Tags: , , ,