Basic question about jQuery

I'm still new to jQuery and still learning. Ever since I started using it, I've been putting all my JavaScript code inside:

$(function() {
    function insideJQuery() {
        // This function calls stuff within this jQuery function, so it has to be here.
    }
}

Open in new window


But now I'm facing a problem where I have an <a> element with href="javascript:insideJQuery()", and I'm getting the error message -- "Uncaught ReferenceError: insideJQuery() is not defined". This is expected because the function is inside another function, and therefore is out of scope.

But I can't really move the insideJQuery() function out of the JQuery's function because that function calls other functions within that scope that use a lot of jQuery; that's why it's there in the first place.

How can I access an inner nested function from the outside? The jQuery function isn't exactly a function I can call and have it return a reference to the inner nested function. What should I do?

Thanks.
elepilAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
There are two ways of doing this - see sample below.

The first is to set your function equal to a global variable. The second is to add an event handler inside the $(function to pick up the <a> click and call the function from there.
<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>Click each of the links below to demonstrate the different methods</p>
<a href="javascript:myFunc('Global Variable');">Method 1 - using a global variable</a><br/>

<a href="#" class="myfunc-link">Method 2 - using an event handler</a>
<script src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript">
$(function() {
  $('a.myfunc-link').click(function(e) {
    e.preventDefault();
    myFunc('Event Handler');
  });
  window.myFunc = function myFunc(val)
  {
    myOtherFunc(val);
  }
  function myOtherFunc(val)
  {
    alert(val);
  }
});
</script>
</body>
</html>

Open in new window

Working sample here
Alexandre SimõesManager / Technology SpecialistCommented:
Well, to answer that, there are a lot of things that need to be understood.

1. What is: $(function() {});


This is one way to execute something on document ready event.
It's the same as $(document).ready(function(){});
Basically makes sure that all the DOM is parsed before the function is executed.

Now, taking what I said above, wrapping every code like this is wrong.
Ideally, every application should, if needed, only have one document ready event listener, which is the "startup" of the application.

Side note 1: using the document ready event is the same as putting your scripts at the end of the body tag.
Side note 2: jquery document ready handles all the fallbacks for all the browsers.

2. Accessing methods inside functions


So you know that you're doing it wrong, so how do you do it?
With plain javascript you need to create objects from functions. Something similar to OOP but in JavaScript.
Recently I did a demo for another question that illustrates that: http://jsfiddle.net/AlexCode/k7zryqhb/
function MessagesManager() {
    var getTime = function (h, m) {
        return new Date((new Date()).setHours(h, m, 0, 0));
    };

    var responses = [
        /* days represent the day of the week. 0=Sunday, 1=Monday, ... */ 
        { days: [1, 2, 3, 4, 5], from: getTime(8, 0), to: getTime(19, 29), message: "We’re open and can see you today." }, 
        { days: [1, 2, 3, 4, 5], from: getTime(0, 0), to: getTime(7, 59), message: "We’re closed but will reopen tomorrow at 8 AM." },
        /* FILL IN THE REST */
    ];

    var isInRange = function (response, date) {
        date = date || new Date();

        return response.days.indexOf(date.getDay()) > -1 && date >= response.from && date <= response.to;
    };

    this.getMessage = function () {
        for (var i = 0; i < responses.length; i++) {
            var response = responses[i];
            if (isInRange(response)) {
                return response.message;
            }
        }

        return 'Message not found'; // you can even use this as the default closed message
    };
}

var msgs = new MessagesManager();
document.getElementById('display').innerHTML = msgs.getMessage();

Open in new window

Notive that inside the function there are variables and there are methods assigned to 'this' (like the getMessage).

Just calling this function won't do anything, we need to create an object out of it, and that's done with the 'new' keyword
var msgs = new MessagesManager();

Open in new window

The result of this is the msgs variable containing an object with one single method exposed, that is the getMessage.
Like this you can reuse this function much like you reuse classes in OOP languages.

3. Another option is AMD


AMD (Async Module Dependency) is the way to enforce dependencies between javascript blocks of code.
This is quite advanced, I'll leave you the link to RequireJS but I thing there's a lot you need to learn before this.

0. Do this before everything else


I'll leave you 2 of the books I require everyone working with me to read at least once.
The Secrets of the JavaScript Ninja
This was written by the guy that created jQuery and is an invaluable source of information.
High Performance JavaScript
This book approaches the same thing but from a different angle. It explains things that would be hard to understand otherwise, like the way the browser works internally and how your code is actually handled.

Read them both and you'll "see the light" :)

Cheers mate!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
elepilAuthor Commented:
Excellent responses from both Alexandre Simões and JulianH!

While JulianH provided an excellent workaround for my problem, Alexandre attacked my problem from the root. I come from a classic OOP background with both Java and ActionScript, so I am still in the process of acclimating to the nuances and idiosyncrasies of the PHP and JavaScript world. I am already a heavy proponent and believer of constructor functions, which is what you demonstrated. Your response addressed directly the aspects of JavaScript that I was uncertain of, and I greatly appreciate it!

I thank you both for your high-quality solutions!
Julian HansenCommented:
You are welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.