0

Ok so here's the question how do i stop js from running twice on the widget.php page? I am creating a ajax loaded custom image selector from a domain on the same server as the current site. I want the user to be able to pick an image and populate the fields below with the href to the image description, the title of the image and the image src in it's self, this then posts the results on the front end in the sidebar.

I have registered a custom widget inside of my functions.php, the widget has custom js inside it the code is as follows:

/*
*
*Ajax loaded gallery for sidebar
*Note this will not work cross browser.
*
*
*/
/**
 * Plugin Name: A gallery Widget
 * Description: A widget that displays an ajax loaded gallery.
 * Version: 0.1
 */

add_action( 'widgets_init', 'my_widget' );

function my_widget() {
  register_widget( 'MY_Widget' );
}

class MY_Widget extends WP_Widget {

  function MY_Widget() {
    $widget_ops = array( 'classname' => 'example', 'description' => __('A widget that displays the chosen gallery images and link from lundhs ', 'example') );

    $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );

    $this->WP_Widget( 'example-widget', __('Reference Projects', 'example'), $widget_ops, $control_ops );
  }

  function widget( $args, $instance ) {
    extract( $args );

    //Our variables from the widget settings.
    $titlewidget = apply_filters('widget_title', $instance['titlewidget'] );
    $introtext = $instance['introtext'];
    $title = $instance['title'];
    $name = $instance['name'];
    $img = $instance['img'];
    $show_info = isset( $instance['show_info'] ) ? $instance['show_info'] : false;

    echo $before_widget;

?>
<?php
if($titlewidget)
  ?>

<h4 class="widget-title"><?php echo $titlewidget;?></h4>
<?php
if($introtext)
?>
<p> <?php echo $introtext; ?></p>
    <div class="row">
<?php
//display gallery img
if ( $img)
  ?>
<a class="columns four" href="<?php echo $name; ?>">
     <img class="imggallery" src="<?php echo $img; ?>">
   </a>
    <?php
  // Display the gallery name and link
    if ( $title )
      ?>
     <a class="columns eight imggallery_link" href="<?php echo $name; ?>"><?php echo $title; ?></a>

</div>

<?php
    echo $after_widget;
  }

  //Update the widget 

  function update( $new_instance, $old_instance ) {
    $instance = $old_instance;

    //Strip tags from title and name to remove HTML
    $instance['titlewidget'] = strip_tags( $new_instance['titlewidget'] );
    $instance['introtext'] = strip_tags( $new_instance['introtext'] );
    $instance['title'] = strip_tags( $new_instance['title'] );
    $instance['name'] = strip_tags( $new_instance['name'] );
    $instance['show_info'] = $new_instance['show_info'];
    $instance['img'] = $new_instance['img'];

    return $instance;
  }

  function form( $instance ) {

    //Set up some default widget settings.
    $defaults = array( 'title' => __('Example', 'example'), 'introtext' => __('introtext', 'example'), 'titlewidget' => __('Reference Project', 'example'), 'img' => __('img', 'example'), 'name' => __('link goes here', 'example'), 'show_info' => true );
    $instance = wp_parse_args( (array) $instance, $defaults ); ?>
<script type="text/javascript">
(function($) {

//load on page load
  $(".area").load("/galleries/ #projects > li a");

//load on widget title click
            $('.widget-top').live("click", function() {
             $(".area").load("/galleries/ #projects > li a");
            });

//stop default href from working
            $('.area a').unbind().live("click", function() {
                             event.preventDefault();
                             return;
             });
//load into input boxes
$(".area a").live("click", function() {
      var title = $(this).attr('title');
      $(".title").val(title);
      var link = $(this).attr('href');
      $(".link").val(link);
      var img = $("img", this).attr('src');
      $(".img").val(img);
      var imgexample = $("img", this).attr('src');
      $(".gallery_one").attr("src", imgexample);
    });
}(jQuery));
</script>
<style type="text/css">
.area img{
    max-width: 100px;
    max-height: 100px;
    display: inline-block;
}
.area a{
    max-width: 100px;
    max-height: 100px;
    display: inline-block;
}
.gallery_one_image_wrap{
  width: 100%;
height: 150px;
}
.gallery_one{
max-width: 80%;
max-height: 150px;
width: 80%;
margin: auto;
padding-left: 10%;
padding-right: 10%;
}
</style>
<script type="text/javascript">
(function($) {
        var addDiv = jQuery('.addinput');
        var i = jQuery('.addinput p').size() + 1;

    jQuery('.addNew').live('click', function() {
        jQuery.append('<p><input type="text" class="p_new' + i +'" size="40" name="p_new_' + i +'" value="" placeholder="I am New" /><a href="#" class="remNew">Remove</a> </p>');
        i + 1;

        return false;
    });

    jQuery('.remNew').live('click', function() {
          if( i > 1 ) {
          jQuery(this).parents('p').remove();
          i - 1;
          }
    return false;
    });
}(jQuery));

</script>
   <h3>Gallery selector for Lundhs</h3>
    <p>
    <label for="<?php echo $this->get_field_id( 'titlewidget' ); ?>"><?php _e('Widget Title:', 'example'); ?></label>
      <input type="text" class="titlewidget" name="<?php echo $this->get_field_name( 'titlewidget' ); ?>" value="<?php echo $instance['titlewidget']; ?>" style="width:100%;" />
    </p>
    <p>
    <label for="<?php echo $this->get_field_id( 'introtext' ); ?>"><?php _e('Intro text:', 'example'); ?></label>
      <input type="text" class="introtext" name="<?php echo $this->get_field_name( 'introtext' ); ?>" value="<?php echo $instance['introtext']; ?>" style="width:100%;" />
    </p>
      <h4 style="text-align: center;">First Pick your images</a>
    <div class="area"></div>

<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
    <h3>Your current front end projects</h3>
    <h4>Reference project one</h4>
    <div class="gallery_one_image_wrap">
    <img class="gallery_one" src="<?php echo $instance['img']; ?>" /><br/>
    </div>
    <p>
      <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'example'); ?></label>
      <input type="text" class="title" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
    </p>
    <p>
      <label for="<?php echo $this->get_field_id( 'name' ); ?>"><?php _e('The link:', 'example'); ?></label>
      <input type="text" class="link" id="<?php echo $this->get_field_id( 'name' ); ?>" name="<?php echo $this->get_field_name( 'name' ); ?>" value="<?php echo $instance['name']; ?>" style="width:100%;" />
    </p>

    //img Input.
    <p>
      <label for="<?php echo $this->get_field_id( 'img' ); ?>"><?php _e('The Link to the image:', 'example'); ?></label>
      <input type="text" class="img" id="<?php echo $this->get_field_id( 'img' ); ?>" name="<?php echo $this->get_field_name( 'img' ); ?>" value="<?php echo $instance['img']; ?>" style="width:100%;" />
    </p>
