Skip to content
Open
51 changes: 51 additions & 0 deletions client/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,54 @@ div .txt-help {
background: #EFEFEF;
padding: 30px;
}

/* Instructors */
.instructor .main, .instructors .main,
.course .main, .courses .main {
background: #555;
max-width: 700px;
margin: auto;
color: #fff;
padding-bottom: 1em;
border-radius: 10px;
}
.instructor h1, .instructors h1,
.course h1, .courses h1 {
text-align: center;
margin: 5px 0 1em;
}
.instructor p, .instructors p,
.course p, .course p {
font-size: 1.2em;
}
.instructor #single, .instructors #single,
.course #single, .courses #single {
padding-bottom: 2em;
}
.instructor .content, .instructors .content,
.course .content, .courses .content {
padding: 2em 4em 1em;
}
#result, #added {
padding: 1em 0 0;
}
.success {
color: #8DC63F;
}
button.btn {
margin: 0 5px 10px 0;
}
input, select {
margin: 0 0 1em 0;
color: #000;
}
option {
padding: 8px 10px;
}
#collections ul {
padding: 1em 0 0;
}
#collections li {
list-style: none;
padding: 0 0 1em;
}
15 changes: 9 additions & 6 deletions client/spa-index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>SPA</title>
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/style.css">
<meta charset="UTF-8">
<title>SPA</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
Hi, I'm the spa index from the spa folder.
<script src="/spa/js/build.js"></script>
Hi, I'm the spa index from the spa folder.
<script src="/spa/js/build.js"></script>
</body>
</html>
28 changes: 11 additions & 17 deletions client/spa/js/instructor/editInstructor.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
<style type="text/css">
.main {
margin: auto;
max-width: 980px;
}
input {
margin: 0 0 1em 0;
}
</style>
<section id="instructor">
<div class="main container">
<div class="container main">
<div class="content">
<form action="#">
<input class="textfield" id="firstName" value="<%- firstName %>" /><br/>
<input class="textfield" id="lastName" value="<%- lastName %>" /><br/>
<input class="textfield" id="skills" value="<%- skills %>" /><br/>
<button class="i-save">Save</button>
<button class="i-cancel">Cancel</button>
<div class="form-group">
<input class="form-control" placeholder="firstName" type="text" id="firstName" value="<%- firstName %>" /><span class="help-inline"></span>
<input class="form-control" placeholder="lastName" type="text" id="lastName" value="<%- lastName %>" /><span class="help-inline"></span>
<input class="form-control" placeholder="skills" type="text" id="skills" value="<%- skills %>" /><span class="help-inline"></span>
</div>
<button class="save btn btn-primary">Save</button>
<button class="cancel btn btn-info">Cancel</button>
<div id="added"></div>
</form>
</div>
</section>
</div>
16 changes: 14 additions & 2 deletions client/spa/js/instructor/instructor.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ var View = require('./instructor.view');

