Dynamic input fields in WordPress widgets

I am trying to create dynamic input fields for a set of predefined labels in a custom widget for the theme I'm working on. I want to achieve something like this:

CourseName FieldONE FieldTWO ------------------------------------------------------------- Chemistry Sprint 2015 Summer 2015 ( - ) Spring 2016 Summer 2016 ( - ) ( + ) ------------------------------------------------------------- Biology Sprint 2015 Summer 2015 ( - ) Fall 2015 Winter 2015 ( - ) Spring 2016 Summer 2016 ( - ) ( + ) -------------------------------------------------------------- Math Fall 2015 Winter 2015 ( - ) ( + ) -------------------------------------------------------------- Physics Fall 2015 Winter 2015 ( - ) ( + ) -------------------------------------------------------------- 

where CourseName is chemistry, biology, mathematics and physics (only predefined labels, maximum 4) and FieldONE and FieldTWO are dynamic inputs where I want to introduce different terms for each course.

So, if I click on ( + ) , two fields FieldONE and FieldTWO are created for this shortcut. And if I click on ( - ) , both fields will be deleted.

I tried using this Gist , which creates a similar dynamic input as a metabolism, and so far I got this:

 <?php /* Plugin Name: Dynamic Fields Widget Description: Dynamic Fields Version: 0.0 Author: Rain Man */ // Creating the widget class dynamic_widget extends WP_Widget { public function __construct() { parent::__construct( // Base ID of your widget 'dynamic_widget', // Widget name will appear in UI __('Dynamic Widget', 'dynamic_widget_domain'), // Widget description array('description' => __('Sample Dynamic Widget', 'dynamic_widget_domain')) ); } // widget public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); // This is where you run the code and display the output echo __('Hello, World!', 'dynamic_widget_domain'); echo $args['after_widget']; } // form public function form($instance) { if (isset($instance[ 'title' ])) { $title = $instance[ 'title' ]; } else { $title = __('New title', 'dynamic_widget_domain'); } // Widget admin form $repeatable_fields = array(); $courses = array( 'Chemistry' => array( 'coursecode' => 'Chemistry 2059', 'professor' => 'Dr. James Bond', ), 'Biology' => array( 'coursecode' => 'Biology 3029', 'professor' => 'Dr. James Bond', ), 'Math' => array( 'coursecode' => 'Math 2043', 'professor' => 'Dr. James Bond', ), 'Physics' => array( 'coursecode' => 'Physics 2075', 'professor' => 'Dr. James Bond', ) ); ?> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function( $ ){ $( '#add-row' ).on('click', function() { var row = $( '.empty-row.screen-reader-text' ).clone(true); row.removeClass( 'empty-row screen-reader-text' ); row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' ); return false; }); $( '.remove-row' ).on('click', function() { $(this).parents('tr').remove(); return false; }); }); </script> <?php foreach ($courses as $course_key => $course_info) { ?> <label><?php echo $course_info['coursecode']; ?></label> <table id="repeatable-fieldset-one" width="100%"> <thead> <tr> <th width="40%">Fall Term</th> <th width="40%">Winter Term</th> <th width="8%"></th> </tr> </thead> <tbody> <?php if ($repeatable_fields) : foreach ($repeatable_fields as $field) { ?> <tr> <td><input type="text" class="widefat" name="name[]" value="<?php if ($field['name'] != '') { echo esc_attr($field['name']); } ?>" /></td> <td> </td> <td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') { echo esc_attr($field['url']); } else { echo ''; } ?>" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button" href="#">Add</a></td> </tr> <?php } else : // show a blank one ?> <tr> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button" href="#">Add</a></td> </tr> <?php endif; ?> <? } ?> <!-- empty hidden one for jQuery --> <tr class="empty-row screen-reader-text"> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button" href="#">Add</a></td> </tr> </tbody> </table> </p> <?php } // update public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : ''; return $instance; } } // Class dynamic_widget ends here // Register and load the widget function wpb_load_widget() { register_widget('dynamic_widget'); } add_action('widgets_init', 'wpb_load_widget'); 

and here is a screenshot:

enter image description here

