Wordpress - Adding Widget form fields dynamically
Interesting Question!
I've never seen repeatable fields used in Widgets. Giving a full Answer would require too much work/time, so I'll give you links to the resources I know, and hopefully you'll make this work and share the solution with us ;)
All this examples deal with Meta Boxes, you'll need to copy the jQuery scripts and adapt the post_meta
to the Widgets case.
Create more Meta Boxes as needed - WPSE Q&A
Repeatable Custom Fields in a Metabox - Gist
/** * Repeatable Custom Fields in a Metabox * Author: Helen Hou-Sandi * * From a bespoke system, so currently not modular - will fix soon * Note that this particular metadata is saved as one multidimensional array (serialized) */
Repeatable Custom Fields in a Metabox - Another Gist example, no description given. This one is quite interesting as it has the code to sort the fields.
This is an example of a dynamic widget that renders two fields (image-id and url). if you enter an image-id and press "update", two new fields are added. I build it to create a slick slilder with images and linked url's.
<?php
class imp_image_slider extends WP_Widget
{
/**
* imp_image_slider constructor.
*/
public function __construct()
{
parent::__construct(false, $name = "Impulse Image Slider", array("description" => "Creates Slick Image Slider"));
}
/**
* @see WP_Widget::widget
*
* @param array $args
* @param array $instance
*/
public function widget($args, $instance)
{
// render widget in frontend
}
/**
* @see WP_Widget::update
*
* @param array $newInstance
* @param array $oldInstance
*
* @return array
*/
public function update($newInstance, $oldInstance)
{
$instance = $oldInstance;
$instance['images'] = array();
$instance['urls'] = array();
if (isset($newInstance['images'])) {
foreach ($newInstance['images'] as $key => $value) {
if (!empty(trim($value))) {
$instance['images'][$key] = $value;
$instance['urls'][$key] = $newInstance['urls'][$key];
}
}
}
return $instance;
}
/**
* @see WP_Widget::form
*
* @param array $instance
*/
public function form($instance)
{
$images = isset($instance['images']) ? $instance['images'] : array();
$urls = isset($instance['urls']) ? $instance['urls'] : array();
$images[] = '';
$form = '';
foreach ($images as $idx => $value) {
$image = isset($images[$idx]) ? $images[$idx] : '';
$url = isset($urls[$idx]) ? $urls[$idx] : '';
$form .= '<p>'
. '<label>Slides:</label>'
. sprintf(
'<input type="text" name="%1$s[%2$s]" value="%3$s" class="widefat" placeholder="Image ID">',
$this->get_field_name('images'),
$idx,
esc_attr($image))
. '</p>'
. '<p>'
. sprintf(
'<input type="text" name="%1$s[%2$s]" value="%3$s" class="widefat" placeholder="Url">',
$this->get_field_name('urls'),
$idx,
esc_attr($url))
. '</p>';
}
echo $form;
}
}
add_action('widgets_init', create_function('', 'return register_widget("imp_image_slider");'));
?>