Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading jQuery UI with getScript

I am trying to build a widget which requires the person to load jQuery and jQuery.UI.

Getting the jQuery to load is not a problem but adding ui the the header is just not working and I keep getting this error.

b is undefined
[Break on this error] (function(b,c){function f(g){return!b(...NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,

Here is the script in its simple form.

(function() {

// Localize jQuery variable
var jQuery;

/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.4') {
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type", "text/javascript");
    script_tag.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js");
    script_tag.onload = scriptLoadHandler;  
    script_tag.onreadystatechange = function () { // Same thing but for IE
        if (this.readyState == 'complete' || this.readyState == 'loaded') {
            scriptLoadHandler();
        }
    };
    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);

} else {
    // The jQuery version on the window is the one we want to use
    jQuery = window.jQuery;
    main();
}



/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Restore $ and window.jQuery to their previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(true);  
    // Call our main function
    main();
}

/******** Our main function ********/

function main() {

// Add some validation here to make sure UI is not loaded etc...
jQuery.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js');

jQuery(document).ready(function($)
{    
    var date = new Date();
    var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
    $('.datepicker').datepicker({minDate: new Date(y, m, d)});

    /******* Load HTML *******/
    var jsonp_url = "/search/form/%AFFILIATE_ID%/%FORM_TYPE%/";
    $.getJSON(jsonp_url, function(data)
    {
      $('#my-widget').html(data);
    });

});
}

})(); // We call our anonymous function immediately

Any ideas how I can resolve this ?

like image 321
Lee Avatar asked Dec 08 '10 15:12

Lee


3 Answers

I've run into this one before — jQuery isn't "defined" when jQuery UI begins to load. Yes, this can be true even if jQuery is loading it! ;-)

The jQuery UI script takes the global name jQuery as its first argument. You aren't loading jQuery UI until after you've called jQuery.noConflict(true), which removes jQuery from the global object (window).

There are two ways to solve this. If you're okay leaving window.jQuery intact, simply remove the true from your noConflict call; this relinquishes control over $ but leaves jQuery around for jQuery UI to use:

/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Restore $ to its previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(); // no argument!
    // Call our main function
    main();
}

Alternatively, move your noConflict call into a callback on getScript:

/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Store jQuery in a local variable so it can be removed later
    jQuery = window.jQuery;
    // Call our main function
    main();
}

/******** Our main function ********/

function main() {

// Add some validation here to make sure UI is not loaded etc...
jQuery.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js', function() {
    jQuery.noConflict(true);
});

// ...
like image 108
Ben Blank Avatar answered Oct 28 '22 12:10

Ben Blank


The problem appears to be your main function. You are loading jQuery UI and then calling jQuery(document).ready(). ready() will fire immediately because the DOM is already loaded. So you start loading jQuery UI and then immediately execute jQuery UI code before jQuery UI is loaded. You should pass your function with jQuery UI code into the success handler for getScript().

jQuery.getScript( url, [ success(data, textStatus) ] )
    url - A string containing the URL to which the request is sent.
    success(data, textStatus) - A callback function that is executed if the request succeeds.

http://api.jquery.com/jQuery.getScript/

UPDATE: You need to execute your jQueryUI code after jQueryUI is completely loaded. Right now you're trying to execute jQueryUI code as jQueryUI is loading. Try this instead. Note how I'm not using $(document).ready(), but instead registring an anonymous function to be run after successful completion of jQuery.getScript().

function main() {
    // Add some validation here to make sure UI is not loaded etc...
    jQuery.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js',
        function() {
            var $ = jQuery; // Since we don't get this as an event parameter and we're using jQuery.noConflict()
            var date = new Date();
            var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
            $('.datepicker').datepicker({minDate: new Date(y, m, d)});

            /******* Load HTML *******/
            var jsonp_url = "/search/form/%AFFILIATE_ID%/%FORM_TYPE%/";
            $.getJSON(jsonp_url, function(data) {
                $('#my-widget').html(data);
            });
        });
}
like image 37
James Kovacs Avatar answered Oct 28 '22 10:10

James Kovacs


It might be overkill for your situation, but LAB.js is small, MIT-licensed, and provides a very robust framework for fine-grained control over script loading. For example:

$LAB
  .script("must_be_first.js").wait()
  .script("jquery.js")                      // wait for must_be_first.js
  .script("romulus.js,remus.js").wait()     // any order    
  .script("jquery-ui.js").wait( function(){ // not until all above executed
    do_stuff();                          
    do_other_stuff();
   }).wait()
  .script("must_come_last.js");
like image 1
Ken Redler Avatar answered Oct 28 '22 11:10

Ken Redler