module.exports = Backbone.Controller.extend({
routes: {
'instructors/:id': 'showInstructor'
'instructors/:id': 'showInstructor',
'instructors/new': 'addInstructor'
},
initialize: function(){
this.options.container = this.options.container || 'body';
Expand All @@ -18,12 +19,13 @@ module.exports = Backbone.Controller.extend({
this.fetchModel(instructorId, function(err){
var view;

this.remove();
this.view.remove();
this.view = new View({model: this.model});

if (err){
view = this.renderError();
} else {
this.view.template = this.view.showTemplate;
view = this.renderView();
}
if (cb){
Expand All @@ -32,6 +34,15 @@ module.exports = Backbone.Controller.extend({

}.bind(this));
},
addInstructor: function() {
this.model = new Model();
this.model.isNew();

this.view.remove();

this.view.template = this.view.editTemplate;
this.renderView();
},
fetchModel: function(instructorId, cb){
this.model.set({id: instructorId});
this.model.fetch({
Expand All @@ -50,6 +61,7 @@ module.exports = Backbone.Controller.extend({
},
renderView: function(){
this.renderToContainer(this.view.render().$el);
this.view.delegateEvents(); // delegate for add in collections
return this.view;
},
renderError: function(){
Expand Down
22 changes: 5 additions & 17 deletions client/spa/js/instructor/instructor.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
<style type="text/css">
.main {
margin: auto;
max-width: 980px;
}
#result {
padding: 1em 0;
}
.success {
color: green;
}
</style>
<section id="instructor">
<div class="main container">
<div class="container main" id="single">
<div class="content">
<h1><%- firstName %> <%- lastName %></h1>
<p><%- skills %></p>
<button class="i-edit">Edit</button>
<button class="i-delete">Delete</button>
<button class="modify btn btn-primary">Edit</button>
<button class="delete btn btn-danger">Delete</button>
<div id="result"></div>
</div>
</section>
</div>
2 changes: 1 addition & 1 deletion client/spa/js/instructor/instructor.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ module.exports = Backbone.Model.extend({
if (!attrs.skills){
errors.push('skills cannot be empty');
}
return errors;
return errors.length > 0 ? errors: false;
}
});
39 changes: 27 additions & 12 deletions client/spa/js/instructor/instructor.view.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ var editTemplate = fs.readFileSync(__dirname + '/editInstructor.html', 'utf8');
module.exports = Backbone.View.extend({
className: 'instructor',
template: _.template(template),
showTemplate: _.template(template),
editTemplate: _.template(editTemplate),
events: {
'click .i-delete': 'destroy',
'click .i-edit': 'edit',
'click .i-save': 'save',
'click .i-cancel': 'cancel'
'click .delete': 'destroy',
'click .modify': 'modify',
'click .save': 'save',
'click .cancel': 'cancel'
},
initialize: function(){
this.listenTo(this.model, 'destroy', this.remove);
Expand All @@ -25,37 +26,51 @@ module.exports = Backbone.View.extend({
var context = this.model.toJSON();
this.$el.html(this.template(context));

// if it's adding new model, change button to Add
if (this.model.get('id') === undefined) {
this.$('.save').html('Add');
}

return this;
},
destroy: function(){
this.model.destroy();
},
edit: function(e){
modify: function(e){
var context = this.model.toJSON();
this.$el.html(this.editTemplate(context));

return this;
},
save: function(e) {
e.preventDefault(); // if there's no changes, do not do anything
// if there's no changes, do not do anything
e.preventDefault();

var formData = {
firstName: this.$('#firstName').val().trim(),
lastName: this.$('#lastName').val().trim(),
skills: this.$('#skills').val().trim()
};
var validate = {

var check = {
success: function() {
$('#result').addClass('success')
.html('Successfully updated instructor')
.fadeIn().delay(4000).fadeOut();
},
error: function(model, error) {
.html('Successfully updated instructor')
.fadeIn().delay(4000).fadeOut();

var addNew = $('.save').html();

if (addNew === 'Add') {
$('#added').addClass('success')
.html('Successfully added new instructor')
.fadeIn().delay(4000).fadeOut();
}
},
error: function(model, errors) {
}
};

this.model.save(formData, validate);
this.model.save(formData, check);
},
cancel: function(e) {
e.preventDefault(); // prevent event bubbling
Expand Down
44 changes: 44 additions & 0 deletions client/spa/js/instructor/instructors.collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

var Backbone = require('../vendor/index').Backbone;

module.exports = Backbone.Collection.extend({
url: '/api/instructors/',

initialize: function(){
this.on('sortById', this.sortById);
this.on('sortByFirstName', this.sortByFirstName);
this.on('sortByLastName', this.sortByLastName);
this.on('addNew', this.addNew);
this.trigger('sortById');
},

sortById: function(){
this.comparator = function(model){
return model.get('id');
};
this.sort();
},

sortByFirstName: function(){
this.comparator = function(model){
return model.get('firstName');
};
this.sort();
},

sortByLastName: function(){
this.comparator = function(model){
return model.get('lastName');
};
this.sort();
},

addNew: function() {
this.create = function(model) {
model.get('firstName');
model.get('lastName');
model.get('skills');
};
}
});
59 changes: 59 additions & 0 deletions client/spa/js/instructor/instructors.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

var Backbone = require('../vendor/index').Backbone;
var $ = require('../vendor/index').$;
var Model = require('./instructor.model');
var Collection = require('./instructors.collection');
var View = require('./instructors.view');

module.exports = Backbone.Controller.extend({
routes: {
'instructors': 'showInstructors'
},
initialize: function(){
this.options.container = this.options.container || 'body';
},
getCollection: function(){
if (!this.collection){
Collection = Collection.extend({model: Model});
this.collection = new Collection();
}
return this.collection;
},
getView: function(){
if (!this.view){
var V = View.extend({collection: this.collection});
this.view = new V();
this.view.on('addNew', function() {
// trigger the router for addNew
this.navigate('instructors/new', { trigger: true });
}.bind(this));
}
return this.view;
},
showInstructors: function(){
var self = this;

this.getCollection().fetch({
success: function(collection, response, options){
self.getView();
self.renderView();
},
error: function(collection, response, options){
self.renderError();
}
});
},
renderToContainer: function(html){
return $(this.options.container).html(html);
},
renderView: function(){
this.renderToContainer(this.view.render().$el);
this.view.delegateEvents();
return this.view;
},
renderError: function(){
return this.renderToContainer(
'<p>There was a problem rendering instructors</p>');
}
});
16 changes: 16 additions & 0 deletions client/spa/js/instructor/instructors.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="container main" id="collections">
<div class="content">
<h1>Instructors</h1>
<button class="addNew btn btn-primary">Add New</button>
<button class="sortById btn btn-default">Sort By Id</button>
<button class="sortByFirstName btn btn-default">Sort By First Name</button>
<button class="sortByLastName btn btn-default">Sort By Last Name</button>
<ul class="instructors">
<% _.each( models, function( model ){ %>
<li class="instructor">
<%- model.attributes.firstName %> <%- model.attributes.lastName %>
</li>
<% }); %>
</ul>
</div>
</div>
Loading