there are a lot of problems right now, first the "Add" javascript button no longer works, and I'm not sure how to save access data later.

any idea how to make dynamic input fields for labels? It should not be like the code from the existing one that I used, but it would be better if we could make my changes work.

+7
javascript jquery wordpress widget
source share
4 answers

Try this code, I tested it and it works. The js code must be inserted into the footer not in the widget, otherwise the click button will be executed twice.

In the widget () function, you will see that the loop displays the input values.

  <?php /* Plugin Name: Dynamic Fields Widget Description: Dynamic Fields Version: 0.0 Author: Rain Man */ // Creating the widget class dynamic_widget extends WP_Widget { public $courses; public function __construct() { parent::__construct( // Base ID of your widget 'dynamic_widget', // Widget name will appear in UI __('Dynamic Widget', 'dynamic_widget_domain'), // Widget description array('description' => __('Sample Dynamic Widget', 'dynamic_widget_domain')) ); $this->courses = array( 'Chemistry' => array( 'coursecode' => 'Chemistry 2059', 'professor' => 'Dr. James Bond', ), 'Biology' => array( 'coursecode' => 'Biology 3029', 'professor' => 'Dr. James Bond', ), 'Math' => array( 'coursecode' => 'Math 2043', 'professor' => 'Dr. James Bond', ), 'Physics' => array( 'coursecode' => 'Physics 2075', 'professor' => 'Dr. James Bond', ) ); add_action( 'in_admin_footer',array( $this,'jsfooter')); } public function jsfooter() { ?> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function( $ ){ $(document ).off('click').on('click','div.open .add-row' , function() { var row = $(this).closest('tr').clone(true); row.find('input').each(function(){ $(this).val(""); }); // row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' ); $(this).parents('tr').after(row); return false; }); $( document).on('click', 'div.open .remove-row',function() { if ($(this).parents('tbody').find('tr').length >1) { $(this).parents('tr').remove(); } return false; }); }); </script> <?php } // widget public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); // This is where you run the code and display the output foreach ($this->courses as $course_key => $course_info) { echo $course_info['coursecode'] .'<br>'; foreach ($instance['repeat'][$course_key ]["fall"] as $k=>$field) { echo 'Fall Term ' . $field .' / '; echo 'Winter Term ' . $instance['repeat'][$course_key ]["winter"][$k] .'<br>'; } } echo $args['after_widget']; } // form public function form($instance) { if (isset($instance[ 'title' ])) { $title = $instance[ 'title' ]; } else { $title = __('New title', 'dynamic_widget_domain'); } // Widget admin form $repeatable_fields= isset ( $instance['repeat'] ) ? $instance['repeat'] : array(); ?> <?php foreach ($this->courses as $course_key => $course_info) { ?> <label><?php echo $course_info['coursecode']; ?></label> <table id="repeatable-fieldset-one" width="100%"> <thead> <tr> <th width="40%">Fall Term</th> <th width="40%">Winter Term</th> <th width="8%"></th> <th width="8%"></th> </tr> </thead> <tbody> <?php if ($repeatable_fields[$course_key ]["fall"] || $repeatable_fields[$course_key ]["winter"]) : foreach ($repeatable_fields[$course_key ]["fall"] as $k=>$field) { ?> <tr> <td><input type="text" class="widefat" name="<?php echo $this->get_field_name( 'repeat' )?>[<?php echo $course_key;?>][fall][]" value="<?php echo $field; ?>" /></td> <td><input type="text" class="widefat" name="<?php echo $this->get_field_name( 'repeat' )?>[<?php echo $course_key;?>][winter][]" value="<?php echo $repeatable_fields[$course_key ]["winter"][$k]; ?>" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a class="button add-row" class="button" href="#">Add</a></td> </tr> <?php } else : // show a blank one ?> <tr> <td><input type="text" class="widefat" name="<?php echo $this->get_field_name( 'repeat' )?>[<?php echo $course_key;?>][fall][]" /></td> <td><input type="text" class="widefat" name="<?php echo $this->get_field_name( 'repeat' )?>[<?php echo $course_key;?>][winter][]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a class="button add-row" class="button" href="#">Add</a></td> </tr> <?php endif; ?> </tbody> </table> <?php } ?> <!-- empty hidden one for jQuery --> <?php } // update public function update($new_instance, $old_instance) { $instance = array(); $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : ''; $instance['repeat'] = array(); if ( isset ( $new_instance['repeat'] ) ) { foreach ( $new_instance['repeat'] as $k =>$value ) { $instance['repeat'][$k] = $value; } } return $instance; } } // Class dynamic_widget ends here // Register and load the widget function wpb_load_widget() { register_widget('dynamic_widget'); } add_action('widgets_init', 'wpb_load_widget'); 

