Drupal(jQuery UI + Devel): $.widget is not a function

jQuery whines incessantly

croppercapture14

Real helpful error. I’ve verified that $.widget() is a function and has been included. So, why am I getting this error? (In fact, now that I think of it, Javascript/jQuery has the most obtuse and misleading error messages of any language I have ever programmed in. However, it’s also one of the most ubiquitous languages as well. Interesting.)

Enough meta whining; what’s the problem?

Drupal developers love jQuery, and hence the jquery_ui module. They also love the Devel module. Unsurprisingly, the developers of the Devel module love jQuery UI as well, and have included portions of the UI API directly within the Devel module. This works nicely until you decide that you love the jQuery UI, and install jquery_ui. When you call jquery_ui_add(array(…)) from your code, if you include any files that the Devel module has already included (an outdated version thereof, I might add), then you’ve got two (nearly) identical files of included code that clash brilliantly.

And hence the lovely error, “$.widget is not a function”. Wouldn’t “$.widget is already defined” make a bit more sense?

Fix it, fix it, fix it!

Fortunately, there are many ways to fix this error.

  • Write a patch/Get the authors of the Devel module to add the jQuery UI module as a dependency (and remove the direct jQuery UI includes from the module). Easily the best, but most time-consuming solution.
  • Write a patch/Get the authors of the jQuery UI module to check if a given jQuery UI file has already been added via drupal_add_js(). If it has been, don’t include the file again. Might still cause conflicts because of differing versions
  • Hack the Devel module:
    • Enable the jQuery UI module, and remove the code from the Devel module that includes the jQuery UI files local to the Devel module
    • Replace the jQuery UI files in the Devel module with the same files from your jQuery UI installation. Then, in your code, only include the files that the Devel module uses (ui.draggable.js and ui.mouse.js currently) if the Devel module is disabled. This solution takes a bit of effort but might be the quickest workaround.
  • etc (I’m sure there are many more options)

Personally, I’m using the last option. The code I’m using to detect whether or not the Devel module is enabled (and act accordingly) is:

	if(function_exists('devel_menu'))
		jquery_ui_add(array('ui.datepicker'));
	else
		jquery_ui_add(array('ui.draggable', 'ui.datepicker'));

Happy drupaling!

Thanks to Wei Wang, who tipped me off: http://groups.google.com/group/jquery-ui/browse_thread/thread/675b5fbb64ee7664

Text-version of the error for the Google machine:

$.widget is not a function
http://xxx.com/yyy/zzz/ui.draggable.js?6
Line 391

Update

After writing up this post, I realized that the first option is really not that tough. (Note that if you follow these steps, you’ll have to repeat them every time you update the Devel module.) Add the following line to the Devel Themer module’s devel.info:

dependencies[] = jquery_ui

Now, find the ‘devel_themer_init()’ function in devel_themer.module, and comment out the following lines (104 and 105 for the current version):

    drupal_add_js($path .'/ui.mouse.js');
    drupal_add_js($path .'/ui.draggable.js');

Immediately following the newly commented out lines, insert the following:

	jquery_ui_add(array('ui.draggable', 'ui.mouse'));

You’re done! Booyah.

6 thoughts on “Drupal(jQuery UI + Devel): $.widget is not a function”

Comments are closed.