Using a jQuery accordian on a widget.
-
First things first, I’m new to PHP and the WordPress API, despite that fact I’ve managed to write a fairly involved widget that does exactly what I set out to make it do.
However it suffers in the UI department. My issue is that I have nearly 40 options to select/set and that makes the settings screen quite long, think “scroll of death”. It’s possible to divide the options into 4 distinct sections and I’d like to be able to get those sections into something like an accordion control to limit the vertical scrolling. Something like this would do nicely . Is this possible? Does it go against any WordPress UI rules?
Thanks
Chuck
-
Hello Chuck,
I don’t think it goes against any WordPress UI rules. WordPress ships with jQuery accordion out of the box. Just
wp_enqueue_script('jquery-ui-accordion');
in your widget code and you are good to go.Ok so i put the wp_enqueue_script(‘jquery-ui-accordion’); right near the beginning of my form method in my widget. Figured it belonged there over anywhere else because that the code that draws the frontend where i want the accordion section.
I then dropped this in:
<div id="accordion"> <h3>Section 1</h3> <div> <p> Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate. </p> </div> <h3>Section 2</h3> <div> <p> Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p> </div> </div>
That just ends up rendering out normally with no accordion happening.
So I’m missing something, but what?
Is my id on the opening <div> wrong? If not then what is right?
I’ve seen reference to needing some javascript to get things going that looks like this
<script> (function(){ jQuery("#accordion").accordion(); })(); </script>
I’ve put this in my form method both before and after the section that i want to accordion and it doesn’t make a difference so i’m still lost.
Thanks
ChuckAs I don’t have the source code of your widget, I can only give you a general advice.
- When working with JS, always use Developer Console of your browser. You can detect JS errors or other messages there and also inspect HTML/CSS code easily.
- Before you can use a JS library, it has to be loaded in the browser, otherwise you’ll receive JS undefined errors.
Your widget is run after the function
wp_head()
has been called (=> after outputting the site header</head>
), thereforewp_enqueue_script('jquery-ui-accordion');
outputs the accordion library in the footer of your site. However, your widget is run somewhere in the middle of the page and the accordion library has not yet been loaded into the browser (not yet outputted). If you inspect the Developer Console, you would observe anUncaught TypeError: undefined is not a function
.There are two options how to fix this:
1. Enqueue the accordion library before the
wp_head()
is called. For example, in your functions.php, you could add a piece of code:function lamosty_enqueue_accordion() { wp_enqueue_script( 'jquery-ui-accordion' ); } add_action( 'wp_enqueue_scripts', 'lamosty_enqueue_accordion' );
which does the trick. Action wp_enqueue_scripts is run during
wp_head()
execution.2. If you want to enqueue the accordion library only on pages where the accordion is to be used, modify your JS code as shown below:
jQuery(function($) { $("#accordion").accordion(); });
which is the same as calling
jQuery(document).ready(function($) { $("#accordion").accordion(); });
What it does is that jQuery waits until the page is “ready” (=> everything has been loaded) and runs the inner function only after that. In this case, it doesn’t matter that the accordion library is loaded in the footer of the page because jQuery is waiting till everything is loaded, only then executing the function. You can read more about it on jQuery docs site.
Ok lets assume I have no access to the contents of the functions.php file because i’m writing a widget that i’m planning to distribute. At least I am assuming i wouldn’t have access to the functions.php file in this case but there may be something about packaging a widget that I just don’t understand just yet.
So anyway here is a real basic widget example. It looks almost identical to what i’ve got going on with my widget but all the guts have been removed leaving only the jQuery accordion UI stuff.
<?php /* Plugin Name: jQuery UI example Plugin URI: https://www.someurl.com Description: Show a jQuery UI Accordion control on a widget form Version: 0.0.0 Author: Me Author URI: https://www.someurl.com */ class jquery_ui_example_widget extends WP_Widget { /** constructor */ function jquery_ui_example_widget() { parent::WP_Widget(false, $name = 'jQuery UI Example Widget'); } /** @see WP_Widget::widget */ function widget($args, $instance) { } /** @see WP_Widget::update */ function update($new_instance, $old_instance) { } function form($instance) { wp_enqueue_script('jquery-ui-accordion'); ?> <script> jQuery(document).ready(function($) { $('#accordion').accordion(); </script> <div id="accordion"> <h3>Section 1</h3> <div> <p> Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate. </p> </div> <h3>Section 2</h3> <div> <p> Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p> </div> </div> <?php } } // *** Register the widget add_action('widgets_init', create_function('', 'return register_widget("jquery_ui_example_widget");')); ?>
With the above i get no “accordion” action going on. I’m wondering if there’s some CSS missing here as well.
Thanks
ChuckIf you had opened up your browser’s dev console, you would see that there is an JS error. You are missing closing brackets:
function form($instance) { wp_enqueue_script('jquery-ui-accordion'); ?> <script> jQuery(document).ready(function($) { $('#accordion').accordion(); }); //missing brackets here </script> <div id="accordion">
After that, it is working, though not displaying very nicely. You will need to play with the CSS or something because the accordion doesn’t fit the admin panel’s widget area somehow.
Anyways, you are right about the no-access to
functions.php
, my mistake. There is a nice solution to this problem too.That’ll do it every time. Stared at it for so long I couldn’t see it.
So as to the CSS. I tried this out. I loaded the style from version 1.11.2 because that seems to be the version of the jquery ui that WordPress is loading.
wp_enqueue_script('jquery-ui-accordion'); wp_register_style('jquery_ui_example_css', 'https://code.jquery.com/ui/1.11.2/themes/flick/jquery-ui.css'); wp_enqueue_style('jquery_ui_example_css');
While it looks better its still non-functional. Getting closer.
Thanks
Chuck
- The topic ‘Using a jQuery accordian on a widget.’ is closed to new replies.