Home>Support>Multiple not-siteorigin widgets not saving correct

Multiple not-siteorigin widgets not saving correct

Hi all,

Has the SiteOrigin builder an other way to save widget data?
I have a plugin with a simple custom widget with just a title and multiselect field. Normally the multiselect saves as a normal single array with the selected values.

When I use this plugin in the builder, this array is saved in another array as 0 key. And when I use 2 instances on the same page, only 1 can have saved values.

Does the widget needs some enhancements to work with the builder?

This is our free support forum. Replies can take several days. If you need fast email support, please purchase a SiteOrigin Premium license.

  1. 11 days, 4 minutes ago Alex S Hi, I Work Here

    Hi Frietsje,

    We don’t modify how widgets are saved so if your widget saves correctly when added to the standard widgets page it should save without issue when added to SieOrigin Page Builder.

    Is your multi-select field a standard select with multiple enabled, or is it something a little more complicated?
    Is the code of your widget online somewhere?

  2. 10 days, 23 hours ago frietsje

    Hi Alex,

    It’s a standard select with multiple indeed. The widget class is the same as the wordpress tutorial, just with the extra field.

    I’ve added two screenshots of the widget, after it’s saved. I output the $instance[‘selectfield’] in both cases.
    Normal widget area:

    Siteorigin widget area:

    Note: if I save a second instance in the builder, the first gets emptied.

  3. 10 days, 23 hours ago Alex S Hi, I Work Here

    Hi Frietsje,

    Unfortunately, we’re unable to process attachments at this time. Can you please upload your screenshots to a third party image hosting site like Imgur or vgy.me and send me a link to the images?

  4. 10 days, 23 hours ago frietsje

    Sorry, images are not working. New try on imgur

  5. 10 days, 18 hours ago Alex S Hi, I Work Here

    Hi Frietsje,

    Thanks. Can you please provide me with a copy of your widget’s code so I can take a look over it?

  6. 10 days, 17 hours ago frietsje

    Yes, of course:

    <?php
    class Vdb_Ratio_Widget extends WP_Widget {
    
    	/**
    	 * The ID of this plugin.
    	 *
    	 * @since    1.0.0
    	 * @access   private
    	 * @var      string    $plugin_name    The ID of this plugin.
    	 */
    	private $plugin_name;
    
    	/**
    	 * Meta prefix
    	 *
    	 * @since   1.0.0
    	 * @access  private
    	 * @var     string  $prefix
    	 */
    	private $prefix;
    
    	/**
    	 * Register widget with WordPress.
    	 */
    	function __construct() {
    		$this->plugin_name = 'vdb-ratio';
    		$this->prefix      = $this->plugin_name.'-';
    
    		parent::__construct(
    			$this->prefix.'widget',
    			esc_html__( 'Van der Biesen - Ratio Widget', $this->plugin_name ),
    			array( 'description' => esc_html__( 'A nice Widget', $this->plugin_name ), )
    		);
    	}
    
    	private function get_trips($ids = []){
    		$args = [
    			'post_type' => $this->prefix.'trip',
    			'posts_per_page' => -1,
    		];
    		if(!empty($ids)){
    			if(!is_array($ids)){
    				$ids = [$ids];
    			}
    			$args['post__in'] = $ids;
    		}
    		return new WP_Query($args);
    	}
    
    	/**
    	 * Front-end display of widget.
    	 *
    	 * @see WP_Widget::widget()
    	 *
    	 * @param array $args     Widget arguments.
    	 * @param array $instance Saved values from database.
    	 */
    	public function widget( $args, $instance ) {
    	    //echo "<pre>".print_r($instance['trips'],1)."</pre>";
    		echo $args['before_widget'];
    		if ( ! empty( $instance['title'] ) ) {
    			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
    		}
    		if ( ! empty( $instance['trips'] ) ) {
    			$trips = $this->get_trips($instance['trips']);?>
    			<div class="<?php echo $this->prefix?>trips">
    				<?php foreach($trips->posts as $trip){ ?>
    					<div class="<?php echo $this->prefix?>trips__trip">
    						<div class="<?php echo $this->prefix?>trips__trip__image">
    							<?php echo wp_get_attachment_image(get_post_thumbnail_id($trip->ID), 'medium'); ?>
    						</div>
    						<div class="<?php echo $this->prefix?>trips__trip__content">
    							<div class="<?php echo $this->prefix?>trips__trip__content__title">
    								<?php echo $trip->post_title;?>
    							</div>
    							<div class="<?php echo $this->prefix?>trips__trip__content__depart-from">
    								<?php echo __('Leaving: ',$this->plugin_name) . date('d-m-Y',strtotime(get_post_meta($trip->ID,$this->prefix.'depart-from',true))); ?>
    							</div>
    							<div class="<?php echo $this->prefix?>trips__trip__content__price-from">
    								€ <?php echo get_post_meta($trip->ID,$this->prefix.'price-from', true); ?>
    							</div>
    							<a href="<?php the_permalink($trip->ID) ?>"><?php _e('View',$this->plugin_name) ?></a>
    						</div>
    					</div>
    					<?php
    				}?>
    			</div>
    			<?php
    		}
    
    		echo $args['after_widget'];
    	}
    
    	/**
    	 * Back-end widget form.
    	 *
    	 * @see WP_Widget::form()
    	 *
    	 * @param array $instance Previously saved values from database.
    	 */
    	public function form( $instance ) {
    		//echo "<pre>".print_r($instance['trips'],1)."</pre>";
    		$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', $this->plugin_name );
    		$trips = ! empty( $instance['trips'] ) ? $instance['trips'] : [];
    		$trips_list = $this->get_trips();
    		?>
    		<p>
    			<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', $this->plugin_name ); ?></label>
    			<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
    		</p>
    		<p>
    			<label for="<?php echo esc_attr( $this->get_field_id( 'trips' ) ); ?>"><?php esc_attr_e( 'Trips:', $this->plugin_name ); ?></label>
    			<select size="10" multiple="multiple" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'trips' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'trips' ) ); ?>[]">
    				<?php foreach($trips_list->posts as $item): ?>
    					<?php $selected = (in_array($item->ID,$trips))? 'selected="selected"':''; ?>
    					<option <?php echo $selected ?> value="<?php echo $item->ID ?>"><?php echo $item->post_title ?></option>
    				<?php endforeach;?>
    			</select>
    		</p>
    		<?php
    	}
    
    	/**
    	 * Sanitize widget form values as they are saved.
    	 *
    	 * @see WP_Widget::update()
    	 *
    	 * @param array $new_instance Values just sent to be saved.
    	 * @param array $old_instance Previously saved values from database.
    	 *
    	 * @return array Updated safe values to be saved.
    	 */
    	public function update( $new_instance, $old_instance ) {
    		$instance = array();
    		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
    		$instance['trips'] = ( ! empty( $new_instance['trips'] ) ) ? esc_sql( $new_instance['trips'] ) : '';
    		return $instance;
    	}
    
    }
    
  7. 10 days, 17 hours ago Alex S Hi, I Work Here

    Hi Frietsje,

    Thanks. The issue you’re facing is caused by adding [] to the select name. You shouldn’t need to do this for your select field to work.

    <select size="10" multiple="multiple" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'trips' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'trips' ) ); ?>[]">
  8. 9 days, 21 hours ago frietsje

    Hmm the builder is now processing it correct, but the original widget isn’t finding an array as posted value, so only saves one single value.
    I’ll dig into that later, at least the builder is working now and I know where’s the trouble :)

    Thanks!

  9. 9 days, 21 hours ago Alex S Hi, I Work Here

    Hi Frietsje,

    I recommend giving the the SiteOrigin Widgets Bundle developer docs a look. The SiteOrigin Widgets Bundle isn’t just a series of widgets, it’s an entire development framework that makes making widgets an absolute breeze.

  10. 9 days, 21 hours ago frietsje

    I know, I’ve made a lot of SiteOrigin widgets for a client (I love how easy that is by the way :) ). But this is a separate plugin not specific for the SiteOrigin builder.

Please log in to post on our forums. Signing up is free.

Get The Most Out of SiteOrigin with SiteOrigin Premium

Find Out More