Skip to content

Commit 0b06476

Browse files
committed
Merge pull request #54 from startersacademy/iss42-learning-resources
Iss42 - learning resources module
2 parents ccfe1f9 + f744689 commit 0b06476

16 files changed

Lines changed: 845 additions & 9 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
.idea
22
node_modules
33
server/datasources.local.json
4-
server/model-config.local.json
4+
server/model-config.local.json

client/css/style.css

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,69 @@ header.carousel .fill {
119119
.txt-mbr-desc {
120120
font-size: 14px;
121121
}
122+
123+
/*---Learning Resource---*/
124+
/*Single ID*/
125+
.edit, .b-cancel, .b-update, .b-delete, .div-space-edit {
126+
display: none; /* Hides input box*/
127+
}
128+
.editing .b-edit, .editing .div-space-read {
129+
display: none; /* Hides styled text when .editing*/
130+
}
131+
.editing .b-update, .editing .b-delete, .editing .div-space-edit {
132+
display: block; /* Shows input text box when .editing*/
133+
}
134+
.editing .b-cancel, .editing .b-update {
135+
display: inline;
136+
}
137+
/*.vertical-center {
138+
min-height: 100%;
139+
min-height: 100vh;
140+
display: flex;
141+
align-items: center;
142+
}*/
143+
.sty-resource {
144+
text-transform: capitalize;
145+
}
146+
.sty-title {
147+
font-size: 1.5em;
148+
background: #4F4D4D;
149+
color: #FAFAFA;
150+
padding: 10px 20px;
151+
}
152+
.sty-desc {
153+
background: #F6F6F6;
154+
padding: 30px 20px;
155+
}
156+
.sty-authors {
157+
}
158+
.sty-resource-auth {
159+
font-size: .6em;
160+
color: #B7B7B7;
161+
}
162+
div[class^="div-space-edit"], .ctrl {
163+
margin: 20px 0;
164+
}
165+
div[class^="div-space-read"], .ctrl {
166+
margin: 0px 0;
167+
}
168+
div .txt-help {
169+
margin: 12px 0px;
170+
}
171+
.ctrl {
172+
margin: 30px 0px 20px 0px;
173+
}
174+
#msg {
175+
position: fixed;
176+
top: 10px;
177+
right: 10px;
178+
padding: 8px 12px;
179+
}
180+
.b-edit {
181+
float: right;
182+
margin-left: 10px;
183+
}
184+
.sty-form {
185+
background: #EFEFEF;
186+
padding: 30px;
187+
}

