Как передать переменную JavaScript в PHP в виджете WordPress?

2 мар. 2017 г., 00:42:21
Просмотры: 13.9K
Голосов: 3

Я потратил много времени на поиск решения, где можно передать значение переменной JavaScript в PHP переменную в том же файле, той же функции (Виджет WordPress, функция Form). Есть ли хороший способ сделать это в 2017 году?

Я пробовал метод ниже. Хотя Ajax часть выводит сообщение об успехе, PHP часть не работает.

repeat.php

<?php 
    echo $_POST['examplePHP']; //вызовет ошибку undefined index здесь
?>
<script>
        jQuery(document).ready(function($){

          var exampleJS = "hi!";

          $.ajax({
                url: ajaxurl, //Я пробовал 'repeat.php' вместо ajaxurl, но не работает
                type: 'POST',
                data: {
                  examplePHP: exampleJS
                },
                success: function( response){
                  console.log("Успешно!");
                },
                error: function(error){
                  console.log("Ошибка");
                }
          });

      });
</script>
1
Комментарии

Вам нужно добавить ваш php-код в функцию, которую сможет вызывать ajax. https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)

ngearing ngearing
2 мар. 2017 г. 00:50:09
Все ответы на вопрос 2
0

Я нашел простой способ передать переменную из JavaScript в переменную PHP. Обратите внимание, что этот метод работает в WordPress версии 4.7.2 и только конкретно для виджетов. Я добавил много комментариев, чтобы объяснить, что делает каждая строка. Если у вас есть лучшее решение, поделитесь с нами!

Решение:

  • Создайте скрытое поле ввода для хранения значения из JavaScript, которое вы хотите передать.
  • Получите доступ к этому скрытому полю и присвойте его значение переменной PHP.

Демо-виджет:

  • Я создал демо-виджет, который добавляет слово "ЛЮБЛЮ ТЕБЯ" столько раз, сколько вы нажмете кнопку "Добавить ЛЮБЛЮ ТЕБЯ".

  • Обратите внимание, что я оставил скрытое поле видимым для лучшего понимания.

  • Вы можете изменить type="text" на type="hidden", чтобы скрыть его.

  • Это демо фокусируется только на функции form виджета.

  • Обязательно нажмите кнопку Сохранить, иначе значение скрытого поля не будет сохранено виджетом.

Скриншот демо-виджета:

Скриншот демонстрационного виджета WP Text Repeater

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

wp-text-repeater.php

<?php
/**
* Название плагина: WP Text Repeater
**/

class wp_text_repeater extends WP_Widget {

    /**
     * Устанавливает название и параметры виджета
     */
    public function __construct() {
        $widget_ops = array(
            'classname' => 'wp_text_repeater',
            'description' => 'Виджет, который выводит "ЛЮБЛЮ ТЕБЯ" повторно в зависимости от нажатий кнопки',
        );
        parent::__construct( 'wp_text_repeater', 'WP Text Repeater Widget', $widget_ops );
    }

    /**
     * Выводит содержимое виджета
     *
     * @param array $args
     * @param array $instance
     */
    public function widget( $args, $instance ) {
        // выводит содержимое виджета
    $wp_text_repeater_button = ! empty( $instance['wp_text_repeater_button'] ) ? $instance['wp_text_repeater_button'] : '';
    $wp_text_repeater_appendee = ! empty( $instance['wp_text_repeater_appendee'] ) ? $instance['wp_text_repeater_appendee'] : '';
    $wp_text_repeater_hidden = ! empty( $instance['wp_text_repeater_hidden'] ) ? $instance['wp_text_repeater_hidden'] : '';
    }