The data will be stored in $ instance ['repeat "] in such an array (to understand how I made the loop)

  array (size=4) 'Chemistry' => array (size=2) 'fall' => array (size=1) 0 => string 'AAA' (length=3) 'winter' => array (size=1) 0 => string 'BBBBBBB' (length=7) 'Biology' => array (size=2) 'fall' => array (size=2) 0 => string 'CCCCCC' (length=6) 1 => string 'EEEEEEE' (length=7) 'winter' => array (size=2) 0 => string 'DDDD' (length=4) 1 => string 'FFFFFFFF' (length=8) 'Math' => array (size=2) 'fall' => array (size=1) 0 => string 'GGGGGGG' (length=7) 'winter' => array (size=1) 0 => string 'HHHHHH' (length=6) 'Physics' => array (size=2) 'fall' => array (size=1) 0 => string 'IIIIIIIII' (length=9) 'winter' => array (size=1) 0 => string 'JJJJJJJJ' (length=8) 
+4
source share

I think that setting up this plugin might serve the purpose: https://wordpress.org/plugins/advanced-custom-fields-table-field/installation/

+1
source share
  <?php /* Plugin Name: Dynamic Fields Widget Description: Dynamic Fields Version: 0.0 Author: Rain Man */ // Creating the widget class dynamic_widget extends WP_Widget { public function __construct() { parent::__construct( 'dynamic_widget', __('Dynamic Widget', 'dynamic_widget_domain'), array('description' => __('Sample Dynamic Widget', 'dynamic_widget_domain')) ); } // widget public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); // This is where you run the code and display the output echo __('Hello, World!', 'dynamic_widget_domain'); echo $args['after_widget']; } // form public function form($instance) { if (isset($instance[ 'title' ])) { $title = $instance[ 'title' ]; } else { $title = __('New title', 'dynamic_widget_domain'); } // Widget admin form $repeatable_fields = array(); $courses = array( 'Chemistry' => array( 'coursecode' => 'Chemistry 2059', 'professor' => 'Dr. James Bond', 'id' => 'test1', ), 'Biology' => array( 'coursecode' => 'Biology 3029', 'professor' => 'Dr. James Bond', 'id' => 'test2', ), 'Math' => array( 'coursecode' => 'Math 2043', 'id' => 'test3', ), 'Physics' => array( 'coursecode' => 'Physics 2075', 'id' => 'test4', ) ); $Inc=1; foreach ($courses as $course_key => $course_info) { echo $Inc; ?> <label><?php echo $course_info['coursecode']; ?></label> <table id="repeatable-fieldset-<?php echo $course_info['id']; ?>" width="100%" class="tableclass"> <thead> <tr> <th width="40%">Fall Term</th> <th width="40%">Winter Term</th> <th width="8%"></th> </tr> </thead> <tbody> <?php if ($repeatable_fields): foreach ($repeatable_fields as $field) { ?> <tr> <td><input type="text" class="widefat" name="name[]" value="<?php if ($field['name'] != '') { echo esc_attr($field['name']);} ?>" /></td> <td></td> <td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') { echo esc_attr($field['url']); } else { echo ''; } ?>" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <?php } else: // show a blank one ?> <tr> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <tr class="tablerowclone"> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <?php endif; } ?> <? $Inc++; } ?> </tbody> </table> <style> .tablerowclone{display:none;} </style> </p> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function( $ ){ jQuery(document).off().on('click',' .addrowbtn', function(event) { event.preventDefault(); var row = jQuery(this).closest(".tableclass").find("tr:last").clone(); row.removeClass( 'tablerowclone' ); //row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' ); row.insertBefore(jQuery(this).closest(".tableclass").find("tbody tr.tablerowclone")); return false; }); jQuery(document).on('click', '.remove-row' , function() { var RowLenth = jQuery(this).closest("tbody").children().length; if(RowLenth>2){ jQuery(this).parents('tr').remove(); } return false; }); }); </script> <?php } public function update($new_instance, $old_instance){ $instance = array(); $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : ''; return $instance; } } function wpb_load_widget() { register_widget('dynamic_widget'); } add_action('widgets_init', 'wpb_load_widget'); 

Update

It seems to be working fine.

0
source share

Update .

  <?php /* Plugin Name: Dynamic Fields Widget Description: Dynamic Fields Version: 0.0 Author: Rain Man */ // Creating the widget class dynamic_widget extends WP_Widget { public function __construct() { parent::__construct( 'dynamic_widget', __('Dynamic Widget', 'dynamic_widget_domain'), array('description' => __('Sample Dynamic Widget', 'dynamic_widget_domain')) ); } // widget public function widget($args, $instance) { $title = apply_filters('widget_title', $instance['title']); // This is where you run the code and display the output echo __('Hello, World!', 'dynamic_widget_domain'); echo $args['after_widget']; } // form public function form($instance) { if (isset($instance[ 'title' ])) { $title = $instance[ 'title' ]; } else { $title = __('New title', 'dynamic_widget_domain'); } // Widget admin form $repeatable_fields = array(); $courses = array( 'Chemistry' => array( 'coursecode' => 'Chemistry 2059', 'professor' => 'Dr. James Bond', 'id' => 'test1', ), 'Biology' => array( 'coursecode' => 'Biology 3029', 'professor' => 'Dr. James Bond', 'id' => 'test2', ), 'Math' => array( 'coursecode' => 'Math 2043', 'id' => 'test3', ), 'Physics' => array( 'coursecode' => 'Physics 2075', 'id' => 'test4', ) ); $Inc=1; foreach ($courses as $course_key => $course_info) { echo $Inc; ?> <label><?php echo $course_info['coursecode']; ?></label> <table id="repeatable-fieldset-<?php echo $course_info['id']; ?>" width="100%" class="tableclass"> <thead> <tr> <th width="40%">Fall Term</th> <th width="40%">Winter Term</th> <th width="8%"></th> </tr> </thead> <tbody> <?php if ($repeatable_fields): foreach ($repeatable_fields as $field) { ?> <tr> <td><input type="text" class="widefat" name="name[]" value="<?php if ($field['name'] != '') { echo esc_attr($field['name']);} ?>" /></td> <td></td> <td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') { echo esc_attr($field['url']); } else { echo ''; } ?>" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <?php } else: // show a blank one ?> <tr> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <tr class="tablerowclone"> <td><input type="text" class="widefat" name="name[]" /></td> <td><input type="text" class="widefat" name="url[]" value="" /></td> <td><a class="button remove-row" href="#">Remove</a></td> <td><a id="add-row" class="button addrowbtn" href="#">Add</a></td> </tr> <?php endif; } ?> <? $Inc++; } ?> </tbody> </table> <style> .tablerowclone{display:none;} </style> </p> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function( $ ){ jQuery(document).off().on('click',' .addrowbtn', function(event) { event.preventDefault(); var row = jQuery(this).closest(".tableclass").find("tr:last").clone(); row.removeClass( 'tablerowclone' ); //row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' ); row.insertBefore(jQuery(this).closest(".tableclass").find("tbody tr.tablerowclone")); return false; }); jQuery(document).on('click', '.remove-row' , function() { var RowLenth = jQuery(this).closest("tbody").children().length; if(RowLenth>2){ jQuery(this).parents('tr').remove(); } return false; }); }); </script> <?php } public function update($new_instance, $old_instance){ $instance = array(); $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : ''; return $instance; } } function wpb_load_widget() { register_widget('dynamic_widget'); } add_action('widgets_init', 'wpb_load_widget'); 
0
source share

All Articles