Suppose I have an object, with some properties and methods:
var Form = {
name: 'sign-up',
show: function() {...},
hide: function() {...},
validate: function() {...},
updateCurrency: function() {...},
handleCheckBox: function() {...}
}
Now I want to call different methods when certain events happen in my form like so:
$('#country-select').bind('change', function() {
Form.updateCurrency();
});
$("input[type='checkbox']").bind('change', function() {
Form.handleCheckBox();
});
I have a lot of these event listeners, and frankly, I find them ugly listed out one by one like that and not tied directly to the object they relate to. Is there a more elegant way of encapsulating them within my object literal Form
? Is there a best practice?
Suppose I have an object, with some properties and methods:
var Form = {
name: 'sign-up',
show: function() {...},
hide: function() {...},
validate: function() {...},
updateCurrency: function() {...},
handleCheckBox: function() {...}
}
Now I want to call different methods when certain events happen in my form like so:
$('#country-select').bind('change', function() {
Form.updateCurrency();
});
$("input[type='checkbox']").bind('change', function() {
Form.handleCheckBox();
});
I have a lot of these event listeners, and frankly, I find them ugly listed out one by one like that and not tied directly to the object they relate to. Is there a more elegant way of encapsulating them within my object literal Form
? Is there a best practice?
3 Answers
Reset to default 6I like @gillesc
answer, it's on the right tracks.
However, I think we can do better.
The main issue with @gillesc
answer is that its missing the dynamic aspect of things (event handlers for instance), also it forces your to define ugly callback functions.
So heres how I think you should solve your problem.
// Test object
var testObj = {
// Our event handlers.
// Notice how we must only define the callback function name here.
// Not the function itself. The callback function must be defined in testObj.
handlers: {
'#form submit': 'onSubmit'
},
// Method that will register all handlers to some selector
registerHandlers: function() {
var that = this;
// Go through the handlers list.
$.each(this.handlers, function(k, v) {
// Parsing the event to two different parts.
// 1. trigger event
// 2. selector
var split = k.split(" "),
el = split[0],
trigger = split[1];
// Delegating the trigger to selector
$(document).delegate(el, trigger, that[v]);
});
},
// Our actual callback function
onSubmit: function(evt) {
evt.preventDefault();
alert("submit");
}
};
How would it all work? Thats easy! We just need to call testObj.registerHandlers()
.
JSFiddle demo
Organise your markup better and add classes to element that matches event handler methods so that you can easily create a list of handler and iterate over them to bind them to the targeted elements.
Var Form = {
....,
handlers: {
country: function() {},
checkbox: function() {}
}
};
$.each(FORMS.handlers, function(k, v) {
$('.' + k).on('change', v);
});
<select class="country">....</select>
<input class="checkbox" type="checkbox" />
Then all you have to do is add classes and handlers to extend
Well, you don't need to wrap your functions within more functions for a start. Can't you just:
$('#country-select').bind('change', Form.updateCurrency);
$("input[type='checkbox']").bind('change', Form.handleCheckBox);