web-dev-qa-db-ja.com

ウィジェットで動的フォーム/エントリーは可能ですか?

私はWordPressプラグインの開発に慣れていないので、このウィジェットを使い始めました。私の質問です:WordPressのウィジェットの制限は何ですか?

私はウィジェットフォームをよりインタラクティブ/動的にするためにjQueryを使用しようとしましたが、それはまったく機能していないようです。たとえば、クリックしたときに "Hello!"という文字列を追加するボタンがあります。 "here"というIDを持つdivに。

<div id="here"></div> 
<input type="button" id="add" value="Click Me!" " />

<script>

    jQuery(document).ready(function(){ 
             //call when the button is click
             $(document).on('click', '#add', function() {
                  $('#here').append('<p>Hello</p>');
             });
        });


</script>
  1. 「こんにちは」の段落がフォームに表示されないのはなぜですか。ウィジェット形式ではできないからですか。

  2. フロントエンドを更新するBackbone.jsについても聞きましたが、それがうまくいくかどうかはわかりません。

  3. 可能であれば、wordpressウィジェットクラス全体の動作を説明してください。前もって感謝します!

更新:私はすでに提案されていることを試しましたが、それでもまだうまくいきません。これが私のコードです

repeat.php

     <?php
    /**
     * Plugin Name: Repeat Field
     *
     */



     class repeat_field_widget extends WP_Widget {

        /**
         * Sets up the widgets name etc
         */
        public function __construct() {
            $widget_ops = array(
                'classname' => 'repeat_field_widget',
                'description' => 'Repeat Field for Name input',
            );
            parent::__construct( 'repeat_field_widget', 'Repeat Field', $widget_ops );
        }

        /**
         * Outputs the content of the widget
         *
         * @param array $args
         * @param array $instance
         */
        public function widget( $args, $instance ) {
            // outputs the content of the widget
        }

        /**
         * Outputs the options form on admin
         *
         * @param array $instance The widget options
         */
        public function form( $instance ) {
            // outputs the options form on admin
    ?>
        <div id="here"></div>
        <input type="button" id="addRepeat" value="Click Me!" />

      <?php
        }

        /**
         * Processing widget options on save
         *
         * @param array $new_instance The new options
         * @param array $old_instance The previous options
         */
        public function update( $new_instance, $old_instance ) {
            // processes widget options to be saved
        }
    }


    function register_repeat_field_widget() {
        register_widget( 'repeat_field_widget' );
    }
    add_action( 'widgets_init', 'register_repeat_field_widget' );

    function repeat_field_widget_scripts() {
    wp_enqueue_script( 'repeat-field-widget-scripts', get_template_directory_uri() . '/repeat.js', array( 'jquery' ), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'repeat_field_widget_scripts' );

repeat.js

    jQuery(document).ready(function($){
       //call when the button is click
       $("#addRepeat").click(function() {
           $('#here').append('<p>Hello</p>');
       });
    });
2
Sengngy Kouch

WordPressウィジェットでHTML IDを使用しないことについて指摘してくれてありがとうDave RomseyMark Kaplun。私はようやく自分のニーズに合った解決策を見つけました。

解決策:

3つの関数(ウィジェット、フォーム、更新)すべてにプリセット変数を追加する必要があります。私のコードでは、それらは "spotlight_image_link1、spotlight_image_link2など"と呼ばれています。それから "フォーム関数"でPHPコードを使用して彼らのIDを与えます。詳細については、以下の私のコードを読んでください。

私の解決策は何ができますか?

基本的に、すべてのスポットライトを事前に定義しておく必要があるため、完全に動的ではありません。私の場合は、コードを読みやすくするために2つのスポットライトのみを定義しました。

これは次のようになります。enter image description here

舞台裏のロジック:

  • いつでも「クリックしてください」ボタンをクリックするとスポットライトが追加されます。
  • 定義済みのスポットライトがすでに使用されていることを追跡する「トラッカー」と呼ばれるトラッカー配列があります。すべてのスポットライトを使用したら、[クリックしてください]を無効にします。ボタン。
  • 「スポットライトの削除」がクリックされたら、その特定のスポットライトを削除し、「クリックしてください」を再度有効にします。ボタン。各削除ボタンの名前には番号が付けられています。これにより、どのスポットライトを削除するかがわかります。
  • 入力が空でない場合に限り、スポットライトは保存されます。その条件は、 "form"関数の "while"ループにあります。

制限事項:

今のところ、「保存」をクリックするたびに、スポットライトの順序は1からnに変更されています。それはそれほどユーザーフレンドリーではありませんが、私はフロントエンドとバックエンドを同期させるためにAjaxを使うことを計画しています。まだわからない。

ソースコード:

  • WordPress 4.7.2以降、エラーなしで動作します。
  • すべてのソースコードをプラグインディレクトリの "repeat.php"ファイルに入れてください。方法がわからない場合は、グーグルしてください。

repeat.php

    <?php
/**
 * Plugin Name: Repeat Field
 *
 */

 class repeat_field_widget extends WP_Widget {

    /**
     * Sets up the widgets name etc
     */
    public function __construct() {
        $widget_ops = array(
            'classname' => 'repeat_field_widget',
            'description' => 'Repeat Field for Name input'
        );
        parent::__construct( 'repeat_field_widget', 'Repeat Field', $widget_ops );
    $tracker1;
    }

    /**
     * Outputs the content of the widget
     *
     * @param array $args
     * @param array $instance
     */
    public function widget( $args, $instance ) {
        // outputs the content of the widget
    $spotlight_add_row = ! empty( $instance['spotlight_add_row'] ) ? $instance['spotlight_add_row'] : '';
    $spotlight_row_appender = ! empty( $instance['spotlight_row_appender'] ) ? $instance['spotlight_row_appender'] : '';

    /**============== Spotlight 1 =========================*/
    $spotlight_image_link1 = ! empty( $instance['spotlight_image_link1'] ) ? $instance['spotlight_image_link1'] : '';
    $spotlight_add_image1 = ! empty( $instance['spotlight_add_image1'] ) ? $instance['spotlight_add_image1'] : '';
    $spotlight_image_preview1 = ! empty( $instance['spotlight_image_preview1'] ) ? $instance['spotlight_image_preview1'] : '';
    $spotlight_name1 = ! empty( $instance['spotlight_name1'] ) ? $instance['spotlight_name1'] : '';
    $spotlight_description1 = ! empty( $instance['spotlight_description1'] ) ? $instance['spotlight_description1'] : '';
    $spotlight_link1 = ! empty( $instance['spotlight_link1'] ) ? $instance['spotlight_link1'] : '';

    /**============== Spotlight 2 =========================*/
    $spotlight_image_link2 = ! empty( $instance['spotlight_image_link2'] ) ? $instance['spotlight_image_link2'] : '';
    $spotlight_add_image2 = ! empty( $instance['spotlight_add_image2'] ) ? $instance['spotlight_add_image2'] : '';
    $spotlight_image_preview2 = ! empty( $instance['spotlight_image_preview2'] ) ? $instance['spotlight_image_preview2'] : '';
    $spotlight_name2 = ! empty( $instance['spotlight_name2'] ) ? $instance['spotlight_name2'] : '';
    $spotlight_description2 = ! empty( $instance['spotlight_description2'] ) ? $instance['spotlight_description2'] : '';
    $spotlight_link2 = ! empty( $instance['spotlight_link2'] ) ? $instance['spotlight_link2'] : '';
    }

    /**
     * Outputs the options form on admin
     *
     * @param array $instance The widget options
     */
    public function form( $instance ) {
        // outputs the options form on admin
    $instance = wp_parse_args( (array) $instance, array( 'spotlight_add_row' => '', 'spotlight_row_appender' => '', 'spotlight_image_link1' => '', 'spotlight_add_image1' => '', 'spotlight_image_preview1' => '', 'spotlight_name1' => '', 'spotlight_description1' => '', 'spotlight_link1' => '',
    'spotlight_image_link2' => '', 'spotlight_add_image2' => '', 'spotlight_image_preview2' => '', 'spotlight_name2' => '', 'spotlight_description2' => '', 'spotlight_link2' => '' ));

    //Create Add and delete button
    $spotlight_add_row = $instance['spotlight_add_row'];
    $spotlight_row_appender = $instance['spotlight_row_appender'];

    /**================== Spotlight 1 ==============*/
    $spotlight_image_link1 = $instance['spotlight_image_link1'];
    $spotlight_add_image1 = $instance['spotlight_add_image1'];
    $spotlight_image_preview1 = $instance['spotlight_image_preview1'];
    $spotlight_name1 = $instance['spotlight_name1'];
    $spotlight_description1 = $instance['spotlight_description1'];
    $spotlight_link1 = $instance['spotlight_link1'];

    /**================== Spotlight 2 ==============*/
    $spotlight_image_link2 = $instance['spotlight_image_link2'];
    $spotlight_add_image2 = $instance['spotlight_add_image2'];
    $spotlight_image_preview2 = $instance['spotlight_image_preview2'];
    $spotlight_name2 = $instance['spotlight_name2'];
    $spotlight_description2 = $instance['spotlight_description2'];
    $spotlight_link2 = $instance['spotlight_link2'];

    $starter = 1; //Store which number to continue adding spotlight.
    $num = 1;
    $max_spotlight = 2; //number of spotlight allowed.
    static $tracker = array(0,0); //setup a tracker for each spotlight, zero mean none active.

    while($num <= $max_spotlight){
      $tempImage = 'spotlight_image_link' . $num;

       if ($$tempImage != ''){
        $starter++;
        $tracker[$num - 1] = 1;
?>
        <!-- Image input -->
        <div>
        <p class="spotlight-para">Spotlight <?php echo $num; ?></p>
        <p> <?php $tempImage = 'spotlight_image_link' . $num;  $tempDeleteName = 'deletespotlight_'. $num;?> <!-- store the combined name. -->
            <label for="<?php echo esc_attr( $this->get_field_id( $tempImage ) ); ?>"><?php esc_attr_e( 'Image\'s link:', 'text_domain' ); ?></label>
            <input
                   class="widefat"
                   id="<?php echo $this->get_field_id($tempImage); ?>"
                   name="<?php echo $this->get_field_name($tempImage); ?>"
                   type="text"
                   value="<?php echo esc_attr($$tempImage); ?>"
                   />
           <input style="float:right;" id="delete-spotlight" name="<?php echo $tempDeleteName; ?>" type="button" value="Delete Spotlight" class="button"/>
           <br />
        </p>
        </div>
<?php
      }
     $num++;
    }
    $id_prefix = $this->get_field_id(''); //get the widget prefix id.
?>
    <span id="<?php echo $this->get_field_id('spotlight_row_appender'); ?>"> </span>
    <div>
      <br />
      <input
            class="button"
            type="button"
            id="<?php echo $this->get_field_id('spotlight_add_row'); ?>"
            value="Click Me!"
            onclick="repeater.uploader('<?php echo $this->id;?>', '<?php echo $id_prefix;?>'); return false;"
            />
    </div>

    <script>
    jQuery(document).ready(function($){
      var tracker = <?php echo json_encode($tracker); ?>;
      var c1 = <?php echo json_encode($starter - 1); ?>;//index of the array.

      //disbale add button when reaches max spotlight.
      if(tracker.every(x => x > 0)){
        $('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').attr("disabled",true);
      }

      repeater = {
          //TRY to mass Number into this function........
          uploader :function(widget_id, widget_id_string){
            //Find the non active element
            var i;
            for (i = 0; i < <?php echo $max_spotlight; ?>; i++){
              if ( tracker[i] == 0){
                c1 = i;
                break;
              }
            }
            c1++;
            //alert(c1);



            $("#" + widget_id_string + "spotlight_row_appender").append('<div> <p class="spotlight-para">Spotlight '+c1+'</p><p> <label for="<?php echo esc_attr( $this->get_field_id( "spotlight_image_link'+c1+'")); ?>"><?php esc_attr_e( 'Image\'s link:', 'text_domain' ); ?></label>  <input  class="widefat" id="<?php echo $this->get_field_id("spotlight_image_link'+c1+'"); ?>"  name="<?php echo $this->get_field_name("spotlight_image_link'+c1+'"); ?>" type="text" value="" />  <input style="float:right;"id="delete-spotlight" name="deletespotlight_'+c1+'" type="button" value="Delete Spotlight" class="button"/><br /> </p></div>');
            //check element as active
            tracker[c1-1] = 1;

            //if all element is > 0, disable the deleteButton.
            if(tracker.every(x => x > 0)){
              $('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').attr("disabled",true);
            }
            //alert(c1);
            return false;
          }
      };

      $(document).on('click', '#delete-spotlight', function() {

        $(this).parent().parent().remove(); //remove the field.
        $('#' + '<?php echo $id_prefix; ?>' + 'spotlight_add_row').removeAttr("disabled"); //reset add button.

        //Get the name, and parse to get the ID.
        var deleteButtonName = this.name;
        var stringDeleteButton = deleteButtonName.split("_").pop();
        var deleteButtonID = parseInt(stringDeleteButton);

        tracker[deleteButtonID-1] = 0; //reset element
        //alert(tracker);
      });

    });
    </script>
  <?php
    }

    /**
     * Processing widget options on save
     *
     * @param array $new_instance The new options
     * @param array $old_instance The previous options
     */
    public function update( $new_instance, $old_instance ) {
        // processes widget options to be saved
    $instance = $old_instance;
    $instance['spotlight_add_row'] = sanitize_text_field($new_instance['spotlight_add_row']);
    $instance['spotlight_row_appender'] = sanitize_text_field($new_instance['spotlight_row_appender']);

    $increment = 1;
    while ( $increment <= 2 ){
      //increment variables
      $increment_image_link = 'spotlight_image_link' . $increment;
      $increment_add_image = 'spotlight_add_image' . $increment;
      $increment_image_preview = 'spotlight_image_preview' . $increment;
      $increment_description = 'spotlight_description' . $increment;
      $increment_name = 'spotlight_name' . $increment;
      $increment_link = 'spotlight_link' . $increment;

      $instance[$increment_image_link] = sanitize_text_field( $new_instance[$increment_image_link] );
      $instance[$increment_add_image] = sanitize_text_field( $new_instance[$increment_add_image] );
      $instance[$increment_image_preview] = sanitize_text_field( $new_instance[$increment_image_preview]);
      $instance[$increment_name] = sanitize_text_field( $new_instance[$increment_name] );
      $instance[$increment_description] = sanitize_text_field( $new_instance[$increment_description] );
      $instance[$increment_link] = sanitize_text_field( $new_instance[$increment_link] );

      $increment++;
    }
    $starter = 1;
    $num = 1;

    return $instance;
    }
}


function register_repeat_field_widget() {
    register_widget( 'repeat_field_widget' );
}
add_action( 'widgets_init', 'register_repeat_field_widget' );

クイックノート:

私はこれが最もクリーンで安全、そして最良のコードではないことを知っています、しかし私はまだ学んでいます。私と同じ問題に直面している人に役立つことを願っています。

2
Sengngy Kouch

ウィジェットフォームはJS操作には扱いにくいです。一般に、フォーム内の要素を検出するためにIDを使用しないでください。クラスとfind()parent()などの組み合わせです。

その理由は、HTMLページ上に複数のフォームがある可能性があるためです。ウィジェット管理ページには確かに表示されない "テンプレート"フォームがあり、IIRCは新しいウィジェット用のフォームを生成するために使用されます。これは、同じIDを持つ要素が少なくとも2つあり、DOM APIによってそれらにアクセスしようとしても、一貫した結果が得られないことを意味します。

1
Mark Kaplun