Возможны ли динамические формы / записи в Widget?

Я новичок в разработке плагинов WordPress, и я только начал работать с виджетами. Мой вопрос: каковы ограничения WordPress Widget?

Я попытался использовать jQuery, чтобы сделать форму виджета более интерактивной / динамичной, но она, похоже, не работает вообще. Например, у меня есть кнопка, которая при нажатии добавит строку «Hello!» к div, который имеет id «здесь».

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

Solutions Collecting From Web of "Возможны ли динамические формы / записи в Widget?"

Формы виджетов сложны для манипуляций с JS. В общем, вы никогда не должны использовать идентификаторы для обнаружения элементов в форме, но сочетание классов и find() , parent() и т. Д.

Причина в том, что на HTML-странице может быть более одной формы. На странице администрирования виджетов есть форма «шаблон», которая не отображается, а IIRC используется для создания формы для нового виджета. Это означает, что будет по крайней мере два элемента с одинаковым идентификатором, и попытка получить к ним доступ с помощью DOM API не даст согласованного результата.

Спасибо Дэйв Ромси и Марк Каплун за указание не использовать HTML-код в WordPress Widget. Наконец-то я нашел решение для своих нужд.

Решение:

Нам нужно добавить предустановленные переменные во все 3 функции (виджет, форма, обновление). В моих кодах они называются «spotlight_image_link1, spotlight_image_link2 и т. Д.». Затем в «функции формы» их идентификатор использует PHP-код. Пожалуйста, прочтите мой код ниже для получения дополнительной информации.

Что может сделать мое решение?

В принципе, он не является полностью динамичным, потому что нам необходимо заранее определить все прожектора. В моем случае я только предопределил два прожектора, чтобы сделать код простым для чтения.

Вот как это выглядит: введите описание изображения здесь

Логика за сценой:

  • всякий раз, когда «нажмите меня!» нажмите кнопку, будет добавлен прожектор.
  • Существует массив трекеров, называемый «трекер», который отслеживает, какие предварительно определенные прожекторы уже используются. Когда все прожекторы используются, отключите «Click me!». кнопка.
  • Когда щелкнули «удалить прожектор», удалите этот конкретный прожектор и снова включите «Нажмите меня!». кнопка. Обратите внимание, что имя каждой кнопки удаления добавляется с номером. Это позволяет нам узнать, какой прожектор следует удалить.
  • Прожектор сохраняется только тогда и только тогда, когда вход не пуст. Это условие находится в цикле «while» функции «form».

Ограничение:

На данный момент, когда мы нажимаем «Сохранить», порядок прожектора перестраивается от 1 до n. Это не очень удобно, но я планирую использовать Ajax для синхронизации внешнего интерфейса с внутренним концом. Я еще не знаю, как это сделать.

Исходный код:

  • Начиная с WordPress 4.7.2, он работает без ошибок.
  • Поместите весь исходный код в файл «repeat.php» в вашем каталоге плагинов. Если вы не знаете, как это сделать, пожалуйста, google.

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

Быстрое примечание:

Я знаю, что это не самый чистый, безопасный и лучший код, но я все еще участвую. Надеюсь, это поможет любому, кто сталкивается с теми же проблемами, что и я.