Trying a view for user, timeline(s), entry(ies).
This commit is contained in:
parent
aec172536e
commit
9025a2f8f6
Binary file not shown.
Binary file not shown.
@ -64,17 +64,28 @@ body {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
right: 0; }
|
right: 0; }
|
||||||
|
|
||||||
#entries {
|
#new-entry {
|
||||||
margin-top: 5.5em;
|
margin-top: 5.5em;
|
||||||
padding: 0.5em 0.5em; }
|
padding: 0.5em 0.5em; }
|
||||||
#entries .mark-input, #entries .timestamp-input {
|
#new-entry .mark-input, #new-entry .timestamp-input {
|
||||||
border: solid thin #555555;
|
border: solid thin #555555;
|
||||||
-webkit-box-shadow: inset 0px 2px 4px #CCC;
|
-webkit-box-shadow: inset 0px 2px 4px #CCC;
|
||||||
box-shadow: inset 0px 2px 4px #CCC;
|
box-shadow: inset 0px 2px 4px #CCC;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
font-family: Cantarell; }
|
font-family: Cantarell; }
|
||||||
#entries .mark-input {
|
#new-entry .mark-input {
|
||||||
width: 78%; }
|
width: 78%; }
|
||||||
|
#new-entry .edit-mark .mark-input {
|
||||||
|
display: inline-block; }
|
||||||
|
#new-entry .edit-mark .mark {
|
||||||
|
display: none; }
|
||||||
|
#new-entry .edit-timestamp .timestamp-input {
|
||||||
|
display: inline-block; }
|
||||||
|
#new-entry .edit-timestamp .timestamp {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
|
#entries {
|
||||||
|
padding: 0.5em 0.5em; }
|
||||||
#entries .entry {
|
#entries .entry {
|
||||||
font-family: Cantarell; }
|
font-family: Cantarell; }
|
||||||
#entries .entry div {
|
#entries .entry div {
|
||||||
@ -89,14 +100,6 @@ body {
|
|||||||
display: none; }
|
display: none; }
|
||||||
#entries .entry .notes {
|
#entries .entry .notes {
|
||||||
display: none; }
|
display: none; }
|
||||||
#entries .edit-mark .mark-input {
|
|
||||||
display: inline-block; }
|
|
||||||
#entries .edit-mark .mark {
|
|
||||||
display: none; }
|
|
||||||
#entries .edit-timestamp .timestamp-input {
|
|
||||||
display: inline-block; }
|
|
||||||
#entries .edit-timestamp .timestamp {
|
|
||||||
display: none; }
|
|
||||||
|
|
||||||
.drop-menu {
|
.drop-menu {
|
||||||
position: relative; }
|
position: relative; }
|
||||||
|
@ -95,8 +95,7 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#entries {
|
#new-entry {
|
||||||
|
|
||||||
margin-top: 5.5em;
|
margin-top: 5.5em;
|
||||||
padding: 0.5em 0.5em;
|
padding: 0.5em 0.5em;
|
||||||
|
|
||||||
@ -110,6 +109,21 @@ body {
|
|||||||
|
|
||||||
.mark-input { width: 78%; }
|
.mark-input { width: 78%; }
|
||||||
|
|
||||||
|
.edit-mark {
|
||||||
|
.mark-input { display: inline-block; }
|
||||||
|
.mark { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-timestamp {
|
||||||
|
.timestamp-input { display: inline-block; }
|
||||||
|
.timestamp { display: none; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#entries {
|
||||||
|
|
||||||
|
padding: 0.5em 0.5em;
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
|
|
||||||
font-family: Cantarell;
|
font-family: Cantarell;
|
||||||
@ -128,15 +142,6 @@ body {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-mark {
|
|
||||||
.mark-input { display: inline-block; }
|
|
||||||
.mark { display: none; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-timestamp {
|
|
||||||
.timestamp-input { display: inline-block; }
|
|
||||||
.timestamp { display: none; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.drop-menu {
|
.drop-menu {
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
<script type="text/javascript" src="js/ts.js"></script>
|
<script type="text/javascript" src="js/ts.js"></script>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
|
|
||||||
|
<script id="timelineLink" type="test/html">
|
||||||
|
<li><a href="#">{{id}}</a></li>
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -52,11 +55,12 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="entries">
|
|
||||||
<div id="new-entry">
|
<div id="new-entry">
|
||||||
<input id="new-entry-input" class="mark-input"
|
<input id="new-entry-input" class="mark-input"
|
||||||
placeholder="Start a new task..." type="text" />
|
placeholder="Start a new task..." type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="entries">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<div class="mark">ITHelp: Entering tickets.</div>
|
<div class="mark">ITHelp: Entering tickets.</div>
|
||||||
<input class="mark-input" type="text"/>
|
<input class="mark-input" type="text"/>
|
||||||
|
@ -3,7 +3,15 @@ var Test = {};
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
Test.U = Backbone.Model.extend({
|
Test.U = Backbone.Model.extend({
|
||||||
url: '/ts_api/users'
|
url: '/ts_api/users',
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.timelines = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Test.E = Backbone.Model.extend({
|
||||||
|
url: '/ts_api/entries/jdbernard/work'
|
||||||
});
|
});
|
||||||
|
|
||||||
Test.UView = Backbone.View.extend({
|
Test.UView = Backbone.View.extend({
|
||||||
@ -18,9 +26,59 @@ $(document).ready(function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var user = this.model.get('user');
|
this.$('.fullname').text(this.model.get('name'));
|
||||||
this.$('.fullname').text(user.name);
|
this.$('.username').text(this.model.get('id'));
|
||||||
this.$('.username').text(user.username);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Test.EList = Backbone.Collection.extend({
|
||||||
|
model: Test.E,
|
||||||
|
|
||||||
|
url: '/ts_api/entries/jdbernard/work',
|
||||||
|
|
||||||
|
initalize: function(models, options) {
|
||||||
|
this.user = options.user;
|
||||||
|
},
|
||||||
|
|
||||||
|
comparator: function(entry) {
|
||||||
|
return entry.get('timestamp');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Test.EView = Backbone.View.extend({
|
||||||
|
|
||||||
|
model: Test.E,
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'render');
|
||||||
|
this.model.bind('change', this.render);
|
||||||
|
this.model.view = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
$(this.el).html("<span class='entry-id'>" + this.model.get('id') + "<span class='mark'>" + this.model.get('mark') + "</span>");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Test.EListView = Backbone.View.extend({
|
||||||
|
el: $("#entry-list"),
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'render', 'refresh', 'addOne');
|
||||||
|
|
||||||
|
this.collection.bind('add', this.addOne);
|
||||||
|
this.collection.bind('refresh', this.refresh);
|
||||||
|
},
|
||||||
|
|
||||||
|
addOne: function(entry) {
|
||||||
|
var view = new Test.EView({model: entry});
|
||||||
|
$(this.el).append(view.render().el);
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function() {
|
||||||
|
$(this.el).empty();
|
||||||
|
var thisRef = this;
|
||||||
|
this.collection.each(function(entry) {thisRef.addOne(entry)});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,5 +123,9 @@ function login() {
|
|||||||
$("#login-dialog").dialog('close');
|
$("#login-dialog").dialog('close');
|
||||||
Test.currentUser.set({id: name.val()}, {silent: true});
|
Test.currentUser.set({id: name.val()}, {silent: true});
|
||||||
Test.currentUser.fetch();
|
Test.currentUser.fetch();
|
||||||
|
|
||||||
|
Test.currentEntryList = Test.currentUser.timelines['work'] = new Test.EList([], {user: Test.currentUser});
|
||||||
|
new Test.EListView({collection: Test.currentEntryList});
|
||||||
|
Test.currentEntryList.fetch();
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
138
www/js/ts.js
138
www/js/ts.js
@ -13,7 +13,7 @@ $(document).ready(function(){
|
|||||||
* - notes
|
* - notes
|
||||||
* - start
|
* - start
|
||||||
*/
|
*/
|
||||||
TS.Entry = Backbone.Model.extend({
|
TS.EntryModel = Backbone.Model.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ $(document).ready(function(){
|
|||||||
* - desc
|
* - desc
|
||||||
* - created
|
* - created
|
||||||
*/
|
*/
|
||||||
TS.Timeline = Backbone.Model.extend({
|
TS.TimelineModel = Backbone.Model.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -34,29 +34,41 @@ $(document).ready(function(){
|
|||||||
* - email
|
* - email
|
||||||
* - join_date
|
* - join_date
|
||||||
*/
|
*/
|
||||||
TS.User = Backbone.Model.extend({
|
TS.UserModel = Backbone.Model.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
TS.EntryList = Backbone.Collection.extend({
|
TS.EntryList = Backbone.Collection.extend({
|
||||||
model: TS.Entry,
|
model: TS.EntryModel,
|
||||||
|
|
||||||
comparator: function(entry) { return entry.get('timestamp'); },
|
comparator: function(entry) { return entry.get('timestamp'); },
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function(model, options) {
|
||||||
_.bindAll(this, "ur");
|
if (options.timeline == undefined) {
|
||||||
|
throw "Cannot create an EntryList without a TimelineModel reference."
|
||||||
|
} else { this.timeline = options.timeline; }
|
||||||
|
|
||||||
|
_.bindAll(this, "url");
|
||||||
},
|
},
|
||||||
|
|
||||||
url: function() {
|
url: function() {
|
||||||
return "/entries/" + TS.currentUser.get('username') + "/" + this.timeline.get('id');
|
return "/entries/" + this.timeline.get('user_id') + "/" + this.timeline.get('id');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TS.TimelineList = Backbone.Collection.extend({
|
TS.TimelineList = Backbone.Collection.extend({
|
||||||
model: TS.Timeline,
|
model: TS.TimelineModel,
|
||||||
|
|
||||||
|
initialize: function(models, options) {
|
||||||
|
if (options.user == undefined) {
|
||||||
|
throw "Cannot create a TimelineList without a UserModel reference.";
|
||||||
|
} else { this.user = options.user; }
|
||||||
|
|
||||||
|
_.bindAll(this, 'url');
|
||||||
|
},
|
||||||
|
|
||||||
url: function() {
|
url: function() {
|
||||||
return "/timelines/" + TS.currentUser.get('username');
|
return "/ts_api/timelines/" + this.user.get('id');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -67,7 +79,7 @@ $(document).ready(function(){
|
|||||||
*/
|
*/
|
||||||
TS.EntryView = Backbone.View.extend({
|
TS.EntryView = Backbone.View.extend({
|
||||||
|
|
||||||
model: TS.Entry,
|
model: TS.EntryModel,
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"dblclick div.mark" : "editMark",
|
"dblclick div.mark" : "editMark",
|
||||||
@ -111,11 +123,32 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TS.EntryListView = Backbone.View.extend({
|
||||||
|
|
||||||
|
el: $("#entries"),
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'addOne', 'render');
|
||||||
|
this.collection.bind('add', this.addOne);
|
||||||
|
this.collection.bind('refresh', this.render);
|
||||||
|
this.collection.view = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
addOne: function(entry) {
|
||||||
|
$(this.el).append(entry.view.render().el);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
$(this.el).empty();
|
||||||
|
this.collection.each(this.addOne);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
TS.TimelineView = Backbone.View.extend({
|
TS.TimelineView = Backbone.View.extend({
|
||||||
|
|
||||||
el: $("#timeline"),
|
el: $("#timeline"),
|
||||||
|
|
||||||
model: TS.Timeline,
|
model: TS.TimelineModel,
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"dblclick .timeline-id" : "editId",
|
"dblclick .timeline-id" : "editId",
|
||||||
@ -125,7 +158,8 @@ $(document).ready(function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
_.bindAll(this, 'render', 'close');
|
_.bindAll(this, 'render', 'close', 'editId', 'editDesc',
|
||||||
|
'updateOnEnter');
|
||||||
this.model.bind('change', this.render);
|
this.model.bind('change', this.render);
|
||||||
this.model.view = this;
|
this.model.view = this;
|
||||||
},
|
},
|
||||||
@ -161,11 +195,42 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TS.TimelineListView = Backbone.View.extend({
|
||||||
|
|
||||||
|
el: $("#timeline .drop-menu-items"),
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click #timeline .drop-menu-items a': 'selectTimeline'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
_.bindAll(this, 'addOne', 'render');
|
||||||
|
this.collection.bind('add', this.addOne);
|
||||||
|
this.collection.bind('refresh', this.refresh);
|
||||||
|
this.collection.view = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
addOne: function(timeline) {
|
||||||
|
$(this.el).append(ich.timelineLink(timeline.toJSON()));
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
$(this.el).empty();
|
||||||
|
this.collection.each(this.addOne);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
selectTimeline: function() {
|
||||||
|
// note that this refers to the element that initiated this event
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
TS.UserView = Backbone.View.extend({
|
TS.UserView = Backbone.View.extend({
|
||||||
|
|
||||||
el: $("user"),
|
el: $("user"),
|
||||||
|
|
||||||
model: TS.User,
|
model: TS.UserModel,
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'dblclick .fullname': 'editFullname',
|
'dblclick .fullname': 'editFullname',
|
||||||
@ -173,7 +238,7 @@ $(document).ready(function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
_.bindAll(this, 'render', 'close');
|
_.bindAll(this, 'render', 'close', 'editFullname', 'updateOnEnter');
|
||||||
this.model.bind('change', this.render);
|
this.model.bind('change', this.render);
|
||||||
this.model.view = this;
|
this.model.view = this;
|
||||||
},
|
},
|
||||||
@ -181,6 +246,7 @@ $(document).ready(function(){
|
|||||||
render: function() {
|
render: function() {
|
||||||
this.$('.fullname').text(this.model.get('name'));
|
this.$('.fullname').text(this.model.get('name'));
|
||||||
this.$('.username').text(this.model.get('id'));
|
this.$('.username').text(this.model.get('id'));
|
||||||
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
editFullname: function() {
|
editFullname: function() {
|
||||||
@ -200,13 +266,6 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TS.currentUser = {};
|
|
||||||
TS.currentUser.model = new TS.User({
|
|
||||||
id: $("#user .username").text(),
|
|
||||||
name: $("#user .fullname").text() });
|
|
||||||
|
|
||||||
TS.currentUser.view = new TS.UserView(TS.currentUser.model);
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function login() {
|
function login() {
|
||||||
@ -231,6 +290,41 @@ function login() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
success: function(data, textStatus, jqXHR) {
|
success: function(data, textStatus, jqXHR) {
|
||||||
TS.currentUser = new TS.User(); // TODO
|
|
||||||
|
// initialize the app data
|
||||||
|
// TODO: possiblty replace by script generated server-side
|
||||||
|
|
||||||
|
// create the user model
|
||||||
|
TS.user = new TS.UserModel({
|
||||||
|
id: name.val();,
|
||||||
|
name: '' });
|
||||||
|
|
||||||
|
// create the user view
|
||||||
|
new TS.UserView({model: TS.user});
|
||||||
|
|
||||||
|
// fetch the initial user data from the server
|
||||||
|
TS.user.fetch();
|
||||||
|
|
||||||
|
// create the user's timelines
|
||||||
|
TS.timelineList = new TS.TimelineList([], {user: TS.user});
|
||||||
|
|
||||||
|
// create the timeline list view
|
||||||
|
new TS.TimelineListView({collection: TS.timelineList});
|
||||||
|
TS.timelineList.fetch();
|
||||||
|
|
||||||
|
// load the current timeline
|
||||||
|
TS.currentTimeline = TS.timelineList.at(0);
|
||||||
|
|
||||||
|
// create the timeline view
|
||||||
|
new TS.TimelineView({model: TS.currentTimeline});
|
||||||
|
|
||||||
|
// render the timeline view
|
||||||
|
TS.currentTimeline.view.render();
|
||||||
|
|
||||||
|
// load the entries for this timeline
|
||||||
|
TS.entryList = new TS.EntryList([], {timeline: TS.currentTimeline});
|
||||||
|
|
||||||
|
// create the new entry list view
|
||||||
|
new TS.EntryListView
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Testing Backbone.js</title>
|
<title>Testing Backbone.js</title>
|
||||||
<link rel="stylesheet" media="screen" href="css/dot-luv/jquery-ui-1.8.10.custom.css" type="text/css"/>
|
<link rel="stylesheet" media="screen" href="/css/dot-luv/jquery-ui-1.8.10.custom.css" type="text/css"/>
|
||||||
<script type="text/javascript" src="/js/jquery-1.5.min.js"></script>
|
<script type="text/javascript" src="/js/jquery-1.5.min.js"></script>
|
||||||
<script type="text/javascript" src="/js/jquery-ui-1.8.10.custom.min.js"></script>
|
<script type="text/javascript" src="/js/jquery-ui-1.8.10.custom.min.js"></script>
|
||||||
<script type="text/javascript" src="/js/underscore-min.js"></script>
|
<script type="text/javascript" src="/js/underscore-min.js"></script>
|
||||||
@ -17,6 +17,8 @@
|
|||||||
<div class="fullname">fullname</div>
|
<div class="fullname">fullname</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="entry-list"></div>
|
||||||
|
|
||||||
<div id="login-dialog" title="Login">
|
<div id="login-dialog" title="Login">
|
||||||
<form>
|
<form>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user