<div class="addinput">
<p>
<a href="#" class="addNew">Add new project</a>
</p>
</div>
  <?php
  }
}

the problem arises because this js runs twice adding the additional input boxes twice when '.addNew' is clicked.

    (function($) {
        var addDiv = jQuery('.addinput');
        var i = jQuery('.addinput p').size() + 1;

    jQuery('.addNew').live('click', function() {
        jQuery.append('<p><input type="text" class="p_new' + i +'" size="40" name="p_new_' + i +'" value="" placeholder="I am New" /><a href="#" class="remNew">Remove</a> </p>');
        i + 1;

        return false;
    });

    jQuery('.remNew').live('click', function() {
          if( i > 1 ) {
          jQuery(this).parents('p').remove();
          i - 1;
          }
    return false;
    });
}(jQuery));

the latter code runs twice once in the inactive widgets on the left and once in the active widget in the sidebar. How do i go about forcing the JS to run only in the currently active widget. Moving the js to a separate .js file and enqueing really isn't an option for me because i am going to have to use php values inside the php to populate and retrive the values in the next step of this build. Any help is appreciated. Chris //UPDATE// Right i think the function i'm looking for is is_active_widget() (codex) but I just can't seem to get it to work it still runs the js twice even if i set $skip_inactive to true.
so far I've tried this:

    //start gallery widget

add_action( 'widgets_init', 'my_widget' );

function my_widget() {
  register_widget( 'MY_Widget' );
}

class MY_Widget extends WP_Widget {

