Skip to content

Instantly share code, notes, and snippets.

@sahinsf
Created September 14, 2012 21:05
Show Gist options
  • Save sahinsf/3724817 to your computer and use it in GitHub Desktop.
Save sahinsf/3724817 to your computer and use it in GitHub Desktop.
jQuery to Backbone step by step
<?php
//if(isset($_POST['text']) && !empty($_POST['text']))
//$text = $_POST['text'];
//$text = array("text" => $text);
$text = json_decode(file_get_contents('php://input'));
//$text -> text .= " said user!";
print(json_encode($text));
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>HTML Document</title>
<link href="http://fonts.googleapis.com/css?family=Abel" rel="stylesheet" type="text/css">
<style type="text/css">
body { padding: 0; margin: 0; background-color: #fff; }
h2 { font-family: Abel, sans-serif; margin: 0; padding: 0 0 5px 0;}
input { background-color: #ddd; border: 0; }
input:active { background-color: #bbb; }
#new-status { margin: 20px; padding: 20px; background-color: #67A9C3; }
#statuses { margin: 20px; padding: 20px; background-color: #92B456; }
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
</head>
<body>
<div id="new-status">
<h2>New monolog</h2>
<form action="">
<textarea></textarea><br>
<input type="submit" value="Post"/>
</form>
</div>
<div id="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
<script >
/*
$(document).ready(function() { //wait for DOM to load (listen page event)
$('#new-status form').submit(function(e) { //set a submit listener (listen user event)
e.preventDefault();
$.ajax({ //send input to the server
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: $('#new-status textarea').val() },
success: function(data) { //listen network event
//parse the response
$('#statuses ul').append('<li>' + data.text + '</li>'); // HTML templating
$('#new-status textarea').val('');
}
});
});
});
*/
//This code does a lot of stuff at the same time.
//It listens for page events, user events, network events,
//it does network IO, handles user input, parses the response, and does HTML templating.
/////////////SINGLE RESPONSIBILITY PRINCIPLE:: which is far easier to test, maintain, reuse and extend /////////
//=>And we want to move as much as possible out of $(document).ready, so we can trigger the code ourselves
////////////Separating DOM and Ajax//////////////////////////
/*
function addStatus(){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: $('#new-status textarea').val() }, //DOM
success: function(data) {
$('#statuses ul').append('<li>' + data.text + '</li>'); //DOM
$('#new-status textarea').val(''); //DOM
}
});
}
$(document).ready(function() {
$('#new-status').submit(function(e) { //DOM
e.preventDefault();
addStatus();
});
});
*/
////////////Separating DOM and Ajax//////////////////////////
/*
function addStatus(options) {
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
$(document).ready(function() {
$('#new-status form').submit(function(e) { //DOM
e.preventDefault();
addStatus(
{
text: $('#new-status textarea').val(), //DOM
success: function(data) {
$('#statuses ul').append('<li>' + data.text + '</li>'); //DOM
$('#new-status textarea').val(''); //DOM
}
}
);
});
});
*/
////////////we want to wrap these statuses in an object and be able to write statuses.add instead of addStatus()//////////////////////////
//if it was module pattern !!!
/*
var statuses ={
add : function(options){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
};
*/
/*
//constructor pattern with prototypes
var Statuses = function(){}; //Class
Statuses.prototype.add = function(options){ //method
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
////////////submit handler now has one dependency, the 'statuses' variable, and everything else within it is focused on the DOM////
$(document).ready(function() {
var statuses = new Statuses(); //construct & initialize an object
$('#new-status').submit(function(e) {
e.preventDefault();
statuses.add({
text: $('#new-status textarea').val(),
success: function(data) {
$('#statuses ul').append('<li>' + data.text + '</li>');
$('#new-status textarea').val('');
}
});
});
});
*/
////////////Creating a view//////////////////////////
// Let's move the submit handler and everything inside it into its own class, NewStatusView:
//Now we only bootstrap our application when the DOM is loaded, and everything else is moved out of $(document).ready.
//The steps we have taken so far has given us two components which are easier to test and have more well-defined responsibilities.
/*
var Statuses = function(){};
Statuses.prototype.add = function(options){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
var NewStatusView = function(options){
var statuses = options.statuses;
$('#new-status').submit(function(e) {
e.preventDefault();
statuses.add({ //!!!
text: $('#new-status textarea').val(),
success: function(data) {
$('#statuses ul').append('<li>' + data.text + '</li>');
$('#new-status textarea').val('');
}
});
});
};
$(document).ready(function() {
var statuses = new Statuses();
NewStatusView(
{statuses: statuses}
);
});
*/
//////////////////////////////////////splitting the submit handler in NewStatusView into its own addStatus method: //////////////////////
/*
var Statuses = function(){};
Statuses.prototype.add = function(options){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
var NewStatusView = function(options){
this.statuses = options.statuses; //?????????????????? var statuses = options.statuses;
var add = $.proxy(this.addStatus, this);
$('#new-status form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add({ //!!!
text: $('#new-status textarea').val(),
success: function(data) {
$('#statuses ul').append('<li>' + data.text + '</li>');
$('#new-status textarea').val('');
}
});
};
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
});
*/
///////////////////////////////////////Let's make the success callback call methods instead of working directly on the DOM, which makes the callback easier to read and work with: /////
/*
var Statuses = function(){};
Statuses.prototype.add = function(options){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
var add = $.proxy(this.addStatus, this);
$('#new-status form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
var that = this;
this.statuses.add({ //!!!
text: $('#new-status textarea').val(),
success: function(data) {
that.appendStatus(data.text);
that.clearInput();
}
});
};
NewStatusView.prototype.appendStatus = function(text){
$('#statuses ul').append('<li>' + text + '</li>');
}
NewStatusView.prototype.clearInput = function(){
$('#new-status textarea').val('');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
});
*/
////////////////////Adding Backbone events////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// we let the success callback trigger an event instead of calling methods.
//by declaring which methods we want to call in the constructor when the event is triggered:
//Now we can declare in the constructor what we want to happen when a status is added, instead of addStatus being responsible for handling success.
//The only responsibility addStatus should have is backend communication, not updating the DOM.
// Events do not have to be declared before they are bound, and may take passed arguments.
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(options){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: options.text },
success: options.success
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
events.on('status:add', this.appendStatus, this);
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
$('#new-status form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add({ //!!!
text: $('#new-status textarea').val(),
success: function(data) {
events.trigger('status:add', data.text);
}
});
};
NewStatusView.prototype.appendStatus = function(text){
$('#statuses ul').append('<li>' + text + '</li>');
}
NewStatusView.prototype.clearInput = function(){
$('#new-status textarea').val('');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
});
*/
////////////As we no longer deal with the view in the success callback we can move the triggering of the event into the add method on Statuses/////////////////////////
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
events.on('status:add', this.appendStatus, this);
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
$('#new-status form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add($('#new-status textarea').val());
};
NewStatusView.prototype.appendStatus = function(text){
$('#statuses ul').append('<li>' + text + '</li>');
}
NewStatusView.prototype.clearInput = function(){
$('#new-status textarea').val('');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
});
*/
/////////////////A view's responsibilities //////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Separating responsibilities:: #statuses -> StatusesView || #new-status -> NewStatusView
//Let's pull a StatusesView out of #statuses, and let it be responsible for #statuses.
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
$('#new-status form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add($('#new-status textarea').val());
};
NewStatusView.prototype.clearInput = function(){
$('#new-status textarea').val('');
}
var StatusesView = function(){
events.on('status:add', this.appendStatus, this);
}
StatusesView.prototype.appendStatus = function(text){
$('#statuses ul').append('<li>' + text + '</li>');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
new StatusesView();
});
*/
/////////////////////////////As each view is now responsible for only one HTML element, we can specify them when instantiating the views:///////////////////////////
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
this.el = $('#new-status');
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.el.find('form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add(this.el.find('textarea').val());
};
NewStatusView.prototype.clearInput = function(){
this.el.find('textarea').val('');
}
var StatusesView = function(){
this.el = $('#statuses');
events.on('status:add', this.appendStatus, this);
}
StatusesView.prototype.appendStatus = function(text){
this.el.find('ul').append('<li>' + text + '</li>');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {statuses: statuses} );
new StatusesView();
});
*/
//////////////////////////////////////still difficult to test because they depend on having the HTML present//////////////////////////////////
///////////////////////////////To remedy this we can pass in its DOM dependencies when we instantiate a view.
//Now, this is easy to test! With this change we can use a jQuery trick to test our views.
//Instead of initiating our views by passing in for example $('#new-status'), we can pass in the necessary HTML wrapped in jQuery, e.g. $('<div><form>…</form></div>').
//jQuery will then create the needed DOM elements on the fly.
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
this.el = options.el;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.el.find('form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add(this.el.find('textarea').val());
};
NewStatusView.prototype.clearInput = function(){
this.el.find('textarea').val('');
}
var StatusesView = function(options){
this.el = options.el;
events.on('status:add', this.appendStatus, this);
}
StatusesView.prototype.appendStatus = function(text){
this.el.find('ul').append('<li>' + text + '</li>');
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses')});
});
*/
///////////Our next step is introducing a helper to clean up our views a little bit. Instead of writing this.el.find we can create a simple helper so we can write this.$ instead///////////
//With this little change it feels like we are saying, I want to use jQuery to look for something locally on this view instead of globally in the entire HTML.
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = function(options){
this.statuses = options.statuses;
this.el = options.el;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
};
NewStatusView.prototype.addStatus = function(e){
e.preventDefault();
this.statuses.add(this.$('textarea').val());
};
NewStatusView.prototype.clearInput = function(){
this.$('textarea').val('');
}
NewStatusView.prototype.$ = function(selector){
return this.el.find(selector);
}
var StatusesView = function(options){
this.el = options.el;
events.on('status:add', this.appendStatus, this);
}
StatusesView.prototype.appendStatus = function(text){
this.$('ul').append('<li>' + text + '</li>');
}
StatusesView.prototype.$ = function(selector){
return this.el.find(selector);
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses')});
});
*/
//However, adding this functionality for every view is a pain. That's one of the reasons to use Backbone.js views — reusing functionality across views.
//////////////////////////////Getting started with views in Backbone/////////////////////////////////////////////////////////////////////////////////////
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = Backbone.View.extend({
initialize: function(options){
this.statuses = options.statuses;
this.el = options.el;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.statuses.add(this.$('textarea').val());
},
clearInput: function(){
this.$('textarea').val('');
},
$: function(selector){
return this.el.find(selector);
}
});
var StatusesView = function(options){
this.el = options.el;
events.on('status:add', this.appendStatus, this);
}
StatusesView.prototype.appendStatus = function(text){
this.$('ul').append('<li>' + text + '</li>');
}
StatusesView.prototype.$ = function(selector){
return this.el.find(selector);
}
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses')});
});
*/
///////Now that we use Backbone.js views we can remove the this.$ helper, as it already exists in Backbone.
////////////We also no longer need to set this.el ourselves, as Backbone.js does it automatically when a view is instantiated with an HTML element.
/*
var events = _.clone(Backbone.Events);
var Statuses = function(){};
Statuses.prototype.add = function(text){
$.ajax({
url: 'ajaxStatus.php',
type: 'POST',
dataType: 'json',
data: { text: text },
success: function(data) {
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = Backbone.View.extend({
initialize: function(options){
this.statuses = options.statuses;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.statuses.add(this.$('textarea').val());
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(options){
events.on('status:add', this.appendStatus, this);
},
appendStatus: function(text){
this.$('ul').append('<li>' + text + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses')});
});
*/
/////////////////////////////////Let's use a model: responsible for the network traffic/////////////////////////////////////////////////////////////////////////////////
/// Backbone nicely abstracts Ajax, we don't need to specify "type", "dataType" and "data" anymore
//we only need to specify the URL and call "save" on the model.
//The "save" method accepts the data we want to save as the first parameter, and options, such as the success callback, as the second parameter.
/*
var events = _.clone(Backbone.Events);
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = function(){};
Statuses.prototype.add = function(text){
var status = new Status();
status.save({text: text}, {
success: function(model, data){ // model ????????
events.trigger('status:add', data.text);
}
});
}
var NewStatusView = Backbone.View.extend({
initialize: function(options){
this.statuses = options.statuses;
events.on('status:add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.statuses.add(this.$('textarea').val());
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(options){
events.on('status:add', this.appendStatus, this);
},
appendStatus: function(text){
this.$('ul').append('<li>' + text + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses')});
});
*/
///Handling several models: COLLECTIONS /////////////////////////////////////
// we have introduced models, we need a concept for a list of models, such as the list of statuses in our application: Collections
//really cool thing about collections is that they have scoped events.
//Basically, this just means that we can bind and trigger events directly on a collection instead of using our events variable —
//our events will live on statuses instead of events.
// As we now start firing events directly on statuses there's no need for "status" in the event name, so we rename it from "status:add" to "add".
/*
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = Backbone.Collection.extend({
add: function(text){
var status = new Status();
var that = this;
status.save({text: text}, {
success: function(model, data){ // model ????????
that.trigger('add', data.text); // !!! "add" method --> triggers "add" event ==> triggers view Methods for DOM manipulation
//console.log(model);
//console.log(model.attributes); // same => console.log(data);
}
});
}
});
var NewStatusView = Backbone.View.extend({
initialize: function(options){
this.statuses = options.statuses;
this.statuses.on('add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.statuses.add(this.$('textarea').val());
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(options){
this.statuses = options.statuses;
this.statuses.on('add', this.appendStatus, this);
},
appendStatus: function(text){
this.$('ul').append('<li>' + text + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,statuses: statuses} );
new StatusesView({el: $('#statuses'),statuses: statuses});
});
*/
////////////////////////////// As with el earlier, Backbone.js automatically sets "this.collection" when collection is passed. Therefore we rename statuses to collection in our view:///
/*
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = Backbone.Collection.extend({
add: function(text){
var status = new Status(); ///creates a new model instance
var that = this;
status.save({text: text}, { //saves it to the server
success: function(model, data){ //adds it to the collection
that.trigger('add', data.text); //"add" event to be triggered on the collection,
}
});
}
});
var NewStatusView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.collection.add(this.$('textarea').val());
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.appendStatus, this);
},
appendStatus: function(text){
this.$('ul').append('<li>' + text + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,collection: statuses} );
new StatusesView({el: $('#statuses'),collection: statuses});
});
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////We can simplify this even more by using Backbone's create method. It creates a new model instance, adds it to the collection and saves it to the server.///////////
//1-When creating the status we need to pass in an options hash with the attributes we want to save, instead of only passing the text.
//2-The built in "create" also triggers an "add" event, but rather than passing only the text, as we have done so far, it passes the newly created model.
//We can get the text from the model by calling ' model.get("text") '
// this.$('ul').append('<li>' + text ==> status.get("text") + '</li>');
// pass wait:true to the .create() if you'd like to wait for the server before adding the new model to the collection.
/*
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = Backbone.Collection.extend({
model: Status //In order for collection.create() to work, you should set the model property of the collection
});
var NewStatusView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.clearInput, this);
var add = $.proxy(this.addStatus, this);
this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.collection.create({text: this.$('textarea').val()}, {wait:true}); // !!!! passed wait:true this.collection.create({text: this.$('textarea').val()});
//COLLECTION.create()=> 1-creates a new model instance 2-saves it to the server 3-adds it to the collection
// 4- Creating a model will cause an immediate "add" event to be triggered on the collection, as well as a "sync" event, once the model has been successfully created on the server
// 5- Pass {wait: true} if you'd like to wait for the server before adding the new model to the collection.
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.appendStatus, this);
},
appendStatus: function(status){ //==> this could be left as: function(text) and text.get("text") ,, just naming
console.log(status);
this.$('ul').append('<li>' + status.get("text") + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,collection: statuses} );
new StatusesView({el: $('#statuses'),collection: statuses});
});
*/
///////////////////////////////////////////////////Evented Views////////////////////////////////////////////////////////////////////
//Now, let's get rid of that nasty $.proxy stuff. We can do this by letting Backbone.js delegate our events by specifying them in an "events" hash in the view.
//This hash is on the format {"event selector": "callback"} ===> in a View => events: { "submit form" : "addStatus" }
/*
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = Backbone.Collection.extend({
model: Status
});
var NewStatusView = Backbone.View.extend({
events: {
'submit form' : 'addStatus'
},
initialize: function(){
this.collection.on('add', this.clearInput, this);
//var add = $.proxy(this.addStatus, this);
//this.$('form').submit(add);
},
addStatus: function(e){
e.preventDefault();
this.collection.create({text: this.$('textarea').val()}, {wait:true}); // !!!! passed wait:true this.collection.create({text: this.$('textarea').val()});
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.appendStatus, this);
},
appendStatus: function(status){
console.log(status);
this.$('ul').append('<li>' + status.get("text") + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,collection: statuses} );
new StatusesView({el: $('#statuses'),collection: statuses});
});
*/
//////////////////////////Escape it! prevent XSS-exploits. Instead of using model.get('text') let's use the built-in escape handling and write model.escape('text') ////////////
///If you're using Handlebars, Mustache or similar templating engines, you might get this functionality out of the box.
var Status = Backbone.Model.extend({
url: 'ajaxStatus.php'
});
var Statuses = Backbone.Collection.extend({
model: Status
});
var NewStatusView = Backbone.View.extend({
events: {
'submit form' : 'addStatus'
},
initialize: function(){
this.collection.on('add', this.clearInput, this);
},
addStatus: function(e){
e.preventDefault();
this.collection.create({text: this.$('textarea').val()}, {wait:true}); // !!!! passed wait:true this.collection.create({text: this.$('textarea').val()});
},
clearInput: function(){
this.$('textarea').val('');
}
});
var StatusesView = Backbone.View.extend({
initialize: function(){
this.collection.on('add', this.appendStatus, this);
},
appendStatus: function(status){
console.log(status);
this.$('ul').append('<li>' + status.escape("text") + '</li>');
}
});
$(document).ready(function() {
var statuses = new Statuses();
new NewStatusView( {el: $('#new-status') ,collection: statuses} );
new StatusesView({el: $('#statuses'),collection: statuses});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>HTML Document</title>
<link href="http://fonts.googleapis.com/css?family=Abel" rel="stylesheet" type="text/css">
<style type="text/css">
body { padding: 0; margin: 0; background-color: #fff; }
h2 { font-family: Abel, sans-serif; margin: 0; padding: 0 0 5px 0;}
input { background-color: #ddd; border: 0; }
input:active { background-color: #bbb; }
#new-status { margin: 20px; padding: 20px; background-color: #67A9C3; }
#statuses { margin: 20px; padding: 20px; background-color: #92B456; }
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
</head>
<body>
<div id="new-status">
<h2>New monolog</h2>
<form action="">
<textarea></textarea><br>
<input type="submit" value="Post"/>
</form>
</div>
<div id="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
<script >
$(document).ready(function() { //wait for DOM to load (listen page event)
$('#new-status form').submit(function(e) { //set a submit listener (listen user event)
e.preventDefault();
var text = $('#new-status textarea').val();
//console.log(text);
var data = {};
data.text = text;
//console.log(data.text);
data = JSON.stringify(data);
//console.log(data);
$.ajax({ //send input to the server
url: 'ajaxStatus.php',
type: 'POST',
contentType: 'json', /////////????? doesnt send in json format
dataType: 'json',
data: data,
success: function(data) { //listen network event
console.log(data);
//parse the response
$('#statuses ul').append('<li>' + data.text + '</li>'); // HTML templating
$('#new-status textarea').val('');
}
});
});
});
//This code does a lot of stuff at the same time.
//It listens for page events, user events, network events,
//it does network IO, handles user input, parses the response, and does HTML templating.
//////////////////////////////////////
/*
var ItemView = Backbone.View.extend({
tagName: 'li'
});
var BodyView = Backbone.View.extend({
el: 'body'
});
var
SomethingView = Backbone.View.extend({
id: 'container'
});
var item = new ItemView();
var item2 = new BodyView();
var item3 = new SomethingView();
//item3.setElement(item);
console.log(item);
console.log(item.el);
console.log(item.tagName);
console.log(item2.el);
console.log(item3.el);
console.log(item3.$el);
item3.$el.html("some text");
console.log(item3.$el);
item3.$el.appendTo('#statuses ul');
*/
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment