jQuery AJAX Автозаполнение не работает при попытке сделать его динамичным - PullRequest
0 голосов
/ 03 апреля 2020

У меня автозаполнение работает нормально, если в него подаются жестко закодированные данные. Мой PHP возвращает JSON результат. Я не уверен, где я иду не так.

HTML

<div class="form-group bgcolor">
  <label for="send_to">Direct to: </label><input type="text" name="send_to" id="send_to" class="form-control send_to typeahead" placeholder="Leave blank normally">
</div>

Jquery

        $('.typeahead').typeahead({
          source: {
              groupName: {
               ajax({
                url: 'scripts/order_messaging.php',
                method: 'POST',
                data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
                contentType: 'application/json',
                dataType: 'json',
                success:function(data)
                {
                 result($.map(data, function(item){
                  return item;
                 }));
                }
              })
            },
         },
         debug: true
        });

PHP

//autocomplete user name for user_to
if ( $_POST['action'] == 'autocomplete_to_user' ) {
    $stmt = $pdo->prepare('select * from login where username like :query');
    $stmt->bindValue('query', '%'.$_POST['query'].'%');
    $stmt->execute();
    $result = array();
    while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
        array_push($result, $user_name->username);
    }
    echo json_encode($result);
}

Я думаю, что эта строка в моем jQuery: data: {action: 'autocomplete_to_user', query:query}, Возможно, у меня проблема с синтаксисом.

Ответы [ 4 ]

1 голос
/ 05 апреля 2020

По моему скромному мнению, в документации есть некоторые ошибки. Например, в demos , в частности, в примере Country v2 состояния

POST-запрос будет отправлен с данными myKey: myValue

когда в действительности запрос, отправляемый в примере, равен GET, поскольку он зависит от ключа type объекта ajax из первого источника ( страна *) 1020 * в данном случае), который не установлен, поэтому по умолчанию устанавливается GET.

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

HTML

<form id="form-country_v2" name="form-country_v2">
    <div class="typeahead__container">
        <div class="typeahead__field">
            <div class="typeahead__query">
                <input class="typeahead" name="country_v2[query]" placeholder="Search" autocomplete="off">
            </div>
            <div class="typeahead__button">
                 <button type="submit">
                     <i class="typeahead__search-icon"></i>
                 </button>
            </div>
        </div>
    </div>
</form>

JS

$(document).ready(() => {
  $('.typeahead').typeahead({
    template: "{{display}} <small style='color:#999;'>{{group}}</small>",
    source: {
      users: { //might as well be 'willy wonka', it doesn't matter
        ajax: {
          type: "POST",
          url: "scripts/order_messaging.php",

          //this is not actually needed for the request to work (reach the server),
          //this is used to access said request's returned data, it all
          //depends on how you structure the response in the server,
          //check out the php part
          path: "data.users",

          data: {
            action: 'autocomplete_to_user',
            query: 'username'
          }
        }
      }
    },
    callback: {
      //this is just to help you show the response in the html
      onResult: function(node, query, result, resultCount) {
        if (query === "") return;

        var text = "";

        if (result.length > 0 && result.length < resultCount) {
          text = "Showing <strong>" + result.length + "</strong> of <strong>" + resultCount + '</strong> elements matching "' + query + '"';
        } else if (result.length > 0) {
          text = 'Showing <strong>' + result.length + '</strong> elements matching "' + query + '"';
        } else {
          text = 'No results matching "' + query + '"';
        }
        $('#result-container').html(text);

      },
      onInit: function(node) { //and this is just informational
        console.log('Typeahead Initiated on ', node, node.selector);
      }
    }
  });
});

order_messaging . php

if ($_POST['action'] == 'autocomplete_to_user') {
    $stmt = $pdo->prepare('select * from login where username like :query');
    $stmt->bindValue('query', '%' . $_POST['query'] . '%');
    $stmt->execute();
    $result = array();
    while ($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
        array_push($result, $user_name->username);
    }

    echo json_encode(array(
        "status" => true,
        "error" => null,

        //here you use whatever structure you want to return the data in,
        //as long as the payload is an array ($result).
        //remember in the JS you are expecting 'data.users'?
        //this is where it's coming from
        "data" => array(
            "users" => $result,
        )
    ));
} else
    echo json_encode(array(
        "status" => true,
        "error" => null,
        "data" => array(
            "users" => [],
        )
    ));