  function MY_Widget() {

    $widget_ops = array( 'classname' => 'example', 'description' => __('A widget that displays the chosen gallery images and link from lundhs ', 'example') );
    
    $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );
    
    $this->WP_Widget( 'example-widget', __('Reference Projects', 'example'), $widget_ops, $control_ops );
  }


  function widget( $args, $instance ) {

    extract( $args );

    //Our variables from the widget settings.
    $titlewidget = apply_filters('widget_title', $instance['titlewidget'] );
    $introtext = $instance['introtext'];
    $title = $instance['title'];
    $name = $instance['name'];
    $img = $instance['img'];
    $show_info = isset( $instance['show_info'] ) ? $instance['show_info'] : false;

    echo $before_widget;

?>
<?php 
if($titlewidget)
  ?>


<h4 class="widget-title"><?php echo $titlewidget;?></h4>
<?php 
if($introtext)
?>
<p> <?php echo $introtext; ?></p>
    <div class="row">
<?php 
//display gallery img
if ( $img)
  ?>
<a class="columns four" href="<?php echo $name; ?>">
     <img class="imggallery" src="<?php echo $img; ?>">
   </a>
    <?php
  // Display the gallery name and link 
    if ( $title )
      ?>
     <a class="columns eight imggallery_link" href="<?php echo $name; ?>"><?php echo $title; ?></a>

</div>

<?php    
    echo $after_widget;
  }

  //Update the widget 
   
  function update( $new_instance, $old_instance ) {
    $instance = $old_instance;

    //Strip tags from title and name to remove HTML 
    $instance['titlewidget'] = strip_tags( $new_instance['titlewidget'] );
    $instance['introtext'] = strip_tags( $new_instance['introtext'] );
    $instance['title'] = strip_tags( $new_instance['title'] );
    $instance['name'] = strip_tags( $new_instance['name'] );
    $instance['show_info'] = $new_instance['show_info'];
    $instance['img'] = $new_instance['img'];


    return $instance;
  }

  
  function form( $instance ) {
 if ( is_active_widget( false, false, $this->id_base, true ) ) {?>
<script type="text/javascript">
    jQuery(document).ready(function($) {
//load on page load
 alert('this is the if!');
});
    </script>


  <?php
} 

  else { 
    ?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
});
    </script>

<?php  
}

    //Set up some default widget settings.
    $defaults = array( 'title' => __('Example', 'example'), 'introtext' => __('introtext', 'example'), 'titlewidget' => __('Reference Project', 'example'), 'img' => __('img', 'example'), 'name' => __('link goes here', 'example'), 'show_info' => true );
    $instance = wp_parse_args( (array) $instance, $defaults ); 
    wp_localize_script( 'some_handle', 'object_name', $instance );
    ?>
   <h3>Gallery selector for Lundhs</h3>
    <p>
    <label for="<?php echo $this->get_field_id( 'titlewidget' ); ?>"><?php _e('Widget Title:', 'example'); ?></label>
      <input type="text" class="titlewidget" name="<?php echo $this->get_field_name( 'titlewidget' ); ?>" value="<?php echo $instance['titlewidget']; ?>" style="width:100%;" />
    </p>
    <p>
    <label for="<?php echo $this->get_field_id( 'introtext' ); ?>"><?php _e('Intro text:', 'example'); ?></label>
      <input type="text" class="introtext" name="<?php echo $this->get_field_name( 'introtext' ); ?>" value="<?php echo $instance['introtext']; ?>" style="width:100%;" />
    </p>
      <h4 style="text-align: center;">First Pick your images</a>
    <div class="area"></div>

<p></p>
<p></p>
<p></p>
<p></p>
<p></p>
    <h3>Your current front end projects</h3>
    <h4>Reference project 1</h4>
    <div class="gallery_one_image_wrap">
    <img class="gallery_one" src="<?php echo $instance['img']; ?>" /><br/>
    </div>
    <p>
      <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'example'); ?></label>
      <input type="text" class="title" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" />
    </p>
    <p>
      <label for="<?php echo $this->get_field_id( 'name' ); ?>"><?php _e('The link:', 'example'); ?></label>
      <input type="text" class="link" id="<?php echo $this->get_field_id( 'name' ); ?>" name="<?php echo $this->get_field_name( 'name' ); ?>" value="<?php echo $instance['name']; ?>" style="width:100%;" />
    </p>
    
    //img Input.
    <p>
      <label for="<?php echo $this->get_field_id( 'img' ); ?>"><?php _e('The Link to the image:', 'example'); ?></label>
      <input type="text" class="img" id="<?php echo $this->get_field_id( 'img' ); ?>" name="<?php echo $this->get_field_name( 'img' ); ?>" value="<?php echo $instance['img']; ?>" style="width:100%;" />
    </p>
