Created
March 13, 2012 23:38
-
-
Save carpeliam/3eb37fbb4a4b720f0537 to your computer and use it in GitHub Desktop.
super-sexy model binding for a collection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ProjectPages.Views.Projects ||= {} | |
class ProjectPages.Views.Projects.KeyMilestoneView extends Backbone.View | |
templates: | |
show: JST["backbone/templates/projects/key_milestones/show"] | |
edit: JST["backbone/templates/projects/key_milestones/edit"] | |
form: JST['backbone/templates/projects/key_milestones/_form'] | |
modalHeader: JST["backbone/templates/shared/modal/header"] | |
modalFooter: JST["backbone/templates/shared/modal/footer"] | |
events: | |
'click .edit': 'edit' | |
'click .add-link': 'addMilestone' | |
'submit': 'save' | |
'hidden .modal': 'removeEdit' | |
edit: (e) -> | |
dialog = $(@make('form', id: 'editSidebarDialog', class: 'modal fade')). | |
append(@templates.modalHeader(title: 'Edit Key Milestones')). | |
append(@templates.edit()). | |
append(@templates.modalFooter()) | |
body = dialog.find('tbody') | |
## AWESOME PART #2 (look down at #1 first): appends bound markup to the page | |
@collection.each (km, i) => body.append @bindModelToTemplate(@templates.form, km, i) | |
dialog.find('.add-link:not(:last)').hide() | |
dialog.appendTo(@$el).modal() | |
e.preventDefault() | |
removeEdit: (e) -> | |
@$('#editSidebarDialog').remove() | |
e.preventDefault() | |
## AWESOME PART #1: takes a template function, model, and index. applies the model to the template, | |
## looks through the resulting markup and binds the model and the fragment together. | |
## returns fragment back to caller, ready to be appended to the page. | |
bindModelToTemplate: (template, model, index=new Date().getTime()) -> | |
expr = new RegExp("#{model.collection.relationship}_attributes\\[#{index}\\]\\[([^\\]]+)\\]") | |
fragment = $(template(km: model, index: index)) | |
fragment.find(':input').each -> | |
if result = $(@).attr('name').match(expr) | |
field = result[1] # result[0] == the whole match, which is the name attr itself | |
model.bind "change:#{field}", => $(@).val(model.get(field)) | |
$(@).bind 'change', -> | |
attrs = {}; attrs[field] = $(@).val() | |
model.set(attrs) | |
return fragment | |
addMilestone: (e) -> | |
addLink = $(e.target) | |
body = addLink.closest('tbody') | |
## AWESOME PART #2.5 does same thing as AWESOME PART #2, but with default timestamp | |
body.append @bindModelToTemplate(@templates.form, new ProjectPages.Models.ProjectChild) | |
addLink.remove() | |
e.preventDefault() | |
save: (e) -> | |
# magic happens, a miracle occurs, then... | |
console.log 'serializeArray()', @$('form').serializeArray() | |
data = _(@$('form').serializeArray()).reduce (set, h) -> | |
set[h.name] = h.value | |
set | |
, {} | |
console.log 'reduction', data | |
# @collection.save() | |
@$('#editSidebarDialog').modal('hide') | |
e.preventDefault() | |
render: -> | |
$('.box', @$el).html @templates.show(keyMilestones: @collection) | |
return this | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment