Skip to content

Instantly share code, notes, and snippets.

@runvnc
Created January 31, 2012 08:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save runvnc/1709495 to your computer and use it in GitHub Desktop.
Save runvnc/1709495 to your computer and use it in GitHub Desktop.
connectWith not working?
$(function(){
storiespos = window.location.href.indexOf('stories');
if (storiespos < 0) return;
//The router runs whenever the URL changes.
//Either the user changes it or I call navigate()
//For now I am using hash tags but this also works with regular URLs
//without the # now in HTML 5
var AppRouter = Backbone.Router.extend({
initialize: function() {
//storiesView = new StoriesView({el: $('#stories')});
sprintView = new SprintView({el: $('#stories')});
editStoryView = new StoryEditView({el: $('#main'), model: undefined});
window.editStoryView = editStoryView;
//Handles the list of stories as well as display story edit form
},
routes: {
"list" : "allStories", //list of stories
"editstory/:cid": "editStory",
"*actions": "defaultRoute" // Backbone will try match the route above first
},
allStories: function () {
sprintView.render();
},
editStory: function(cid) {
var story = Stories.getByCid(cid);
if (typeof story == 'undefined') {
story = Stories.get(cid);
}
if (typeof story == 'undefined') {
var s = this;
Stories.fetch({success: function() {
s.editStory(cid);
}});
} else {
//There won't be an id if this is a new record
//but there will be a cid from backbone
editStoryView.model = story;
editStoryView.initialize();
editStoryView.render();
$('#main').show();
}
},
defaultRoute: function( actions ){
console.log('Default route');
console.log( actions );
}
});
window.Story = Backbone.Model.extend({
// Remove this Story, deleting its view.
clear: function() {
this.destroy();
//$(this.view.el).dispose();
}
});
window.CustomField = Backbone.Model.extend({
});
window.CustomFieldList = Backbone.Collection.extend({
model: CustomField,
storage: new Store('customdata', 0)
});
//Display custom field and value on
//the story edit/details view
window.CustomFieldView = Backbone.View.extend({
tagName: "li",
classname: "custom",
template: _.template($('#customfield').html()),
events: {
"click .fieldvalue" : "editVal",
"click .fieldname" : "editName",
},
initialize : function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.setContent();
return this;
},
setInput: function(selector, isInput) {
if (isInput) {
this.$(selector+'-input').show().focus();
this.$(selector).hide();
} else {
this.$(selector+'-input').hide();
this.$(selector).show();
}
},
editName: function(ev) {
this.setInput('#'+ev.target.id, true);
},
editVal: function(ev) {
this.setInput('#'+ev.target.id, true);
},
collectData: function() {
var data = {};
data.parentId = window.currentFieldsView.parentView.getId();
data.fieldname = this.$('.fieldname-input').val();
data.fieldvalue = this.$('.fieldvalue-input').val();
return data;
},
save: function() {
var data = this.collectData();
if (data.fieldname == '' && data.fieldvalue == '') {
//not saving blank custom data rows
} else {
this.model.save(data);
}
},
setContent: function() {
var fname = this.model.get('fieldname');
this.$('.fieldname').html(fname);
this.$('.fieldname').attr('id', 'name-' + this.model.id);
this.$('.fieldname-input').attr('id', 'name-' + this.model.id+'-input');
this.$('.fieldname-input').val(fname);
if (fname == '') {
this.setInput('#name-'+this.model.id, true);
} else {
this.setInput('#name-'+this.model.id, false);
}
var fval = this.model.get('fieldvalue');
this.$('.fieldvalue').html(fval);
this.$('.fieldvalue').attr('id', 'val-' + this.model.id);
this.$('.fieldvalue-input').attr('id', 'val-' + this.model.id+'-input');
this.$('.fieldvalue-input').val(fval);
if (fval == '') {
this.setInput('#val-'+this.model.id, true);
} else {
this.setInput('#val-'+this.model.id, false);
}
}
});
window.FieldListView = Backbone.View.extend({
events: {
//"click #btncustom" : "create"
},
template: _.template($('#story-fields').html()),
//When a field is added to the FieldList collection
//automatically calls add
initialize: function() {
this.fieldViews = [];
if (this.collection) {
this.fieldViews = [];
this.collection.bind('add', this.addOne);
this.collection.bind('refresh', this.addAll);
}
},
render: function() {
$(this.el).html(this.template());
window.currentFieldsView = this;
this.collection.storage.parentId = this.parentView.getId();
var s = this;
this.$('#btncustom').click(function() { s.create(s)} );
var s = this;
this.collection.fetch({success: function() {
s.addAll();
}});
},
addOne: function(field) {
var view = new CustomFieldView({model: field });
$('#fieldlist').append(view.render().el);
window.currentFieldsView.fieldViews.push(view);
},
addAll: function() {
$('#fieldlist').html('');
this.collection.each(this.addOne);
},
create: function(s) {
s.collection.create({
parentId: s.parentView.getId(),
fieldname: '',
fieldvalue: ''
});
},
saveAll: function() {
_.each(this.fieldViews, function(view) {
view.save();
});
}
});
//Currently shows this list of stories first
window.StoryList = Backbone.Collection.extend({
model: Story,
storage: new Store("stories"),
byStatus: function(statusId) {
return _(this.filter(function(data) {
return data.get('status') == statusId;
}));
}
});
window.Stories = new StoryList;
window.Attachment = Backbone.Model.extend({
});
window.FileList = Backbone.Collection.extend({
model: Attachment,
storage: new Store('attachments', 0)
});
//Display an individual file
window.AttachmentView = Backbone.View.extend({
tagName: "li",
classname: "storyfile",
template: _.template($('#story-file').html()),
events: {
},
initialize : function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.setContent();
return this;
},
setContent: function() {
var fname = this.model.get('filename');
var parentId = this.model.get('parentId');
var link = '<a target="_blank" href="/attachments/'+encodeURIComponent(parentId);
link += '_' + encodeURIComponent(fname) + '">' + fname + '</a>';
this.$('.story-filename').html(link);
}
});
window.FileListView = Backbone.View.extend({
events: {
"click #btn-upload" : "startUpload"
},
template: _.template($('#attachments').html()),
//When a file is added to the FileList collection
//automatically calls add
initialize: function() {
window.currentFilesView = this;
if (this.collection) {
this.collection.bind('add', this.addOne);
this.collection.bind('refresh', this.addAll);
}
},
setFiles: function(files) {
for (var i=0; i<files.length; i++) {
var file = files[i];
this.collection.storage.parentId = window.currentFilesView.parentView.getId();
this.collection.create( { parentId: window.currentFilesView.parentView.getId(), filename: file.name,
mimetype: '' } );
}
},
startUpload: function() {
var id = window.currentFilesView.parentView.getId();
$('#upload').contents().find('#parentRecord').val(id);
$('#upload').contents().find('#filesinput').trigger('click');
},
render: function() {
$(this.el).html(this.template());
this.$('#btn-upload').click(this.startUpload);
var s = this;
this.collection.fetch({success: function() {
s.addAll();
}});
},
addOne: function(attachment) {
var view = new AttachmentView({model: attachment });
$('#files-list').append(view.render().el);
},
addAll: function() {
$('#files-list').html('');
this.collection.each(this.addOne);
}
});
//This is the main data entry form for a story
//Backbone views are actually like controllers
window.StoryEditView = Backbone.View.extend({
tagName: "div",
className: "storyedit",
template: _.template($('#story-edit').html()),
events: {
"click #story-save" : "close",
"click #story-edit-title" : "editTitle",
"click #story-edit-description" : "editDescription",
"click #story-edit-points" : "editPoints",
"keypress .story-edit-title-input" : "updateOnEnter",
"hover #story-edit-title" : "highlightTitle",
"hover #story-edit-description" : "highlightDescription"
},
initialize: function() {
if (!this.model) return; //router initialize makes a view without a model
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
this.files = new FileList;
this.files.storage.parentId = this.model.id;
this.fileListView = new FileListView({el: this.$('#story-attachments')[0], collection: this.files});
this.fileListView.parentView = this;
this.customFields = new CustomFieldList;
this.customFields.storage.parentId = this.model.id;
this.customFieldListView = new FieldListView({el: this.$('#field-list')[0], collection: this.customFields});
this.customFieldListView.parentView = this;
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.setContent();
this.fileListView.el = this.$('#story-attachments')[0];
this.fileListView.render();
this.customFieldListView.el = this.$('#field-list')[0];
this.customFieldListView.render();
return this;
},
getId: function() {
return this.model.id;
},
setInput: function(selector, isInput) {
if (isInput) {
$(selector+'-input').show().focus();
$(selector).hide();
} else {
$(selector+'-input').hide();
$(selector).show();
}
},
//Show all of the data from the model in
//the DOM
setContent: function() {
var title = this.model.get('title');
this.$('#story-edit-title').html(title);
this.$('#story-edit-title-input').val(title);
if (typeof(title)=='undefined' || !title || title=='') {
this.setInput('#story-edit-title', true);
this.setInput('#story-edit-points', true);
this.setInput('#story-edit-description', true);
$('#story-edit-title-input').focus();
} else {
}
var description = this.model.get('description');
if (typeof(description)=='undefined' || !description || description=='') {
this.setInput('#story-edit-description', true);
}
this.$('#story-edit-description').html(description);
this.$('#story-edit-description-input').val(description);
var points = this.model.get('points');
if (typeof(points)=='undefined' || !points || points==0 || points=='') {
this.setInput('#story-edit-points', true);
}
this.$('#story-edit-points').html(points);
this.$('#story-edit-points-input').val(points);
this.$('#select-status').val(this.model.get('status'));
this.$('#select-flag').val(this.model.get('flag'));
this.$('#story-edit-order-input').val(this.model.get('order'));
},
highlightTitle: function(ev) {
if (ev.type == 'mouseenter') {
this.$('#story-edit-title').css('border','1px solid #003DF5');
} else {
this.$('#story-edit-title').css('border','1px solid #fff');
}
},
highlightDescription: function(ev) {
if (ev.type == 'mouseenter') {
this.$('#story-edit-description').css('border','1px solid #003DF5');
} else {
this.$('#story-edit-description').css('border','1px solid #fff');
}
},
editTitle: function() {
this.setInput('#story-edit-title', true);
},
editDescription: function() {
this.setInput('#story-edit-description', true);
},
editPoints: function() {
this.setInput('#story-edit-points', true);
},
edit: function() {
$(this.el).addClass("editing");
this.input.focus();
},
collectData: function() {
data = {};
data.title = this.$('#story-edit-title-input').val();
data.description = this.$('#story-edit-description-input').val();
data.points = this.$('#story-edit-points-input').val();
data.status = this.$('#select-status').val() * 1;
data.flag = this.$('#select-flag').val();
return data;
},
saveAll: function() {
var data = this.collectData();
this.model.save(data);
},
close: function() {
var data = this.collectData();
this.customFieldListView.saveAll();
this.model.save(data, { success: function() {
router.navigate('/list', true);
}});
},
// Remove this view from the DOM.
remove: function() {
$(this.el).remove();
},
updateOnEnter: function(e) {
if (e.code == 13) this.close();
},
clear: function() {
this.model.destroy();
}
});
//Individual row/item in the story list
window.StoryItemView = Backbone.View.extend({
tagName: "li",
className: "story",
template: _.template($('#story-item').html()),
//Backbone automatically wires these
events: {
"singleclick .story-item" : "editStory",
"dblclick .story-item-title" : "editTitle",
"blur .story-item-title-input" : "saveTitle",
"blur .story-item-points-input" : "savePoints",
"singleclick .story-item-points" : "editPoints",
"keypress .todo-input" : "updateOnEnter"
},
//Whenever the model changes, render this view again
initialize: function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
this.parentView = this.options.parentView;
//this.model.view = this;
},
setInput: function(selector, isInput) {
if (isInput) {
this.$(selector+'-input').show().focus().select();
this.$(selector).hide();
} else {
this.$(selector+'-input').hide();
this.$(selector).show();
}
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
//$(this.el).draggable();
this.setContent();
return this;
},
setContent: function() {
var title = this.model.get('title');
this.$('.story-item-title').html(title);
this.$('.story-item-title-input').val(title);
var points = this.model.get('points');
this.$('.story-item-points').html(points);
this.$('.story-item-points-input').val(points);
this.$('.story-item-points').css('background-color', this.parentView.color);
},
edit: function() {
$(this.el).addClass("editing");
this.input.focus();
},
editStory: function() {
router.navigate('/editstory/'+this.model.id, true);
},
editTitle: function(e) {
this.setInput('.story-item-title', true);
e.stopPropagation();
},
editPoints: function(e) {
this.setInput('.story-item-points', true);
e.stopPropagation();
},
saveTitle: function() {
this.model.save({title: this.$('.story-item-title-input').val()});
this.setInput('.story-item-title', false);
editStoryView.render();
},
savePoints: function() {
this.model.save({points: this.$('.story-item-points-input').val()});
this.setInput('.story-item-points', false);
editStoryView.render();
},
close: function() {
//this.model.save({content: this.input.getProperty("value")});
$(this.el).removeClass("editing");
},
updateOnEnter: function(e) {
if (e.code == 13) this.close();
},
// Remove this view from the DOM.
remove: function() {
$(this.el).remove();
},
clear: function() {
this.model.clear();
}
});
//List of stories with a particular Status
window.StoriesView = Backbone.View.extend({
events: {
},
template: _.template($('#status-column').html()),
//When a story is added to the Stories collection
//automatically calls add
initialize: function() {
this.status = this.options.status;
this.name = this.options.name;
this.color = this.options.color;
Stories.bind('add', this.addOne, this);
Stories.bind('refresh', this.addAll, this);
},
render: function() {
$(this.el).html(this.template());
this.setContent();
$('#stories').show();
this.addAll();
},
setContent: function() {
this.$('.status-heading').html(this.name);
this.$('.status-heading').css('background-color', this.color);
this.$('.story-item-points').css('background-color', this.color);
/* this.$('ul').sortable({
connectWith: '.stories-list'
}).disableSelection(); */
//$(this.el).disableSelection();
/*$( this.el ).droppable({
drop: function( event, ui ) {
console.log('Dropped');
console.log('event is ');
console.log(event);
console.log('ui is ');
console.log(ui);
}
});*/
},
//Edit story view in new mode (uses cid
//which is autogenerated)
addOne: function(story) {
if (router) {
router.navigate('/editstory/'+story.cid, true);
}
this.addOneItem(story);
},
addOneItem: function(story) {
if (this.location) return;
var view = new StoryItemView({model: story, parentView: this});
this.$(".stories-list").append(view.render().el);
},
addAll: function() {
this.$('.stories-list').html('');
Stories.byStatus(this.status).each(this.addOneItem, this);
},
create: function(s) {
Stories.create({
status: s.status * 1,
title: '',
description: '',
points: 2
});
}
});
//Main window shows 4 story lists by status and story edit
//for current sprint
window.SprintView = Backbone.View.extend({
events: {
"click #create-story" : "create"
},
initialize: function() {
this.rawView = new StoriesView({el: '#raw-stories', status: 1, color: '#ab1401', name: 'Raw'});
this.groomedView = new StoriesView({el: '#groomed-stories', status: 2, color: 'fdad00', name: 'Groomed'});
this.inProgressView = new StoriesView({el: '#inprogress-stories', status: 3, color: '6b8e00', name: 'In Progress'});
this.completedView = new StoriesView({el: '#completed-stories', status: 4, color: '02548e', name: 'Completed'});
var s = this;
Stories.fetch({success: function() { s.render(); }} );
},
render: function() {
$('#stories').show();
this.rawView.render();
this.groomedView.render();
this.inProgressView.render();
this.completedView.render();
$('.stories-list').css('border-color', 'blue');
$('.stories-list').css('border-style', 'solid');
$('#raw-stories ul, #groomed-stories ul, #completed-stories ul, #inprogress-stories ul').sortable({
connectWith: ['.stories-list'],
items: 'li'
}).disableSelection();
},
create: function(e) {
this.rawView.create(this.rawView);
}
});
var router = new AppRouter;
Backbone.history.start();
//Shows the stories list to start
router.navigate('/list', true);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment