【问题标题】:Dynamic input fields in WordPress widgetsWordPress 小部件中的动态输入字段
【发布时间】:2017-04-26 18:29:29
【问题描述】:

我正在尝试为我正在处理的主题的自定义小部件中的一组预定义标签创建动态输入字段。我想实现这样的目标:

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  ( - )
                                                       ( + )
--------------------------------------------------------------

其中CourseName 是 Chemistry 、Biology、Math 和 Physics(仅预定义标签,最多 4 个),FieldONEFieldTWO 是动态输入,我想为每门课程输入不同的术语。

因此,如果我单击( + ),则会为该标签创建两个字段FieldOneFieldTWO。如果我点击( - ),这两个字段都会被删除。

我尝试使用this Gist 创建与元框类似的动态输入,到目前为止我得到了这个:

<?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');

这是一个截图:

现在有很多问题,首先javascript“添加”按钮不再起作用,我不知道如何保存数据以便以后访问。

知道如何为标签制作动态输入字段吗?它不必与我分享的 gist 中的代码相似,但最好让我的修改生效。

【问题讨论】:

  • 首先你要添加 jQuery(并且不正确),这在 Wordpress 中通常不需要并且可能会导致冲突问题
  • @TimHallman 是的,这只是为了测试,javascript 没有工作,所以我通过添加 jquery 库来测试它。
  • 嗨@RainMan 你需要这个小部件在前端可见吗?这个字段应该从用户那里收集数据并且管理员用户可以访问,对吗?
  • @oserk 是的,没错

标签: javascript jquery wordpress widget


【解决方案1】:

试试这个代码,我测试了它,它可以工作。 js代码需要插入footer而不是widget,否则点击按钮会被执行两次。

在函数widget()中,你会看到显示输入值的循环。

    <?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');

数据将存储在 $instance['repeat"] 这样的数组中(以了解我是如何制作循环的)

    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)

【讨论】:

  • 我一定是遗漏了一些东西,你如何添加新字段并在使用 js 时调用 get_field_name ?
  • 它在 wordpress 小部件部分运行良好。但它不适用于 Elementor 管理面板,因为 javascript 未在 Elementor 管理页面上加载。如何为 Elementor 加载 javascript?
【解决方案2】:

我认为自定义这个插件可能会达到目的:https://wordpress.org/plugins/advanced-custom-fields-table-field/installation/

【讨论】:

  • 我不想使用任何额外的插件
  • @RainMan 虽然我理解避免使用额外插件的必要性,但 Advanced Custom Fields 是一款制作精良、积极维护且通常很棒的插件。如果您想编写自定义字段,这就是这样做的方法。它将节省大量创建新字段的时间,这通常对你自己来说是一件痛苦的事情,而就我的目的而言,这对于我所做的每个 WordPress 项目都是绝对必要的。我基本上拒绝在没有 ACF 的情况下做 WordPress。专业版的开发许可证是一次性费用。避免使用这个插件,你会自取其辱。
【解决方案3】:

更新

        <?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');

【讨论】:

    【解决方案4】:
            <?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');
    

    更新

    似乎工作正常。

    【讨论】:

    • 您好,问题不只是添加新行的javascript,而是如何存储特定标签的数据,而且您的代码没有运行,您确定这是您更改的唯一行吗?
    • 可以保存序列化的数据。保持隐藏键。
    • 你提到这是'首先javascript“添加”按钮不再起作用'
    • 你测试过这个吗?我无法让添加按钮工作
    • $(.'empty-row .screen-reader-text ').clone(); .添加空间空行。 .screen-reader-text
    【解决方案5】:

    我个人遇到的主要问题是无法使用 $this-&gt;get_field_name( '{{field}}' ) 使用 js 动态创建行时。 这是我对问题的解决方案:

    function getFieldName(field){
        var pattern = '<?=$this->get_field_name( "{{field}}" )?>';
        return pattern.replace('{{field}}', field);
    }
    

    我知道这不是你的问题,但它仍然可以帮助某人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 2012-10-09
      • 1970-01-01
      • 2018-11-18
      • 2017-07-06
      相关资源
      最近更新 更多