    /**
     * Выводит форму настроек в админке
     *
     * @param array $instance Параметры виджета
     */
    public function form( $instance ) {
        // выводит форму настроек в админке
    $instance = wp_parse_args( (array) $instance, array( 'wp_text_repeater_button' => '', 'wp_text_repeater_appendee' => '', 'wp_text_repeater_hidden' => ''));

    $wp_text_repeater_button = $instance['wp_text_repeater_button'];
    $wp_text_repeater_appendee = $instance['wp_text_repeater_appendee'];
    $wp_text_repeater_hidden = $instance['wp_text_repeater_hidden'];

    $tempHidden = 'wp_text_repeater_hidden';

  ?>
    <!-- Скрытое поле, хранящее количество нажатий кнопки пользователем -->
    <input
          class="widefat"
          id="<?php echo $this->get_field_id($tempHidden); ?>"
          name="<?php echo $this->get_field_name($tempHidden); ?>"
          type="text"
          value="<?php echo esc_attr($$tempHidden);?>"/>
  <?php

    $max = 0; //Количество нажатий кнопки пользователем

    //Если скрытое поле JavaScript на фронтенде имеет значение, присвоить $max это значение.
    //Это условие синхронизирует JavaScript и PHP части.
    if(strlen($$tempHidden) > 0){
      $max = intval($$tempHidden);
    }

    $counter = 0;
    while($counter < $max){ //цикл по количеству нажатий кнопки
  ?>
      <p>ЛЮБЛЮ ТЕБЯ!</p>
  <?php
     $counter++;
    }

    $id_prefix = $this->get_field_id(''); //получить префикс ID виджета.
  ?>
    <!-- Сюда можно добавлять весь ваш контент -->
    <span id="<?php echo $this->get_field_id('wp_text_repeater_appendee')?>"></span>

    <!-- Кнопка, вызывающая jQuery функцию для добавления слова "ЛЮБЛЮ ТЕБЯ" -->
    <input style="background-color: #08a538; color:white; height: 27px;"
          class="button widefat"
          type="button"
          id="<?php echo $this->get_field_id('wp_text_repeater_button'); ?>"
          value="Добавить ЛЮБЛЮ ТЕБЯ"
          onclick="text_repeater.addLove('<?php echo $this->id;?>', '<?php echo $id_prefix;?>'); return false;"
          />

    <script>

    jQuery(document).ready(function($){
      var preIndexID;
      var numberOfLove = <?php echo $max; ?>; //получить значение из PHP для синхронизации фронтенда и бэкенда.
      text_repeater = {
          addLove :function(widget_id, widget_id_string){
              preIndexID = widget_id_string; //получить правильный префикс ID виджета.
              numberOfLove++;
              numberOfLove = numberOfLove.toString(); //конвертировать число в строку для скрытого поля.
              $("#" + preIndexID + "wp_text_repeater_hidden").val(numberOfLove); //изменить значение скрытого поля.
              $("#" + preIndexID + "wp_text_repeater_appendee").append('<p>ЛЮБЛЮ ТЕБЯ!</p>'); //динамически обновить фронтенд с "ЛЮБЛЮ ТЕБЯ".
          }
      }
    });

    </script>
  <?php
    }

    /**
     * Обработка параметров виджета при сохранении
     *
     * @param array $new_instance Новые параметры
     * @param array $old_instance Предыдущие параметры
     */
    public function update( $new_instance, $old_instance ) {
        // обрабатывает параметры виджета для сохранения
    $instance = $old_instance;

    $instance['wp_text_repeater_button'] = sanitize_text_field($new_instance['wp_text_repeater_button']);
    $instance['wp_text_repeater_appendee'] = sanitize_text_field ($new_instance['wp_text_repeater_appendee']);
    $instance['wp_text_repeater_hidden'] = sanitize_text_field( $new_instance['wp_text_repeater_hidden'] );

    return $instance;

    }
}

// регистрация виджета wp_text_repeater
function register_wp_text_repeater_widget() {
    register_widget( 'wp_text_repeater' );
}
add_action( 'widgets_init', 'register_wp_text_repeater_widget' );
3 мар. 2017 г. 20:52:12
0

Помните, что код выполняется сверху вниз.

Таким образом, вы не можете получить переменную POST до её отправки через AJAX.

Вот пример, который сработает в вашей настройке:

<?php 
    if(isset($_POST['examplePHP'])){ //проверяем, существует ли $_POST['examplePHP']
        echo $_POST['examplePHP']; // выводим данные
        die(); // останавливаем выполнение скрипта.
    }
?>

<script>
        jQuery(document).ready(function($){

          var exampleJS = "Привет!";

          $.ajax({
                url: window.location, //window.location указывает на текущий URL. при необходимости измените.
                type: 'POST',
                data: {
                  examplePHP: exampleJS
                },
                success: function( response){
                  console.log("Успешно! Мои POST-данные: "+response);
                },
                error: function(error){
                  console.log("Ошибка");
                }
          });

      });
</script>

Сначала мы проверяем существование переменной POST с помощью isset(). Если она существует, мы выводим содержимое 'examplePHP' и останавливаем выполнение скрипта с помощью die();.

Если переменная POST отсутствует, это означает, что кто-то просто загружает страницу. В этом случае мы не выводим данные, а продолжаем работу с остальной частью страницы.

Я добавил window.location, который указывает на текущий URL. А переменная response содержит выведенные данные.

Поскольку это WordPress Stack Exchange, я рекомендую использовать WordPress AJAX. Подробнее об этом можно прочитать на странице Codex!

2 мар. 2017 г. 01:05:41