Автозаполнение jQuery и ответ в формате JSON — разные ответы при отправке вручную или автоматически

#php #jquery #json #codeigniter #autocomplete

#php #jquery #json #codeigniter #автозаполнение

Вопрос:

Я вижу странное поведение в этой настройке автозаполнения пользовательского интерфейса jQuery.

Когда я начинаю вводить, скажем, «Smith», автозаполнение предлагает несколько вариантов в выпадающем списке (например, «Джо Смит», «Мэри Тейлор», «Джек Воробей»). На консоли я не вижу ошибок, и ответ

[{"value":"Joe Smith"},{"value":"Mary Taylor"},{"value":"Jack Sparrow"}]

Но если я нажму кнопку отправки / поиска, то я получу пустую страницу с:

[{"value":"Joe Smith"}]

Каким-то образом мой запрос модели возвращает всех пользователей при запуске через jQuery autocomplete — но когда я запускаю его вручную, он возвращает правильный результат.

Есть идеи, что здесь не так?

Спасибо.

JS:

     $(function() {
        function log( message ) {
            $( "<div/>" ).text( message ).prependTo( "#log" );
            $( "#log" ).attr( "scrollTop", 0 );
        }

        $( "#search_input" ).autocomplete({
            source: "http://example.com/search",
            minLength: 2,
            select: function( event, ui ) {
                log( ui.item ?
                    "Selected: "   ui.item.value   " aka "   ui.item.id :
                    "Nothing selected, input was "   this.value );
            }
        });
    });
  

Контроллер (search.php Разметка CodeIgniter):

 function index()
{
    $term = $this->input->post('search_input');

    $response = json_encode($this->search_model->search($term));

    echo $response;
}
  

Модель (search_model.php Разметка CodeIgniter):

 function search($term)
{
    $query = $this->db->query("
    SELECT up.first_name, up.last_name
        FROM user_profiles up, users u, pets p 
        WHERE u.activated = 1
          AND u.banned = 0
          AND up.last_name LIKE '%" . $term . "%'
            GROUP BY up.last_name
        ORDER BY up.last_name ASC;
        ");

    $search_data = array();

    foreach ($query->result() as $row) {

        $search_data[] = array(

            'value' => $row->first_name . ' ' . $row->last_name,
        );
    }
    return $search_data;
}
  

Ответ №1:

Похоже, вы отправляете не по поисковому запросу. Я упростил это до одной функции php. $ term будет отправлен скриптом автозаполнения.

 $term = $_GET['term']

     function search($term)
    {
        $query = $this->db->query("
        SELECT up.first_name, up.last_name
            FROM user_profiles up, users u, pets p 
            WHERE u.activated = 1
              AND u.banned = 0
              AND up.last_name LIKE '%" . $term . "%'
                GROUP BY up.last_name
            ORDER BY up.last_name ASC;
            ");

        $search_data = array();

        foreach ($query->result() as $row) {

            $search_data[] = array(

                'value' => $row->first_name . ' ' . $row->last_name,
            );
        }
        echo json_encode($search_data);
    }
  

Комментарии:

1. танкс @ jason — вы правы, в конце я разобрался с этим с вашей помощью — когда я жестко отправляю (нажав кнопку отправки) Я делаю POST , поэтому запрос работает — но когда я выполняю нажатия клавиш в input поле, которое отправляет GET , которое имеет тот же эффект, что и пустой поиск (возвращает все результаты) — CodeIgniter обрабатывает только, POST поэтому нужно вручную использовать GET , как вы предложили, для передачи термина запроса

Ответ №2:

Я думаю, что лучшим решением является использование jQuery .ajax() и установка функции в POST данные. Таким образом, я могу избежать использования GET и мне не нужно создавать дополнительный контроллер для обработки обоих POST и GET .

 $("#search_input").autocomplete({
    source: function(request, response) {
            $.ajax({
                url: "search",
                dataType: "json",
                type: "POST",
                data: {
                    search_input: request.term
                },
                success: function(data) {
                    //map the data into a response that will be understood by the autocomplete widget
                    response($.map(data, function(item) {
                        return {
                            label: item.value,
                            value: item.value
                        }
                    }));
                }
            });
    },
    minLength: 2,
    //when you have selected something
    select: function(event, ui) {
        //close the drop down
        this.close
    },
    //show the drop down
    open: function() {
        $(this).removeClass("ui-corner-all").addClass("ui-corner-top");
    },
    //close the drop down
    close: function() {
        $(this).removeClass("ui-corner-top").addClass("ui-corner-all");
    }
});