Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support an existing 'events' function attribute #51

Merged
merged 1 commit into from
Jan 18, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions backbone.stickit.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@

this.unstickModel(model);

this.events || (this.events = {});
// this.events may be a function, but we want to add new event bindings
// to it. Creating our own stickitEvents property allows us to add
// bindings while allowing this.events to remain a function. This also
// supports multiple calls to stickit() in a single Backbone View.
this.stickitEvents = _(_.result(this, 'events') || {}).extend(
this.stickitEvents
);

// Iterate through the selectors in the bindings configuration and configure
// the various options for each field.
Expand Down Expand Up @@ -116,7 +122,7 @@
if (isFormEl($el) || isContenteditable($el)) {
// Bind events to the element which will update the model with changes.
_.each(config.eventsOverride || getModelEvents($el), function(type) {
self.events[type+'.stickit '+selector] = function() {
self.stickitEvents[type+'.stickit '+selector] = function() {
var val = getElVal($el, isContenteditable($el));
// Don't update the model if false is returned from the `updateModel` configuration.
if (evaluateBoolean(self, config.updateModel, val, modelAttr))
Expand All @@ -137,9 +143,9 @@
updateViewBindEl(self, $el, config, getVal(model, modelAttr, config, self), model, true);
}
});
// We added to `this.events` so we need to re-delegate.
this.delegateEvents();

// We added to `this.stickitEvents` so we need to re-delegate.
this.delegateEvents(this.stickitEvents);

// Wrap remove so that we can remove model events when this view is removed.
this.remove = _.wrap(this.remove, function(oldRemove) {
Expand Down
112 changes: 112 additions & 0 deletions test/bindData.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,118 @@ $(document).ready(function() {
equal(model2.get('candy'), 'butterfinger');
});

test('stickit (existing events property as hash with multiple models and bindings)', function() {

var model1, testView;

model1 = new (Backbone.Model)({id:1, candy:'twix' });
model2 = new (Backbone.Model)({id:2, candy:'snickers'});

testView = new (Backbone.View.extend({

initialize: function() {
this.model = model1;
this.otherModel = model2;
},

events: {
click: 'handleClick'
},

bindings: {
'#test0-textarea': 'candy'
},

otherBindings: {
'#test0-input': 'candy'
},

render: function() {
var html = document.getElementById('jst0').innerHTML;
this.$el.html(_.template(html)());
this.stickit();
this.stickit(this.otherModel, this.otherBindings);
return this;
},

handleClick: function() {
this.clickHandled = true;
}

}))();

$('#qunit-fixture').html(testView.render().el);

testView.$('#test0-textarea').val('kit kat').keyup();
testView.$('#test0-input').val('butterfinger').keyup();

equal(model1.get('candy'), 'kit kat');
equal(model2.get('candy'), 'butterfinger');

testView.$el.click();

equal(testView.clickHandled, true);

});

test('stickit (existing events property as function with multiple models and bindings)', function() {

var model1, testView;

model1 = new (Backbone.Model)({id:1, candy:'twix' });
model2 = new (Backbone.Model)({id:2, candy:'snickers'});

testView = new (Backbone.View.extend({

initialize: function() {
this.model = model1;
this.otherModel = model2;
},

events: function() {

var self = this;

return {
click: function() {
self.clickHandled = true;
}
};

},

bindings: {
'#test0-textarea': 'candy'
},

otherBindings: {
'#test0-input': 'candy'
},

render: function() {
var html = document.getElementById('jst0').innerHTML;
this.$el.html(_.template(html)());
this.stickit();
this.stickit(this.otherModel, this.otherBindings);
return this;
}

}))();

$('#qunit-fixture').html(testView.render().el);

testView.$('#test0-textarea').val('kit kat').keyup();
testView.$('#test0-input').val('butterfinger').keyup();

equal(model1.get('candy'), 'kit kat');
equal(model2.get('candy'), 'butterfinger');

testView.$el.click();

equal(testView.clickHandled, true);

});

test('bindings:setOptions', function() {

model.set({'water':'fountain'});
Expand Down