Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

So I have some widgets that are using some custom jquery on the backend. I can get the widget forms to call the jquery files but only AFTER I've saved the widget and reloaded the page.

Is there anyway to use that jquery as soon as I've dragged it from the "Available Widgets" area to the sidebar area?

So in my widget code, in the form function, I have this:

function form( $instance ) {

wp_enqueue_media();
wp_enqueue_script('kjd_widgets',plugins_url('lib/kjd_widgets.js',__FILE__),null);

so that works but only after ive reloaded the page. How can I get the JS to load when the widget is activated and? And would I have to add something to my jQuery to bind the new widget form to the jQuery?

share|improve this question
1  
You're going to have to show some code. –  Wyck Oct 9 '13 at 21:31
    
oops sorry, there we go. –  rugbert Oct 15 '13 at 14:34
1  
Have you seen Update widget form after drag-and-drop? –  toscho Oct 17 '13 at 5:06
add comment

1 Answer

up vote 3 down vote accepted
+50

I know this issue from this Q&A: Update widget form after drag-and-drop (WP save bug).

I was answering a Stack Overflow question and faced the same problem. We have to add an AjaxComplete action and fire our function when XMLHttpRequest.responseText is true. I'm not sure about the inner workings but we only have to modify one line in the following code (by onetrickpony):

// http://wordpress.stackexchange.com/a/37707
jQuery( document ).ajaxComplete( function( event, XMLHttpRequest, ajaxOptions ) {
    // determine which ajax request is this (we're after "save-widget")
    var request = {}, pairs = ajaxOptions.data.split('&'), i, split, widget;
    for( i in pairs ) {
        split = pairs[i].split( '=' );
        request[decodeURIComponent( split[0] )] = decodeURIComponent( split[1] );
    }
    // only proceed if this was a widget-save request
    if( request.action && ( request.action === 'save-widget' ) ) {
        // locate the widget block
        widget = jQuery('input.widget-id[value="' + request['widget-id'] + '"]').parents('.widget');

        // trigger manual save, if this was the save request 
        // and if we didn't get the form html response (the wp bug)
        if( !XMLHttpRequest.responseText ) 
            wpWidgets.save(widget, 0, 1, 0);

        // we got an response, this could be either our request above,
        // or a correct widget-save call, so fire an event on which we can hook our js
        else
            jQuery('DO_OUR_STUFF');
    }
});

Demo plugin

<?php
/* Plugin Name: Demo Widget jQuery Damit */

add_action( 'widgets_init', 'b5f_load_widgets' );

function b5f_load_widgets() {
    register_widget( 'B5F_Example_Widget' );
}

class B5F_Example_Widget extends WP_Widget {
    private $url;

    function B5F_Example_Widget() {
        $this->url = plugins_url( '/test-me.js', __FILE__ );
        $widget_ops = array( 'classname' => 'example', 'description' => '' );
        $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );
        $this->WP_Widget( 'example-widget','Example Widget', $widget_ops, $control_ops );
        if( is_admin() )
            wp_enqueue_script( 'test-me', $this->url, array(), false, true );
    }

    function widget( $args, $instance ) {
        echo 'Test';
    }

    function update( $new_instance, $old_instance ) {
        return $instance;
    }

    function form( $instance ) {
        echo "<a href='#' class='test-me'>File to load: {$this->url}</a>";
    }
}

And onetrickpony's code adapted to our widget (/wp-content/our-plugin/test-me.js):

// Common function to do the Trick and our jQuery action
function test_click() {
    var number = 1 + Math.floor( Math.random() * 5000000 );
    jQuery( this ).html( 'WordPress Answers #' + number );
}

// Our jQuery
jQuery( document ).ready( function( $ ) {
    $( '.test-me' ).click( test_click );
});

// OneTrick's
// http://wordpress.stackexchange.com/a/37707
jQuery( document ).ajaxComplete( function( event, XMLHttpRequest, ajaxOptions ) {
    var request = {}, pairs = ajaxOptions.data.split('&'), i, split, widget;
    for( i in pairs ) {
        split = pairs[i].split( '=' );
        request[decodeURIComponent( split[0] )] = decodeURIComponent( split[1] );
    }

    if( request.action && ( request.action === 'save-widget' ) ) {
        widget = jQuery('input.widget-id[value="' + request['widget-id'] + '"]').parents('.widget');
        if( !XMLHttpRequest.responseText ) 
            wpWidgets.save(widget, 0, 1, 0);
        else
            jQuery( '.test-me' ).click( test_click ); // <--- One trick, pony!
    }
});
share|improve this answer
    
+1 Was searching for ajaxComplete just two days ago... –  kaiser Oct 21 '13 at 0:40
    
!timestamps, but pretty sure you did vote. Reminds me of a newbie who was like "+1!!", and people were "hmmm, io, man, you actually have to push the button..." –  brasofilo Oct 21 '13 at 1:48
    
screenshots say more than words - upvoted answer previously, then read again and encountered ajaxComplete and wanted to +1 again, realizing that it's name plus one for a reason :) –  kaiser Oct 21 '13 at 11:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.