Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object literals and event listeners, 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?

like image 614
alnafie Avatar asked Apr 25 '12 08:04

alnafie


People also ask

What is the advantages of using object literals?

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!

What is the difference between an object and an object literal?

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.

Is an event listener an object?

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.

Are event listeners callbacks?

The event listener can be specified as either a callback function or an object whose handleEvent() method serves as the callback function.


2 Answers

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

like image 159
Kirstein Avatar answered Sep 22 '22 01:09

Kirstein


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

like image 22
GillesC Avatar answered Sep 20 '22 01:09

GillesC