it-swarm.com.de

Sind dynamische Formulare/Einträge in Widget möglich?

Ich bin neu in der Entwicklung von WordPress Plugins und habe gerade angefangen, mit dem Widget zu arbeiten. Meine Frage ist: Was sind die Einschränkungen von WordPress Widget?

Ich habe versucht, jQuery zu verwenden, um das Widget-Formular interaktiver/dynamischer zu gestalten, aber es scheint überhaupt nicht zu funktionieren. Zum Beispiel habe ich eine Schaltfläche, die beim Klicken eine Zeichenfolge von "Hallo!" zu einem div, der id "hier" hat.

<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. Warum wird der Absatz "Hallo" nicht im Formular angezeigt? Liegt es daran, dass Widget-Formulare dies verhindern?

  2. Ich habe auch von Backbone.js gehört, das das Front-End aktualisiert, bin mir aber nicht sicher, ob das funktionieren wird.

  3. Wenn möglich, erläutern Sie bitte, wie die gesamte WordPress-Widget-Klasse funktioniert. Danke im Voraus!

Update: Ich habe bereits versucht, was vorgeschlagen wird, aber es funktioniert immer noch nicht. Hier ist mein Code.

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

Vielen Dank anDave RomseyundMark Kaplunfür den Hinweis, dass HTML ID nicht in WordPress Widget verwendet wird. Ich finde endlich eine Lösung für mein Bedürfnis.

Lösung:

Wir müssen eine voreingestellte Variable in alle 3 Funktionen (Widget, Formular, Update) einfügen. In meinen Codes heißen sie "spotlight_image_link1, spotlight_image_link2, etc". Dann geben Sie in der "Form-Funktion" ihre ID mit PHP-Code. Bitte lesen Sie meinen Code unten für weitere Informationen.

Was kann meine Lösung tun?

Grundsätzlich ist es nicht vollständig dynamisch, da wir alle Scheinwerfer im Voraus definieren müssen. In meinem Fall habe ich nur zwei Scheinwerfer vordefiniert, um den Code einfach zu lesen.

Hier, wie es aussieht: enter image description here 

Logik hinter den Kulissen:

  • wann immer das "Klick mich!" Wenn Sie auf die Schaltfläche klicken, wird ein Scheinwerfer hinzugefügt.
  • Es gibt ein Tracker-Array namens "Tracker", das festhält, welche vordefinierten Scheinwerfer bereits verwendet werden. Deaktivieren Sie das Kontrollkästchen "Klick mich!", Wenn alle Scheinwerfer verwendet wurden. Taste.
  • Wenn Sie auf "Scheinwerfer löschen" klicken, entfernen Sie diesen bestimmten Scheinwerfer und aktivieren Sie das Kontrollkästchen "Klick mich!" Taste. Beachten Sie, dass der Name jeder Löschtaste mit einer Nummer versehen ist. So wissen wir, welcher Scheinwerfer gelöscht werden soll.
  • Das Spotlight wird nur dann und nur dann gespeichert, wenn die Eingabe nicht leer ist. Diese Bedingung befindet sich in der "while" -Schleife der "form" -Funktion.

Einschränkung:

Wann immer wir auf "Speichern" geklickt haben, wird die Reihenfolge der Scheinwerfer von 1 auf n geändert. Es ist nicht besonders benutzerfreundlich, aber ich plane, Ajax zu verwenden, um das Front-End mit dem Back-End zu synchronisieren. Ich bin mir noch nicht sicher wie.

Quellcode:

  • Ab WordPress 4.7.2 funktioniert es fehlerfrei.
  • Füge den gesamten Quellcode in die "repeat.php" -Datei in deinem Plugin-Verzeichnis ein. Wenn Sie nicht wissen, wie, googeln Sie es bitte.

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

Kurznotiz:

Ich weiß, dass dies nicht der sauberste, sicherste und beste Code ist, aber ich lerne noch. Ich hoffe das hilft jedem, der die gleichen Probleme hat wie ich.

2
Sengngy Kouch

Widget-Formulare sind schwierig für die JS-Manipulation. Im Allgemeinen sollten Sie niemals IDs verwenden, um Elemente im Formular zu erkennen, sondern eine Kombination aus Klassen und find(), parent() usw.

Der Grund dafür ist, dass die HTML-Seite möglicherweise mehrere Formulare enthält. Sicher ist, dass auf der Widget-Verwaltungsseite ein "Vorlagen" -Formular nicht angezeigt wird und IIRC verwendet wird, um das Formular für ein neues Widget zu generieren. Dies bedeutet, dass mindestens zwei Elemente mit derselben ID vorhanden sind und ein Versuch, über DOM-APIs auf sie zuzugreifen, kein konsistentes Ergebnis liefert.

1
Mark Kaplun