HIH

1 голос
/ 03 апреля 2020

Согласно jQuery Ajax Документация , dataType: 'json' оценивает ответ как JSON и возвращает объект JavaScript.

Вам необходимо упорядочить данные по используя JSON.stringify({action: 'autocomplete_to_user', query:query}) перед отправкой на PHP. Кроме того, вам нужно добавить заголовок Content-Type: 'application/json', который сообщает вам PHP код, который запрашивает данные JSON. Вы можете сделать это, добавив contentType: 'application/json' в настройках Ajax.

Ваш окончательный код jQuery будет выглядеть следующим образом:

$('.typeahead').typeahead({
  source: function(query, result)
  {
   $.ajax({
    url: 'scripts/order_messaging.php',
    method: 'POST',
    data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
    contentType: 'application/json',
    dataType: 'json',
    success:function(data)
    {
     result($.map(data, function(item){
      return item;
     }));
    }
  })
 }
});

См. jQuery Ajax Документация для деталей режима. Надеюсь, это поможет!

РЕДАКТИРОВАТЬ:

Вам необходимо обновить PHP код, чтобы прочитать JSON. Пожалуйста, обратитесь к этой ссылке . Ваш PHP код должен выглядеть следующим образом:

<?php
    // Read the input stream
    $body = file_get_contents("php://input");

    // Decode the JSON object
    $object = json_decode($body, true);
    //autocomplete user name for user_to
    if ( $object ['action'] == 'autocomplete_to_user' ) {
        $stmt = $pdo->prepare('select * from login where username like :query');
        $stmt->bindValue('query', '%'.$object['query'].'%');
        $stmt->execute();
        $result = array();
        while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
            array_push($result, $user_name->username);
        }
        echo json_encode($result);
    }
?>

0 голосов
/ 06 апреля 2020

Что ж, после долгих проб и ошибок я получил автозаполнение, работающее с использованием jQuery .autocomplete.

Я не знаю, что я делал неправильно с заголовком, но документацию было сложно понять (возможно, из-за моего ограниченного опыта работы с jQuery).

Для всех тех, кто в будущем нуждается в помощи; Вот полезное руководство, которое я нашел: jquery Руководство по автозаполнению пользовательского интерфейса

Спасибо всем

0 голосов
/ 04 апреля 2020

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

1) Необходимо реструктурировать параметр source. Вы предоставили ему обратный вызов AJAX, который не поддерживается. Согласно документации, он принимает массив или объект с настройками, поэтому AJAX необходимо определить следующим образом:

$('.typeahead').typeahead({
    source: {
        // source has an "ajax" property where you just need to place
        // the object with AJAX params (the one you'd normally place inside
        // an $.ajax() call)
        ajax: {
            url: 'scripts/order_messaging.php',
            method: 'POST',
            data: {
                action: 'autocomplete_to_user',
                query: query,
            },
            dataType: 'json',
            path: '',
        },
    },
});

Свойство path объекта ajax является ключевым здесь. Он сообщает функции typeahead, где искать данные, которые были возвращены действием AJAX. Поскольку вы кодируете одномерный массив значений, вам нужно установить его в пустую строку, то есть ваши данные находятся в root ответа.

Если вы, например, должны были вернуть массив, такой как echo json_encode(['users' => $result]);, тогда вам нужно установить путь к 'users' (потому что это индекс в ответе, который содержит ваши данные).

2) Вы должны следовать строгому * Структура 1024 *, чтобы заставить ее работать:

<div class="typeahead__container">
    <div class="typeahead__field">
        <div class="typeahead__query">
            <input class="js-typeahead" name="q" autocomplete="off">
        </div>
    </div>
</div>

Если вы пропустите какой-либо из этих элементов, это не вызовет функциональность. Эта HTML структура является одной из первых вещей, которые они упоминают в документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...