Поддержка Проблемы и решения Связанные списки Ajax

  • Доброго дня
    Имею проблему с реализацией связанных списков (второй список должен измениться моментально, в зависимости от выбранного <option> в первом). Списки формируются на основе двух таблиц из БД. Первый список формируется без проблем следующим образом:

    <select class="selectpicker show-tick form-control" data-header="Выберите тип населенного пункта" name="heat_area_type" id="heatAreaType">
    <?php
    $area_types = $wpdb -> get_results("SELECT * FROM {$table_prefix}ic_area_type");
    foreach ($area_types as $area_type)
    {
    echo '<option value="'.$area_type -> area_type_id.'">'.$area_type -> area_type_name.'</option>'."\n";
     }
    ?>
    </select>

    А вот второй список, который должен формироваться в зависимости от выбранного <option> в первом, не формируется. Вот код для формирования второго списка:

     $("#heatAreaType").change(function(){
            var heatAreaType = $(this).val();
             $.ajax({
                type: 'POST',      
                url: 'http://localhost/wp-content/themes/infrcost/city.php',
                data: 'area_type_id='+heatAreaType,
                success: function(data) {
                    //alert(heatAreaType);
                    $('#heat_area').html(data);
                }
            });   
        });

    Это файл city.php:

    <?php
        global $wpdb;
        $area_type= $_POST['area_type_id'];
        $areas = $wpdb -> get_results("SELECT area_id,area_name FROM dima_ic_area WHERE area_type_id = $area_type");
        foreach ($areas as $area) 
        {
            echo '<option value="'.$area -> area_id.'">'.$area -> area_name.'</option>'."\n";
        }
    ?>

    При изменении <option> в первом списке ничего не происходит. Помогите, пожалуйста, всё перепробовал, может кто-то сможет понять — где моя ошибка ?
    Заранее спасибо

