2

I've tried doing this one of two ways:

  1. In the form method of my Widget class (which extends WP_Widget), I have the following snippet, which sets a global javascript variable:

    if( $instance ) :
    ?>
        <script type="text/javascript">
            window.widget_order_name = "<?php echo $this->get_field_name( 'order' ) ?>";
        </script>
    <?php
    endif;
    
  2. In the widget admin markup, I also tried to create the following html structure:

    <div
      field_name='<?php echo $this->get_field_name( 'order' ) ?>'
      id='order_field_name'
      class='hidden'>
    </div>
    

In my widget admin javascript file, I grab the value of this field_name in one of two ways (as seen below) and then attached that widget name to that of a hidden input field (which contains a value I want to store).

  1. The first way, using window.widget_order_name:

    var widget_field_name = window.widget_order_name;
    
  2. The second way, using jQuery to grab the field_name:

    var widget_field_name = $( '#order_field_name' ).attr( 'field_name' );
    

My problem:

Whenever I first move the widget from the Available Widgets container to my sidebar, I don't get the actual field name, I get instead a sort of placeholder for the field name.

So, instead of getting something like this:

<input 
  type="hidden" 
  name="widget-hours-widget[2][order][]"
  value="L48">

I get this:

<input 
  type="hidden" 
  name="widget-hours-widget[__i__][order][]" 
  value="L26">

After the save button is clicked, the field_name gives me the correct name of the widget, widget-hours-widget[2] rather than the placeholder widget-hours-widget[__i__].

Has anybody run into a similar problem or know how to go about fixing it?

Thanks.

1
  • Let's agree that your __i__ comes from the Widgets class you are overrding, in function form_callback(...), ie. if ( -1 == $widget_args['number'] ) { // We echo out a form where 'number' can be set later $this->_set('__i__'); $instance = array(); } Here, $instance is set to an empty array. In your code, with $instance set an empty array, if( $instance ) : will be TRUE. Is this what you really want?
    – conner_bw
    Aug 28, 2013 at 19:22

1 Answer 1

0

The Problem

So I figured out what the problem was. In the statement below, jQuery was grabbing the first element with the id of #order_field_name.

var widget_field_name = $( '#order_field_name' ).attr( 'field_name' );

As it turns out, there were actually two elements with that id. The first element with this id is the widget in the Available Widgets section. This is the section where you click & drag the widget to a sidebar. This is element the jQuery selector was returning to me.

The widget name and description.

And the markup:

enter image description here

The Solution

I had a click listener that was dynamically adding hidden input boxes with the field name. So, I used jQuery's tree traversal methods to go back up to widget's form element and traverse back down to the element with the #order_field_name id. From there, I grabbed the field_name attribute, which has the correct field_name.

$( 'a.add-schedulable' ).click( function( evt ) {

  // ... code omitted ...

  var widget_field_name = $( this ).parents( 'form' ).find( '#order_field_name' ).attr( 'field_name' );

   // ... code omitted ...
}); 

From there, I used a bit of javascript & jQuery to create a hidden input element with the desired attribute, which looks something similar to this:

<input 
  type="hidden" 
  name="widget-hours-widget[3][order][]" 
  value="L13"> 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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