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.
11 replies on “jQuery in WordPress Widgets admin pages”
Any luck finding a solution?
No, unfortunately this is the best I’ve got so far, but it does the job even if it’s a little bit “hacky”.
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!
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!
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
FYI for anyone wanting an update on this I’ve edited the post above.
[…] I’ve had some difficulty in the last couple of months adding jQuery in to my widget form in the admin area (for ThinkTwit), especially with adding functionality that will let me roll up a group of settings to make it easier for the user to edit them as there are so many. It turned out that this was due to objects being loaded after the page has loaded (see issue and solution). […]
As it turns out, the best way to handle this is to use wp_localize_script() to pass PHP values into a linked JS file:
http://codex.wordpress.org/Function_Reference/wp_localize_script
Also, why is it 4:30am? This is not an easy problem to resolve 🙂
Hi Ian,
Looks like a good solution, thanks. Not sure I follow on your question about 4:30am though?
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.
Hi Mark,
That’s really helpful, I will try it out in my next update – thanks very much!
Steve