Просмотр 9 ответов — с 1 по 9 (всего 9)
  • Модератор Yuri

    (@yube)

    где моя ошибка ?

    Вот тут:

                url: 'http://localhost/wp-content/themes/infrcost/city.php',
    

    Это файл city.php:

    <?php
        global $wpdb;

    При прямом обращении к этому скрипту движок остается «за бортом», следовательно, обращение к его функционалу ничего, кроме ошибок, дать не может.

    Как правильно — см. AJAX in Plugins « WordPress Codex

    @yube , спасибо за ответ. Подскажите, пожалуйста, правильно ли я понял: в functions.php моей темы мне нужно прописать следующий код:

    add_action( 'wp_enqueue_scripts', 'my_function' );
    function my_function()
    {
    wp_enqueue_script( 'my-ajax-request', get_template_directory_uri() . '/js/custom_script.js' );//здесь мой JS код указанный выше, отслеживающий изменение <option> в первом списке
    wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); 
    }

    Я так понимаю вместо array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) нужно прописать путь к моему скрипту city.php ?
    ps извините, если написал бред, окончательно запутался

    Модератор Yuri

    (@yube)

    правильно ли я понял

    Увы, нет.

    Не должно быть никаких прямых обращений к php-скриптам Темы. Для перехвата запроса существуют add_action( 'wp_ajax_*

    @yube , ещё раз спасибо. Я близок к решению задачи, но не могу разобраться с последним моментом — как вывести полученные элементы списка <option> в сам список. Если по порядку:
    в functions.php моей темы я подключил свой скрипт след. образом:

    wp_enqueue_script( 'custom', get_template_directory_uri() .'/js/custom.js','','',true );
    wp_localize_script( 'custom', 'myTheme', array('ajaxurl' => admin_url( 'admin-ajax.php' )));

    вот сам custom.js :

    jQuery(document).ready(function ($) {
      var $mainBox = $('#heat_area_name');
      var typeBox = $('#heatAreaType');
      typeBox.change(function(){
            var heatAreaType = $(this).val();
    	jQuery.post(
                myTheme.ajaxurl,
                {
                 action: 'get_city',
                 city: heatAreaType
                 },
                function (response) {
    		alert(heatAreaType);
                    $mainBox.html(response);
                });    
          });
    });

    Для перехвата запроса в functions.php я использую:

    add_action( 'wp_ajax_get_city', 'ajax_show_city' );
    function ajax_show_city() {
        global $wpdb;
        $area_type= $_POST['city'];
        $areas = $wpdb -> get_results("SELECT area_id,area_name FROM dima_ic_area WHERE area_type_id = $area_type");
        foreach ($areas as $area) 
        {
            echo "<script>alert('Value= ".$area -> area_id." Город= ".$area -> area_name." ');</script>";
            echo '<option value="'.$area -> area_id.'">'.$area -> area_name.'</option>';
        }
    	wp_die();
    }

    Через alert все данные из таблиц выводятся, а вот в список, который расположен в author.php :

    <select class="selectpicker show-tick form-control" data-header="Выберите населенный пункт" name="heat_area" id="heat_area_name">
                                        
    </select>

    в этот список ничего не прилетает. Подскажите, пожалуйста, где я ошибся или что-то забыл ? Может быть загвоздка в строке $mainBox.html(response); , но что не так?
    Заранее спасибо за любую помощь

    Модератор Yuri

    (@yube)

    Извините, я еще не достиг нужного уровня просветления, чтобы мысленно отлаживать такой код, а внедрять это всё на тестовый сайт просто лень 🙂

    Что бросается в глаза, так это бесполезная строка

    echo "<script>alert('Value= ".$area -> area_id." Город= ".$area -> area_name." ');</script>";
    

    Лишний код внутри <select>..</select> может помешать корректной работе.

    И вообще, я бы посоветовал использовать для отладки console.log(...) вместо alert(...).

    Да, еще. Я никогда не использовал в обработчиках ajax wp_die(), только die(), а потому не уверен, что эта функция тут уместна.

    @yube , ещё раз извиняюсь за беспокойство — нашел в чем причина, но не понимаю от чего так происходит: для оформления списков использую библиотеку bootstrap-select.min.js. Все библиотеки подключаю следующим образом:

    add_action('wp_footer', 'add_scripts');
    if (!function_exists('add_scripts')) {
    function add_scripts() {
    if(is_admin()) return false;
    wp_deregister_script('jquery');
     wp_enqueue_script('jquery', get_template_directory_uri().'/js/jquery-3.2.1.min.js','','',true);
    wp_enqueue_script('bootstrap',get_template_directory_uri().'/js/bootstrap.min.js','','',true);
    wp_enqueue_script('bootstrap_select', get_template_directory_uri().'/js/bootstrap-select.min.js','','',true);
    wp_enqueue_script('js_main', get_template_directory_uri().'/js/main.js','','',true);
    wp_enqueue_script( 'custom', get_template_directory_uri() .'/js/custom.js','','',true );
     wp_localize_script( 'custom', 'myTheme', array('ajaxurl' => admin_url( 'admin-ajax.php' )));
    	}
    }

    Так вот если у моего списка убрать классы selectpicker show-tick , которые использует bootstrap-select.min.js — то всё работает. И при этом когда всё работает в консоли обнаружил ошибку Скрин ошибки:
    Could not load content for http://localhost/wp-content/themes/js/bootstrap-select.js : HTTP status code: 404
    Ещё раз извиняюсь — наверное нужно прописать зависимости моего custom.js от bootstrap-select.js ? или не верно ? не пойму..

    • Ответ изменён 3 года, 11 месяцев назад пользователем Dmitry Kohan.

    Дело в том, что я нигде не обращаюсь в своем коде к bootstrap-select.js, подключаю только bootstrap-select.min.js, ломаю голову откуда берется это подключение и ошибка…

    Подскажите, пожалуйста, может быть ли данная проблема вызвана конфликтом между bootstrap-select.min.js и моими собственными скриптами ?

    Добился окончательного решения проблемы за счет исключения из кода классов, используемых библиотекой bootstrap-select.min.js (может кому-нибудь пригодится).
    @yube , спасибо огромное за помощь

Просмотр 9 ответов — с 1 по 9 (всего 9)
  • Тема «Связанные списки Ajax» закрыта для новых ответов.