tags:

views:

31

answers:

3

I am relatively new to javascript so please be patient if what i am asking is completely stupid!

I am trying to make a simple module. Inside the module i want to have a config object that holds settings for the module. I am also using jquery. The jquery selectors work only when in a function directly in the main object/module.

I understand that javascript has functional scope so I am suprised that I cannot use the jquery selectors anywhere inside the module.

EDIT: I want to be able to directly set all of my configs inside the configs object using jquery selectors. This way i keep all the messy stuff inside one place and can then access configs.whatever throughout the rest of the module. At the moment jquery selectors do not work inside the configs module.

    var OB = function() {

    var configs = {
        'mode'    : 'test',
        'numOfSelects' : $('.mySelect').find('select').length,  // This doesnt work
    }

    var getMode = function() {
        return configs.mode;
    }

    function init() { 
        alert(configs.numOfSelects);  // This alerts 0 until the following line
        alert($('.mySelect').find('select').length);  // This correctly alerts 2
    };

    var handlers = {
        successHandler : function() {
            alert("Success");
        },
        errorHandler : function() {
            alert("error");
        }
    }

    return {
        init    : init,
        getMode : getMode
    }

}( );

$(document).ready(function(){
    OB.init();
});
+1  A: 

EDIT: It's funny that my original answer below was incorrect because I didn't notice two little parentheses at the end of the definition of OB, and it turns out that these are the culprit. You define and then immediately invoke OB, which is before the DOM has been fully loaded. Remove those parentheses and make the change I suggest below.

Calling OB() returns an object with init and getMode, but you haven't called OB(), you've only referred to OB. Try this instead:

$(document).ready(function(){
    OB().init();
});

Also, I assume you want to later refer to getMode. In particular, you will to get the copy of getMode that has access to the same local scope that your init() call had access to. To achieve this, you will need to store the result of calling OB() for later use:

var ob;

$(document).ready(function(){
    ob = OB();
    ob.init();
});

function some_other_function() {
    ... ob.getMode() ...;
}
Marcelo Cantos
But i have called OB(). I have included the opening and closing parenthesis at the end of the function as in }( );
David
Silly me, I didn't notice those parentheses.
Marcelo Cantos
Something else just occurred to me, one of the main points of the module pattern is to reduce global variables. If I have everything encapsulated inside OB but then also introduce ob ament i then introducing another global. albeit, only 1 but stil...
David
@David: You normally avoid that by placing all uses of `ob` inside the `document.ready` handler.
Marcelo Cantos
So you mean basically keep the whole module inside document.ready ?
David
Yep............
Marcelo Cantos
+1  A: 

It isn't that jQuery isn't in scope — that's that the code isn't executing when you think it is. The variable config is defined when that anonymous function (var OB = function() {}()) is executed. The DOM isn't ready yet, so that DOM traversal doesn't find anything. When you do the DOM traversal in init(), that isn't executed until it's explicitly called inside the $(document).ready() handler, at which point that DOM is set up. That's the difference you're seeing.

Chuck
Thanks chuck. I knew i was being stupid. You wouldnt believe how long i have tried working this out.
David
I want to give @chuck, @absynce and @marcelo the correct answer as you all pointed it out to me. But i cant.
David
+1  A: 

OB() needs to be called after the DOM has completely loaded. Hence the answer by Marcelo, which calls OB() in the ready() method.

absynce
Aaaahhh!!! Now i see. I am calling it before the dom has loaded and so there are no select boxes to count yet!.
David
Chuck, you beat me to it:) You did a better job of describing it as well.
absynce