1

So I have trying to build a embeddable widget that will play nicely w/others when it is loaded on an external website. Since I have never had to do this before I was following a great tutorial by Alex Marandon on how to build a web widget. I am able to load jquery (1.7.1), however, whenever I attempt to load jquery-ui (1.8.16) - from w/in the JS - I get a JS error that says "a is undefined". The following fiddle reproduces what I am seeing:

http://jsfiddle.net/malonso/qfBLx/

Now if I combine the jquery and jqueryui into a single file and put it on my server it works fine but that is less than optimal for a variety of reasons and I would like to avoid that if possible. The other strange thing is that if I attempt to load any other JS file in place of jqueryui, the file loads just fine; clearly I am missing something there.

Thanks in advance.

Update:

The fiddle contains all the relevant code but I will include the javascript portion below. The code waits until the browser has loaded jquery and then it makes a request to load jqueryui. I actually use jquery to print debug statements before and after the request to load jqueryui, so jquery is definitely "available". Just for giggles I tried delaying the loading of jqueryui until 3 seconds after the browser determine jquery is loaded and I get the same issue.

(function() {

// Localize jQuery variable
var jQuery;

/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.7.1') {
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js");
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // For old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              scriptLoadHandler();
          }
      };
    } else {
      script_tag.onload = 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() {
    jQuery(document).ready(function($) {
        loadJS();

    });
}

function loadJS(){
    jQuery('#debug').append("About to load jquery-ui<br>");
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js");
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
    jQuery('#debug').append("Request made to load jquery-ui<br>");
}


})(); // We call our anonymous function immediately
malonso
  • 2,247
  • 1
  • 21
  • 33

2 Answers2

1

This is a bit of a late response, but I was coming across this error when dynamically inserting JQuery UI 1.8.16 into a page with jQuery 1.9

The problem was that the "$.browser" function has been deprecated.

Switching to Jquery V1.7.2 fixed my problem completely. Hope this helps someone else

Tony Carbone
  • 484
  • 4
  • 10
0

If you believe the problem is that the script tag is not being added I found this a bit tricky but below is what I am using and it seems to be working though I am not serving the js just reading from file, also I have not tried with jquery-ui. as always mileage may vary

// add additional javascripts
$.fn.addJavascript = function(src) {
    if (!$('script[src="' + src + '"]').exists()) {
        var script   = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', src);
        document.getElementsByTagName("head")[0].appendChild(script);
    }
};

// .exists() helper
$.fn.exists = function() {
    return this.length !== 0;
}; 

// usage
var d = ["lib/json2.js", "lib/jquery-ui.js"];
for (var i=0; i < d.length; i++) {
    $.fn.addJavascript(d[i]);
} 

I had some success adding jQuery-ui functions within the plugin I was writing using such doing it like such $(window).load(function() { foo.draggable }); I would have already had jQuery loaded though and the 'chain of events' would have gone like

  • page load with jQuery
  • jQuery dom ready call plugin on selection
  • selection for each instantiate new plugin
  • plugin init()
    • add dependencies if not exists
    • render plugin
    • window.load -> bind jquery-ui functionality

Having played with this for a bit I have finally come up with a slightly better dependency adding function though I need to look at checking for existence, also you may wish too look at this question

function addDependencies(args) {
  var head = document.getElementsByTagName('head')[0];
  for (var i=0; i < args.length; i++) {
    var src = args[i];
    var isCss = src.match(/.+\.css$/i);
    var isJs = src.match(/.+\.js$/i);

    if (isCss) {
      if (document.createStyleSheet) {
        document.createStyleSheet(src);
      } else {
        var style = document.createElement('link');
        style.type = 'text/css';
        style.rel = 'stylesheet';
        style.href = src;
        head.appendChild(style);
      }
    } else if (isJs) {
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = src;
      // script.onload = ;
      head.appendChild(script);
    }
  }
  return true;
}

(function() {
  var dependencies = [
    "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js",
    "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js",
    "http://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/reset-fonts-grids/reset-fonts-grids.css"
  ];

  addDependencies(dependencies);

  $(document).ready(function() {
    $('#foo').draggable();
  });

})();

here is a demo

Community
  • 1
  • 1
T I
  • 9,785
  • 4
  • 29
  • 51
  • Thanks Tom, I appreciate the quick response. I would tend to disagree that it isn't relevant to the problem. The problem is that loading jqueryui is *causing* an error. I am not even trying to do anything w/it in the code I attached other than simply loading it. – malonso Feb 07 '12 at 12:53