<div class="addinput">
<p>
<a href="#" class="addNew">Add new project</a>
</p>
</div>
  <?php
  }
}

I have also tried moving it into the class MY_Widget extends WP_Widget { } then adding the add_action. Like so:

    class MY_Widget extends WP_Widget {

  function MY_Widget() {
    $widget_ops = array( 'classname' => 'example', 'description' => __('A widget that displays the chosen gallery images and link from lundhs ', 'example') );
    
    $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'example-widget' );
    
    $this->WP_Widget( 'example-widget', __('Reference Projects', 'example'), $widget_ops, $control_ops );
  }
  add_action('widgets_init', 'jsadd');
  function jsadd(){

 if ( is_active_widget( false, false, 'MY_Widget', true ) ) {?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
  alert("we made it this far and this is the If!!");
});
    </script>


  <?php
} 

  else { 
    ?>
    <script type="text/javascript">
jQuery(document).ready(function($) {
  // Stuff to do as soon as the DOM is ready;
  alert("we made it this far!!");
});
    </script>

<?php  
}

  }

but still no luck. DOes anybody know what i'm doing wrong here?

1 Answer 1

1

Use wp_enqueue_script. You assign a name to your js file when enqueued, and it will stop a file from being enqueued multiple times. Right now your JS is simple enough, but as it gets more complex, it's better to have it outside in it's on .js file.

add_action( 'wp_enqueue_scripts', 'add_my_js' );
function add_my_js() {
    wp_enqueue_script( 'my-script', get_stylesheet_directory_uri() . '/js/my-script.js' );
}

To add variables to your JS files, look at wp_localize_script. this allows you to point to the same JS handle (in this case, my-script, and attach variables onto them through a single object. Example:

 add_action( 'wp_enqueue_scripts', 'add_my_js' );
    function add_my_js() {
        wp_enqueue_script( 'my-script', get_stylesheet_directory_uri() . '/js/my-script.js' );
       wp_localize_script( 'my-script', 'myData', array( 'var1' => $variable1, 'var2' => $something_else ) );
    }

Then, within your JS file, you can call upon myData.var1 and myData.var2 in Object notation.

One thing to keep in mind here is those variables need to already be set by the time the wp_enqueue_scripts action is called, so best do the declarations before then, or within your function if not already set.

7
  • my problem with using that is that i am going to have to use php variables inside of the js as this build progresses. and I have no clue how to move the variables from the php file through to the js file..
    – vimes1984
    Jul 17, 2013 at 13:39
  • 1
    Just edited answer, take a look at wp_localize_script. Example is above. It creates a JS object after your script has been loaded in, so you have access to the variables declared. Jul 17, 2013 at 13:49
  • the example you have given is to queue scripts on the front end not on the admin pages for that 'admin_enqueue_scripts' is used inside the wp_enqueue.
    – vimes1984
    Jul 17, 2013 at 14:19
  • And concerning using wp_localize_script to deal with the array, this would mean i have to declare this inside of my widget class which means that the answer you gave isn't right, inside of the class this is the way to do it like it says here but when i add this into my existing class i get the following error.Notice: Undefined property: MY_Widget::$option_name in wp-includes/widgets.php on line 291 Warning: array_merge() [function.array-merge]: Argument #2 is not an array in wp-includes/widgets.php on line 777 codex.wordpress.org/Function_Reference/add_action
    – vimes1984
    Jul 17, 2013 at 14:20
  • You would need to post your code for me to debug it for you, but it looks like your MY_Widget::$option_name is set in an action after admin_enqueue_scripts is called. As for the second warning, that's on your side, passing a string, or null, as a parameter in array_merge. Jul 17, 2013 at 14:28

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.