Skip to content

Instantly share code, notes, and snippets.

@karlwestin
Last active December 11, 2015 15:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karlwestin/4618724 to your computer and use it in GitHub Desktop.
Save karlwestin/4618724 to your computer and use it in GitHub Desktop.
Backbone.JS frontend blog thing

so i wrote the blog app described by luc perkins in Backbone. I consider pretty good with backbone.js, but this doesn't even come close to the slickness of the angular app he describes in his post :/

This definitely made me more interested in angular.js!

to get started:

bower install backbone
bower install jquery
bower install requirejs
python -m simpleHTTPServer
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>YESS</title>
</head>
<body>
<div id="app">
<hr>
<div>
<button class="js_new_post">New</button>
</div>
<hr>
</div>
<script type="template/x-template" id="postTemplate">
<div style="padding: 20px; background-color: <%= backgroundColor %>;">
<h1><%= title %>
<div><%= post %></div>
<hr>
<div>
<b>Published at: <%= updated %></b>
<button class="js_edit">Edit</button>
</div>
</script>
<script type="template/x-template" id="editTemplate">
<input type="text" placeholder="title" id="title" value="<%= title %>">
<br>
<textarea placeholder="post" id="post"><%= post %></textarea><br>
<input type="text" placeholder="mood" id="mood" value="<%= mood %>"><br>
<select id="backgroundColor">
<% _.each(colors, function(color) { print("<option value='" + color + "' " + (color == backgroundColor ? "selected>" : ">") + color + "</option>") }) %>
</select>
<div>
<button class="js_save">Save</button>
<button class="js_delete">Delete</button>
</div>
</script>
<script src="components/requirejs/require.js" data-main="script" type="text/javascript" charset="utf-8"></script>
</body>
</html>
require.config({
shim: {
backbone: {
deps: ["jquery", "underscore"],
exports: "Backbone"
},
underscore: {
exports: "_"
}
},
paths: {
backbone: "components/backbone/backbone",
jquery: "components/jquery/jquery",
underscore: "components/underscore/underscore"
}
});
define([
"underscore",
"backbone"
], function(_, Backbone) {
var Post = Backbone.Model.extend({
defaults: {
"title": "",
"post": "",
"mood": "neutral",
"backgroundColor": "white",
"colors": ["white", "red", "green", "blue"]
},
validate: function(data) {
var mood = _.chain(["title", "post", "mood"])
.map(function(check) {
return !data[check] ? "Post needs a " + check : false;
})
.compact()
.value();
return mood.length ? mood : false;
}
});
var Blog = Backbone.Collection.extend({
model: Post
});
function renderMethod() {
var data = this.model.toJSON(),
content = this.template(data);
this.$el.html(content);
return this;
}
var PostView = Backbone.View.extend({
edit: function(e) {
var view = new EditView({ model: this.model });
view.setElement(this.el);
view.render();
e && e.preventDefault();
},
events: {
"click .js_edit": "edit"
},
initialize: function() {
this.model.on("change", this.render, this);
},
render: renderMethod,
template: _.template($("#postTemplate").html())
});
var EditView = Backbone.View.extend({
"delete": function(e) {
e.preventDefault();
this.model.collection.remove(this.model);
},
events: {
"click .js_save": "save",
"click .js_delete": "delete"
},
render: renderMethod,
save: function(e) {
e.preventDefault();
var data = {};
_.each(["post", "title", "mood", "backgroundColor"], function(item) {
data[item] = this.$("#" + item).val();
});
data.updated = new Date().getTime();
if(this.model.set(data, { validate: true })) {
this.undelegateEvents();
}
},
template: _.template($("#editTemplate").html())
});
var PostList = Backbone.View.extend({
add: function(model) {
this.views[model.cid] = new PostView({ model: model });
this.$el.prepend(this.views[model.cid].el);
this.views[model.cid].edit();
},
events: {
"click .js_new_post": "newPost"
},
initialize: function() {
this.views = {};
this.collection = new Blog();
this.collection.on("add", this.add, this);
this.collection.on("remove", this.remove, this);
},
newPost: function(e) {
e.preventDefault();
var post = new Post();
this.collection.add(post);
},
remove: function(model) {
var view = this.views[model.cid];
if(view) {
view.off();
view.$el.detach();
delete this.views[model.cid];
}
}
});
var blog = new PostList({ el: document.getElementById("app") });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment