jQuery in WordPress Widgets admin pages

I’ve been struggling for a few days with trying to get jQuery working within the widgets part of the WordPress 3.2.1 admin pages. Even the most basic of tests does not seem to allow me to, for instance, append some text to a div, using:

<div id="test">Test: >/div>

<script type="text/javascript">
  jQuery(document).ready(function($){
    $("#test").append("HELLO!");
  });
</script>

It seems to work fine within the widget on the front page, but as soon as I try to use any jQuery within the admin pages it seems to mess up. There are a few articles out there suggesting how to get it working but everything I’ve tried so far seems to fail.

So in the meantime, until someone works out how to get this working (because I give up!), I’ve hacked the code used to expand the widgets themselves when placed in the sidebar. Hopefully someone else who’s also struggling to achieve what I have attempted will find this useful:

<div class="widget" style="border: 0">
  <div class="widget-top" style="border: 0; background: inherit; cursor: default; width: 94%">
    <div class="widget-title-action"><a class="widget-action hide-if-no-js" href="#available-widgets"></div>
    <div class="widget-title" style="padding: 6px 0 0"><h3 style="margin: 0; cursor: default">General Settings</h3></div>
  </div>
  <div class="widget-inside" style="display: block; border: 1px solid #DFDFDF; padding: 5px; width: 86%;">
    // Your menu here
  </div>
</div>

If you wish to have your menu start expanded when the page is loaded the above code will do the trick. However, if you want it contracted then you will have to remove “display: block” from the div with the class named widget-inside.

Hope that helps!

** UPDATE **

So I’ve finally worked out what is causing this issue and how to get around it. It appears that jQuery is actually loading as it should but (possibly due to the jQuery.noConflict(); call in the jQuery script that I mentioned in my comment) it doesn’t load the same. Unrelated to this (I believe) is that widget form options seem to be loaded after the page is loaded, which means that if you are trying to access an object in your form you can’t access it as normal.

The way around this is to use the .live() event which will attach a function to the object once it has loaded – note that live() is now deprecated but I couldn’t get this code working with .on() which is its replacement.

So the example that I will give to demonstrate this comes from a soon-to-launch update to ThinkTwit whereby a link is added that when clicked will reset the form options to default. The following link:

<a id="reset_settings" href="#">Reset Settings</a>

will have an event attached to it when it loads:

<script type="text/javascript">
	jQuery(document).ready(function($) {
		$("#reset_settings").live("click", function() {
			alert("CLICK!");
		}
	});
</script>

Knowing this information should help me solve the accordion issue too but for now I’ll just leave you with the above.

About Stephen Pickett


Stephen Pickett is a programmer, IT strategist, project manager, RightNow and telephony expert, information security specialist, all-round geek. He is currently Professional Services Director at Connect Assist, a social business that helps charities and public services improve quality, efficiency and customer engagement through the provision of helpline services and CRM systems.


Stephen is based in south Wales and attended Cardiff University to study Computer Science, in which he achieved a 2:1 grading. He has previously worked for Think Consulting Solutions, the leading voice on not-for-profit fundraising, Fujitsu Services and Sony Manufacturing UK as a software developer.


Stephen is the developer of ThinkTwit, a WordPress plugin that allows you to display multiple Twitter feeds within a blog.


11 thoughts on “jQuery in WordPress Widgets admin pages

  1. How were you hooking into the admin area?

    I’d assume errors would show in the firebug console, if jQuery wasn’t loaded, and you were hooking into the footer to ensure it was loaded previously. If the theme has any javascript errors, in my experience, no js gets executed thereafter. So it could be another culprit. If vanilla js works, then double check to make sure jQuery is loaded.

    Using the hook print admin scripts is the way to go, but given I use admin_footer for multiple other things as well, this is what I did:

    function widget_inject(){
    global $pagenow;
    if($pagenow == “widgets.php”){
    echo ‘ jQuery(“#widgets-left”).prepend(“My jQuery Added Header “);’;
    }
    }
    add_action(‘admin_footer’, ‘widget_inject’ );

    Several Excellent ways on how to hook into different pages of the admin area: bit[dot]ly/MxZv9V

    Cheers!

  2. Hi David,

    To be honest it’s a while back since I looked at this, but as I recall I was loading it as you would on a public page – and I’m pretty sure JS worked but jQuery was not loading correctly.

    I’ll take a look at this when I next get a chance, but it will be low on the list for the time being as I want to get upgrades more smooth first. Thanks for the pointers though, much appreciated!

  3. FYI I’ve done some more research in to this and found some code that will actually let me use jQuery from within the admin area.

    The first issue I’ve run in to is that it specifies its own jQuery script – I tried instead changing this for the WordPress one but it appears that the last statement in this (jQuery.noConflict();) causes the code to break so I’m currently working a way around this.

    The second issue is that I’m having trouble getting the code that is loaded to line up with code in the widget settings. Once I’ve gotten past these issues I’ll update this post with the solution.

    I found this at: http://forum.jquery.com/topic/loading-jquery-if-undefined

  4. It’s got to do with the jQuery accordion itself. It;s height is set to auto unless specified otherwise. In the case of the accordion being in a collapsed panel, it’s initial size will be small because the are it has to work in is collapsed.

    The workaround is as follows:

    jQuery( “.accordion” ).accordion({
    collapsible: true,
    active: false,
    heightStyle: “content”
    });

    document.addEventListener(‘DOMNodeInserted’, function(e) {
    var el = $(e.target);
    if(el.hasClass(‘accordion’)) {
    el.accordion({
    collapsible: true,
    heightStyle: “content”
    });
    }
    });

    The second bit of code there adds an event listener so that the script itself can be enqueed, and not have to be placed inline in your widget content.

    Hope this helps.

Leave a Reply