简体   繁体   中英

Use Jquery and Ajax to create autocomplete/autosuggest list with JSON data retrieved from API using PHP

I'm struggling to create a dynamic auto-suggest list for a search field using Jquery with data in JSON format. This JSON data is retrieved from an API using PHP .

I want the auto-suggest list to update with each new key typed into the search field. This means that the API has to be called with PHP for each new key pressed, and new JSON data is generated with each key. I can't figure out how to use Jquery/Ajax to:

  1. call the API with each key entered into the search box and

  2. to repopulate the HTML list with the results

I know I'm not doing this right because I can't get the Jquery/Ajax component right. I know I should be using the keyup event and $.ajax to get my JSON data in event callback, but I don't know how to do it properly. Currently I'm able to create a list of autosuggestions/autocompletes from the JSON data that the PHP gets from the API when the page loads with a default query "sail".

Here is my code:

<?php

$subscriptionKey = "12345678";

$host = "https://api.com";
$path = "/Suggestions";

$mkt = "en-US";
$query = "sail";

/*This function calls the API and returns the JSON data in a PHP variable*/
function get_suggestions ($host, $path, $key, $mkt, $query) {

  $params = '?mkt=' . $mkt . '&q=' . $query;

  $headers = "Content-type: text/json\r\n" .
    "Ocp-Apim-Subscription-Key: $key\r\n";

  $options = array (
    'http' => array (
      'header' => $headers,
      'method' => 'GET'
    )
  );
  $context  = stream_context_create ($options);
  $result = file_get_contents ($host . $path . $params, false, $context);
  return $result;
}

$result = get_suggestions ($host, $path, $subscriptionKey, $mkt, $query);

echo json_encode (json_decode ($result), JSON_PRETTY_PRINT);

$suggestions = json_decode ($result, true);

$suggestionsArray = call_user_func_array('array_merge',$suggestions["suggestionGroups"]);

?>

<!DOCTYPE html>
<html>
<head>  
    <link rel="stylesheet" type="text/css" href="assets/css/style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>
$( "#search" ).keyup(function() {
  *When a new key is typed into the search box:*
  *call PHP function get_suggestions($host, $path, $subscriptionKey, $mkt, $query) with the current value of the text input in the search box being the value for $query. This function gets the JSON data from the API*
  *Parse the JSON data and populate the UL element with the results*
  *Do these above steps each time a new key is typed, to create a dynamic list of autosuggestions/autocompletes for the given query* 
    ;
});
</script>

</head>
<body>
    <div align="center>
        <input type="text" name="search" id="search" placeholder="Search" class="form-control">
    </div>

    <ul class="list-group" id="result">
        <!-- This code was to test to make sure I could format the JSON data from the API, and I know this is not how to properly create an autosuggest list -->
        foreach ($suggestionsArray as $name => $arr) {
              foreach($arr as $data){
                  echo "<li class=urlname>";
                  echo "<a class=urlnamelink href='/search.php? 
                  q=".$data["displayText"]."'>".$data["query"]."</a>\n";
                  echo "</li>";
              }
        }
    </ul>
</body>
</html>

Here's a sample of the JSON data that the PHP code gets from the API:

{
    "_type": "Suggestions",
    "queryContext": {
        "originalQuery": "sail"
    },
    "suggestionGroups": [
        {
            "name": "Web",
            "searchSuggestions": [
                {
                    "url": "https:\/\/www.api.com\/search?q=sailpoint&FORM=USBAPI",
                    "displayText": "sailpoint",
                    "query": "sailpoint",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailor+moon&FORM=USBAPI",
                    "displayText": "sailor moon",
                    "query": "sailor moon",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailboats+for+sale&FORM=USBAPI",
                    "displayText": "sailboats for sale",
                    "query": "sailboats for sale",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailrite&FORM=USBAPI",
                    "displayText": "sailrite",
                    "query": "sailrite",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailor&FORM=USBAPI",
                    "displayText": "sailor",
                    "query": "sailor",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailing+anarchy&FORM=USBAPI",
                    "displayText": "sailing anarchy",
                    "query": "sailing anarchy",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailfish&FORM=USBAPI",
                    "displayText": "sailfish",
                    "query": "sailfish",
                    "searchKind": "WebSearch"
                },
                {
                    "url": "https:\/\/www.api.com\/search?q=sailflow&FORM=USBAPI",
                    "displayText": "sailflow",
                    "query": "sailflow",
                    "searchKind": "WebSearch"
                }
            ]
        }
    ]
}
$("#search").autocomplete({
source: function (request, response) {
    var aObj = {
        "ReviseReason": $("#search").val(),
        "headId":91
    };
    var urlpath = base + "Common/GetReason";
    $.ajax({
        type: "POST",
        url: urlpath,
        dataType: "JSON",
        contentType: "application/json;charset=utf-8",
        data: JSON.stringify(aObj),
        success: function (result) {
            if (result.IsSessionOut != null) {
                notify('danger', "Your Session Is Over,Please Login Again");
                return false;
            } else if (result.Error != null && result.Error != "") {
                return false;
            } else {
                $('#hdByAirShipReason').val("");
                response(result.ListAutoCpomplete);
            }
        }
    });
},
//delay: 500,
minLength: 1,
select: function (event, ui) {
    $('#hdByAirShipReason').val(ui.item.id);
}

});

This is the type of autocomplete with ajax code you're looking. Mind one thing, you're Json markup is invalid with autocomplete. in autocomplete json data, the field you want to display must have property name 'label' and value as 'id'. You can always include additional property fields however.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM