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?
The advantages of using object literals to create objects include convenience, flexibility in declaration, and less code during declaration. You can drop an object literal anywhere in your program with no previous setup and it'll work, which can be very handy!
Objects created using object literal are singletons, this means when a change is made to the object, it affects the object entire the script. Whereas if an object is created using constructor function and a change is made to it, that change won't affect the object throughout the script.
The event listener objects are server-side objects that allow you to be notified of certain user events such as drilling down or pivoting and perform some actions after the event has been processed. There are three types of event listener objects.
The event listener can be specified as either a callback function or an object whose handleEvent() method serves as the callback function.
I 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With