Xây dựng giao diện (ok)
Last updated
Last updated
"use strict";
window.APP = window.APP || {};
APP.crudRouter = Backbone.Router.extend({
routes: {
"crud/new": "create",
"crud/index": "index",
"crud/:id/edit": "edit",
"crud/active": "active",
"crud/disable": "disable"
},
$container: $('#primary-content'),
initialize: function () {
this.collection = new APP.crudCollection();
this.collection.fetch({ajaxSync: false, async: false});
APP.helpers.debug(this.collection);
this.index();
// start backbone watching url changes
Backbone.history.start();
var pubnub = PUBNUB.init({
publish_key: 'demo',
subscribe_key: 'demo'
});
},
create: function () {
var view = new APP.crudNewView({
collection: this.collection,
model: new APP.crudModel()
});
this.$container.html(view.render().el);
},
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);
$(document).ready(function() {
$('#list-cruds').DataTable();
} );
},
active: function () {
var view = new APP.crudIndexView({collection: new APP.crudCollection(this.collection.where({active: "1"}))});
this.$container.html(view.render().el);
$(document).ready(function() {
$('#list-cruds').DataTable();
} );
},
disable: function () {
var view = new APP.crudIndexView({collection: new APP.crudCollection(this.collection.where({active: "0"}))});
this.$container.html(view.render().el);
$(document).ready(function() {
$('#list-cruds').DataTable();
} );
}
});
"use strict";
APP.crudModel = Backbone.Model.extend({
url: function() {
var id = this.get('id');
return "crud.php?p=item&&id=" + id;
},
defaults: {
name: "",
address: "",
email: "",
phone: "",
id: "",
active: 0
},
validate: function (attrs) {
var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
var errors = {};
if (!attrs.name) {
errors.name = "name must be required";
}
if (!attrs.address) {
errors.address = "address must be required";
}
if (!attrs.email) {
errors.email = "email must be required";
} else if (!attrs.email.match(mailformat)) {
errors.email = "You have entered an invalid email address!" ;
}
if (!attrs.phone) {
errors.phone = "phone must be required";
} else if(isNaN(attrs.phone)) {
errors.phone = "phone must be numeric";
}
if (!_.isEmpty(errors))
return errors;
}
});
APP.crudCollection = Backbone.Collection.extend({
name: 'crudCollection',
model: APP.crudModel,
url: 'crud.php',
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>CRUD BackboneJS PHP MySQL</title>
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css" rel="stylesheet">
<style>
.alert.fixed {
position: fixed;
top: 20px;
left: 25%;
width: 50%;
margin-bottom: 0;
box-shadow: 0px 0px 10px #454545;
}
</style>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="modal fade" id="modalDelete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
Modal Confirm
</div>
<div class="modal-body">
<div class="content"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<a href="#" id="delete" class="btn btn-success success">Delete</a>
</div>
</div>
</div>
</div>
<div class="container">
<div class="page-header">
<h1>MY CRUD</h1>
</div>
<div id="message"></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>
<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>
<div class="form-group">
<label>Active:</label>
<% if(_.isEmpty(active) == false && active == 1) { %>
<input type="checkbox" name="active" value="1" checked>
<% } else { %>
<input type="checkbox" name="active" value="0">
<% } %>
</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>
<!-- the index container -->
<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>
<div id="collapseExample2">
<% if (_.isEmpty(cruds)){ %>
<div class="alert alert-warning">
<p>There are currently no cruds. Try creating some.</p>
</div>
<% } %>
<table id="list-cruds" class="table table-bordered table-striped">
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Address</th>
<th>Active</th>
<th width="140">Action</th>
</tr>
</thead>
<tbody>
<% var idx = 1 %>
<% _.each(cruds, function (crud) { %>
<tr>
<td><%= idx++ %></td>
<td><%= crud.name %></td>
<td><%= crud.email %></td>
<td><%= crud.phone %></td>
<td><%= crud.address %></td>
<% if (crud.active == 0) {%>
<td>Disable</td>
<% } else { %>
<td>Active</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 id="deleteButton" class="btn btn-xs btn-danger item-destroy" data-id="<%= crud.id %>"><i class="fa fa-trash"></i> Delete</a>
</td>
</tr>
<% }); %>
</tbody>
</table>
<a style="margin:10px 0px;" class="btn btn-large btn-info" href="#crud/index"> All</a>
<a style="margin:10px 0px;" class="btn btn-large btn-info" href="#crud/active"> Active</a>
<a style="margin:10px 0px;" class="btn btn-large btn-info" href="#crud/disable"> Disable</a>
</div>
</script>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="assets/js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<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="assets/js/pubnub.min.js"></script>
<script src="bower_components/pubnub-backbone/backbone-pubnub.min.js"></script>
<script>
var pubnub = PUBNUB.init({
subscribe_key: 'sub-c-4c7f1748-ced1-11e2-a5be-02ee2ddab7fe',
publish_key: 'pub-c-6dd9f234-e11e-4345-92c4-f723de52df70',
});
</script>
<script src="routers.js"></script>
<script src="models.js"></script>
<script src="views/view.js"></script>
<script src="helpers.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"></script>
<script>
var app = new APP.crudRouter();
</script>
</body>
</html>
(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) {
$('.help-block').remove();
_.each(_.keys(errors), function (key) {
$('*[name=' + key + ']').parent().addClass('has-error');
$('<span class="help-block has-error">'+ errors[key] +'</span>').insertAfter($('*[name=' + key + ']'));
});
}
};
}());
<?php
$db = new PDO('mysql:host=localhost;dbname=backbone_phpmysql', 'root', 'root');
$page = isset($_GET['p'])? $_GET['p'] : '';
if($page=='add'){
$sql = "INSERT INTO crud values (:id,:nm,:em,:hp,:ad,:at)";
$query = $db->prepare($sql);
$query->execute(array(":id"=>null,":nm"=>$_POST['name'],":em"=>$_POST['email'],":hp"=>$_POST['phone'],":ad"=>$_POST['address'],":at"=>$_POST['active']));
} else if($page=='edit'){
$sql = "UPDATE crud SET name= :nm, email= :em, phone= :hp, address= :ad, active= :at WHERE id = :id";
$query = $db->prepare($sql);
$query->execute(array(":id"=>$_POST['id'],":nm"=>$_POST['name'],":em"=>$_POST['email'],":hp"=>$_POST['phone'],":ad"=>$_POST['address'], ":at"=>$_POST['active']));
} else if($page=='trash'){
$sql = "DELETE FROM crud WHERE id = :id";
$query = $db->prepare($sql);
$query->execute(array(":id"=>$_POST['id']));
} else if($page=='item'){
$statement = $db->query("SELECT * FROM crud WHERE id = ".$_GET['id']);
$statement->setFetchMode(PDO::FETCH_ASSOC);
echo json_encode($statement->fetch());
} else{
$statement = $db->query('SELECT * FROM crud');
$statement->setFetchMode(PDO::FETCH_ASSOC);
echo json_encode($statement->fetchAll());
}
?>
views/view.js
"use strict";
APP.crudIndexView = Backbone.View.extend({
template: _.template($('#indexTemplate').html()),
events: {
'click .item-destroy': 'destroy'
},
destroy: function (e) {
$('#modalDelete .modal-content .modal-body .content').html("are you sure delete ?");
$('#modalDelete').modal('toggle');
var id = $(e.currentTarget).attr("data-id");
var crud = this.collection.get(id);
$('#delete').click(function(){
$('#modalDelete').modal('hide');
if (crud.destroy()) {
new APP.AlertView.show("CRUD", "Deleted Success", "success");
} else {
new APP.AlertView.show("CRUD", "Deleted Error", "danger");
}
$.post("crud.php?p=trash", {id: id}, function (data) {
Backbone.history.navigate("crud/index", {trigger: true});
});
});
},
render: function () {
this.$el.html(
this.template({cruds: this.collection.toJSON()})
);
return this;
}
});