client/spa-index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<head lang="en">
44
<meta charset="UTF-8">
55
<title>SPA</title>
6+
<link rel="stylesheet" href="../css/bootstrap.min.css">
7+
<link rel="stylesheet" href="../css/style.css">
68
</head>
79
<body>
810
Hi, I'm the spa index from the spa folder.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
var Backbone = require('../vendor/index').Backbone;
4+
var $ = require('../vendor/index').$;
5+
var Model = require('./learning-resource.model');
6+
var View = require('./learning-resource.view');
7+
8+
module.exports = Backbone.Controller.extend({
9+
10+
routes: {
11+
'learning-resource/:id': 'showLearningResource'
12+
},
13+
14+
initialize: function(){
15+
this.options.container = this.options.container || 'body';
16+
},
17+
18+
initializeModel: function(attributes){
19+
this.model = new Model(attributes);
20+
this.view = new View({model: this.model});
21+
},
22+
23+
showLearningResource: function(learningResourceId){
24+
var self = this;
25+
var view = this.view;
26+
27+
//Ensures that what the view put in the DOM is removed and
28+
//any events the view had listenTo'd are removed.
29+
if (view) view.destroy();
30+
31+
this.initializeModel({id: learningResourceId});
32+
33+
this.model.fetch({
34+
success: function(){
35+
view = self.renderView();
36+
},
37+
error: function() {
38+
view = self.renderError();
39+
}
40+
});
41+
},
42+
43+
renderToContainer: function(view){
44+
return $(this.options.container).html(view);
45+
},
46+
47+
renderView: function(){
48+
this.renderToContainer(this.view.render().$el);
49+
return this.view;
50+
},
51+
52+
renderError: function(){
53+
return this.renderToContainer(
54+
'<p>There was a problem rendering this learning resource.</p>');
55+
}
56+
57+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<style type="text/css">
2+
</style>
3+
<div class="vertical-center">
4+
<div class="container">
5+
<div class="row">
6+
<div id="form-area" class="col-xs-8 col-xs-offset-2">
7+
<span id="msg" class="btn"></span>
8+
<div class="div-space-read sty-title">
9+
<button class="b-edit btn btn-primary">Edit</button>
10+
<span><%- title %></span>
11+
<div class="sty-resource-auth">
12+
<span class="sty-resource"><%- resourceType %></span>
13+
<span class="sty-authors">by: <span id="author-dsp"></span></span>
14+
</div>
15+
</div>
16+
<div class="div-space-edit">
17+
<div class="txt-help">Title: </div>
18+
<input class="form-control" id="title" value="<%- title %>" placeholder="Title">
19+
</div>
20+
<div class="div-space-edit">
21+
<div class="txt-help">Resource Type: </div>
22+
<select id="resourceType" class="form-control">
23+
<option value="document">Document</option>
24+
<option value="link">Link</option>
25+
<option value="presentation">Presentation</option>
26+
</select>
27+
</div>
28+
<div class="div-space-edit">
29+
<div class="txt-help">Authors: </div>
30+
<input class="form-control" id="auth" value="<%- authors %>" placeholder="Authors">
31+
</div>
32+
<!-- <div class="div-space-read">
33+
<span class="sty-resource"><%- resourceType %></span>
34+
<%_.each(authors, function(val){ %>
35+
<div class="sty-authors"><%= val %></div>
36+
<% }); %>
37+
</div> -->
38+
<div class="div-space-read sty-desc">
39+
<span><%- description %></span>
40+
</div>
41+
<div class="div-space-edit">
42+
<div class="txt-help">Description: </div>
43+
<textarea class="form-control" id="desc" value="<%- description %>" placeholder="Description"><%- description %></textarea>
44+
</div>
45+
<div class="ctrl">
46+
<div class="pull-left">
47+
<button class="b-delete btn btn-primary">Delete</button>
48+
</div>
49+
<div class="pull-right">
50+
<!-- <button class="b-edit btn btn-primary">Edit</button> -->
51+
<button class="b-cancel btn btn-primary">Cancel</button>
52+
<button class="b-update btn btn-primary">Update</button>
53+
</div>
54+
</div>
55+
</div>
56+
</div> <!-- /row -->
57+
</div> <!-- /container -->
58+
</div> <!-- /vertical-center -->
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
var Backbone = require('../vendor/index').Backbone;
4+
5+
module.exports = Backbone.Model.extend({
6+
7+
defaults: {
8+
title: 'JavaScript Is Sexy',
9+
resourceType: 'link',
10+
description: 'Learn JavaScript properly.',
11+
authors: ['Mom', 'Dad']
12+
},
13+
14+
urlRoot: '/api/learning-resources',
15+
16+
initialize: function(){
17+
this.on('change', function(){
18+
this.trigger('foo', 'bar');
19+
});
20+
},
21+
22+
validate: function(attrs){
23+
24+
if (!attrs.title) {
25+
return 'Title cannot be empty';
26+
}
27+
if (!attrs.description) {
28+
return 'Description cannot be empty';
29+
}
30+
if (!attrs.authors) {
31+
return 'Authors cannot be empty';
32+
}
33+
}
34+
});
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
'use strict';
2+
3+
var Backbone = require('../vendor/index').Backbone;
4+
var _ = require('../vendor/index')._;
5+
var $ = require('../vendor/index').$;
6+
7+
var fs = require('fs'); //will be replaced by brfs in the browser
8+
9+
// readFileSync will be evaluated statically so errors can't be caught
10+
var template = fs.readFileSync(__dirname + '/learning-resources.html', 'utf8');
11+
12+
module.exports = Backbone.View.extend({
13+
14+
className: 'learning-resource',
15+
16+
template: _.template(template),
17+
18+
events: {
19+
'click .b-delete': 'destroy',
20+
'click .b-edit': 'edit',
21+
'click .b-cancel': 'cancel',
22+
'click .b-update': 'save'
23+
},
24+
25+
initialize: function(){
26+
this.listenTo(this.model, 'destroy', this.remove);
27+
this.listenTo(this.model, 'change', this.render);
28+
},
29+
30+
edit: function(){
31+
var resource = this.model.get('resourceType');
32+
this.$el.addClass('editing'); //displays input fields
33+
$('#form-area').addClass('sty-form'); //add bg color of form
34+
},
35+
36+
cancel: function(){
37+
this.$('#title').val(this.model.get('title'));
38+
this.$('#desc').val(this.model.get('description'));
39+
this.$('#auth').val(this.model.get('authors'));
40+
this.$('select option[value="'+this.model.get('resourceType')+'"]')
41+
.attr('selected','selected');
42+
$('#form-area').removeClass('sty-form'); //remove bg color of form
43+
$('#msg').empty()
44+
.addClass('alert-warning')
45+
.html('Changes cancelled')
46+
.fadeIn().delay(2000).fadeOut('slow')
47+
.queue(function(remove){
48+
$('#msg').removeClass('alert-warning');
49+
remove();
50+
});
51+
this.$el.removeClass('editing');
52+
},
53+
54+
save: function(){
55+
var view = this;
56+
var auth = [];
57+
if (this.$('#auth').val() === '') auth = null;
58+
else $.each(this.$('#auth').val().split(','), function(){
59+
auth.push($.trim(this));
60+
});
61+
var attributes = {
62+
title: this.$('#title').val().trim(),
63+
resourceType: $('#resourceType option:selected').val(),
64+
description: this.$('#desc').val().trim(),
65+
authors: auth
66+
};
67+
var options = {
68+
success: function(){
69+
$('#form-area').removeClass('sty-form');
70+
view.$el.removeClass('editing');
71+
$('#msg').empty()
72+
.addClass('alert-success')
73+
.html('Sucessfully updated')
74+
.fadeIn().delay(2000).fadeOut('slow')
75+
.queue(function(remove){
76+
$('#msg').removeClass('alert-success');
77+
remove();
78+
});
79+
},
80+
error: function(model, error){
81+
//server response errors if no validations specified
82+
}
83+
};
84+
this.model.save(attributes, options);
85+
if (this.model.validationError) {
86+
$('#msg').empty()
87+
.addClass('alert-danger')
88+
.html(this.model.validationError)
89+
.fadeIn().delay(2000).fadeOut('slow')
90+
.queue(function(remove){
91+
$('#msg').removeClass('alert-danger');
92+
remove();
93+
});
94+
}
95+
},
96+
97+
render: function(){
98+
var context = this.model.toJSON();
99+
var auth = this.model.get('authors').toString().split(',').join(', ');
100+
this.$el.html(this.template(context));
101+
this.input = this.$('.editing');
102+
this.$('select option[value="'+this.model.get('resourceType')+'"]')
103+
.attr('selected','selected');
104+
this.$('#auth').val(auth);
105+
this.$('#author-dsp').text(auth);
106+
return this;
107+
},
108+
109+
destroy: function(){
110+
this.model.destroy();
111+
this.remove();
112+
}
113+
});

0 commit comments

Comments
 (0)