Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
129
rated 0 times [  133] [ 4]  / answers: 1 / hits: 16242  / 13 Years ago, tue, january 10, 2012, 12:00:00

I am attempting to create a Backbone.js view based on a Twitter bootstrap-modal, which makes use of Backbone's automatic event delegation via the events attribute of the view.



Unfortunately, bootstrap-modal seems to break Backbone's event delegation as it clones the view HTML before displaying the modal:



that.$element
.appendTo(document.body)
.show()


My view:



App.Views.ProjectsNav ||= {}

class App.Views.ProjectsNav.NewProjectView extends Backbone.View
events: {
'click .save': 'save',
'shown': 'shown'
}

save: (e) ->
...
false

shown: () ->
App.Helpers.Forms.setFocus($(@el), true)
false

render: () ->
$(@el).html(ich.nav_edit_project_template(@model.toJSON()))
@$('.modal').modal({'show': true, 'keyboard': true, 'backdrop': true})
@


The corresponding (Mustache) HTML template:



<div class=modal hide style=display: none; >
<div class=modal-header>
<a href=# class=close>×</a>
<h3>New Project</h3>
</div>
<div class=modal-body form-stacked>
<label for=name>Name</label> <input type=text name=name value={{name}}/><input type=hidden name=lock_version value={{lock_version}}/>
</div>
<div class=modal-footer>
<a href=javascript:void(0) class=save btn primary>Create</a>
<a href=javascript:void(0) class=cancel btn secondary>Cancel</a>
</div>
</div>


Neither save nor shown are called when the respective events are triggered.



Any ideas?


More From » backbone.js

 Answers
20

Allright, so the solution is was rather simple:



App.Views.ProjectsNav ||= {}

class App.Views.ProjectsNav.NewProjectView extends Backbone.View
tagName: 'div'

events: {
'click .save': 'save',
'click .cancel': 'hide',
'hidden': 'hidden',
'shown': 'shown'
}

initialize: (options) ->
super(options)
@collection = options.collection

hide: () ->
@el.modal(true).hide()
false

save: (e) ->
...
@model.save(attrs, {
success: (project) =>
@model = project
@collection.add(@model)
@hide()
error: (project) =>
alert('Something went wrong: ' + project)
}
)
false

render: () ->
@el = ich.nav_edit_project_template(@model.toJSON()).modal('keyboard': true, 'backdrop': true)
@delegateEvents()
@el.modal('show': true)
@

hidden: () ->
@remove()
false

shown: () ->
App.Helpers.Forms.setFocus($(@el), true)
false


Summing things up, the key is to split showing the modal into two steps giving the possibility to assign @el and invoke @delegateEvents() afterwards before making it visible. @el.modal(true) can be used to get access to the object controlling the modal, e.g., to programmatically hide it.


[#88096] Tuesday, January 10, 2012, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
kaylea

Total Points: 459
Total Questions: 97
Total Answers: 106

Location: Denmark
Member since Wed, Aug 26, 2020
4 Years ago
;