views:

37

answers:

2

NEWBIE ALERT! (C# guy trying to learn jQuery for a new MVC app).

I modified some code I found on the web (Stephen Walther- http://bit.ly/bWxU3E) and modified it to use jQuery instead of the MSAjax library. It is a cascading dropdown list and some dummy data. Works great. Next, I try to put the function bindDropDownList() into a separate .js file so I can reuse it. Then it crashes because (I think) the function is all jQuery calls and it can only interpret javascript code. It doesn't recognize the jQuery methods of the objects. Am I totally off here, or is there a trick to make this work?

Here is my code snippet that works perfectly. The function bindDropDownList() is first. If I move it into it's own .js file and reference it, it crashes on the first line, targetDropDownList.empty(), with the error "object doesn't support this method".

<script type="text/javascript">
    function bindDropDownList(parentKey, allOptions, targetDropDownList) {
        targetDropDownList.empty();
        for (var i = 0; i < allOptions.length; i++) {
            option = allOptions[i];
            if (option.ParentKey == parentKey) {
                targetDropDownList.append($('<option/>').attr("value", option.Key).text(option.Name));
            }
        }
    }
</script>
<script type="text/javascript">
    $(document).ready(function () {
        $('#StatesDropDown').change(function () {
            var allOptions = $('#StatesDropDown').data('allOptions');
            bindDropDownList(this.value, allOptions, $('#CitiesDropDown'));
        });
        $('#StatesDropDown').data('allOptions', [{ Key: 1, ParentKey: 1, Name: 'hello' }, { Key: 3, ParentKey: 1, Name: 'helloxxxx' }, { Key: 2, ParentKey: 2, Name: 'yelp'}]);
    });
</script>
A: 

jQuery methods are JavaScript methods you can use them anywhere after they're defined, I think the issue is your external file being included before jQuery.

When using any library make sure it's included before you try and use its functions. To fix your issue take a look at your <script> order and adjust accordingly, so that your file comes after the jQuery library.

Nick Craver
Nick, I'm sure you're right, but I don't quite understand this. The third argument passed to `bindDropDownList` has already been created as a jQuery selection, so wouldn't the `.empty()` method be available on it?
lonesomeday
@lonesomeday - If you include a JavaScript file that uses `.someMethod()` before your include the file that has that method defined, it'll blow up....it's not the execution that's blowing up here, it's the initial evaluation of the script where the browser JavaScript compiler/VM/tracing engine is trying to figure out what your code does...in this case it's saying "wtf is that method???"....because it isn't defined yet if the jQuery library is included *after*...remember each file is read in order by the browser....at that point it has no knowledge of jQuery yet, if it isn't included before.
Nick Craver
@Nick thanks. I'm still not sure I understand, though -- I've done [a mock-up of the OP's code](http://pastebin.org/232056) and it seems to work fine for me. What's the difference?
lonesomeday
@lonesomeday - Your function isn't in it's own file :)
Nick Craver
@Nick Oh dear, I should read better. Many thanks.
lonesomeday
A: 

I found the answer on another blog! I kept googling with terms like 'jquery in javascript' and various derivations of such to no avail. But then I googled 'jquery external file' and found the answer here: http://www.latentmotion.com/separating-jquery-functions-into-external-files-without-selectors/

In summary, you can't reference a jquery function in an external library file unless you wrap that function in a special jquery code block.

(function($){  
    yourFunction = function() {  
        $("body").append('See? It works.');  
    };  
})(jQuery);

That solved it!