I have the following Todos app in Backbone:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Hello World in Backbone.js</title>
<style type='text/css'>
#todoapp ul {
list-style-type: none;
}
#todo-list input.edit {
display: none;
}
#todo-list .editing label {
display: none;
}
#todo-list .editing input.edit {
display: inline;
}
</style>
</head>
<body>
<section id='todoapp'>
<header id='header'>
<h1>Todos</h1>
<input id='new-todo' placeholder='What needs to be done?'>
</header>
<section id='main'>
<ul id='todo-list'></ul>
</section>
</section>
<script type='text/x-handlebars-template' id='item-template'>
<div class='view'>
<input class='toggle' type='checkbox'>
<label>{{ title }} </label>
<input class='edit' value='{{ title }}'>
<button class='destroy'>remove</button>
</div>
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.amd.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
<script type="text/javascript">
var App = {
Models: {},
Collections: {},
Views: {}
}
App.Models.Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
App.Collections.TodoList = Backbone.Collection.extend({
model: App.Models.Todo,
localStorage: new Store('backbone-todo')
});
App.Views.Todo = Backbone.View.extend({
tagName: 'li',
template: Handlebars.compile($('#item-template').html()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
this.input = this.$('.edit');
return this;
},
initialize: function(){
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
},
events: {
'dblclick label': 'edit',
'keypress .edit': 'updateOnEnter',
'blur .edit': 'close',
'click .toggle': 'toggleCompleted',
'click .destroy': 'destroy'
},
edit: function(){
this.$el.addClass('editing');
this.input.focus();
},
updateOnEnter: function(e){
if(e.which == 13){
this.close();
}
},
close: function(){
var value = this.input.val().trim();
if(value){
this.model.save({title: value});
}
this.$el.removeClass('editing');
},
toggleCompleted: function(){
this.model.toggle();
},
destroy: function(){
this.model.destroy();
}
});
App.Views.TodoList = Backbone.View.extend({
el: '#todoapp',
initialize: function() {
this.input = this.$('#new-todo')
this.collection.on('add', this.addOne, this);
this.collection.on('reset', this.addAll, this);
this.collection.fetch();
},
events: {
'keypress #new-todo': 'createTodoOnEnter'
},
createTodoOnEnter: function(e) {
if(e.which !== 13 || !this.input.val().trim()){
return;
}
this.collection.create(this.newAttributes());
this.input.val('');
},
addOne: function(todo){
var view = new App.Views.Todo({model: todo});
$('#todo-list').append(view.render().el);
},
addAll: function(){
this.$('#todo-list').html('');
this.collection.each(this.addOne, this);
},
newAttributes: function(){
return {
title: this.input.val().trim(),
completed: false
}
}
});
var todoList = new App.Collections.TodoList();
var todoListView = new App.Views.TodoList({collection: todoList});
</script>
</body>
</html>
But when I open the html file in my browser, the template placeholders are not populate with the data. It shows {{ title }} instead of the actual title. What am I missing here?
PS: I'm seeing the following 2 errors in the console: 1. Uncaught ReferenceError: define is not defined (in handlebars.amd.js)
Uncaught ReferenceError: Handlebars is not defined (on line
Handlebars.compile($('#item-template').html()))