Enabling jquery when dragging available widget to sidebar area

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?

1
1

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):

// https://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 s #' + number );
}

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

// OneTrick's
// https://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!
    }
});

Leave a Comment