2017-01-17 115 views
0

我正在使用自動完成從多個來源獲取建議,並將它們顯示爲UI中的一個列表。當我輸入時,會顯示建議,但是當我將鼠標懸停在某個提示上時,出現「TypeError:n未定義」錯誤。當我點擊一個建議時,我得到一個錯誤「ui.item未定義」。JQuery-UI提供了「TypeError:n未定義」和「ui.item未定義」

的HTML頁面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>jQuery Autocomplete with Multiple Search Engines Suggestions</title> 

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> 
<script type="text/javascript"> 
$.widget("custom.catcomplete", $.ui.autocomplete, { 
    _renderMenu: function(ul, items) { 
     var self = this, currentCategory = ""; 
     $.each(items, function(index, item) { 
      if (item.category != currentCategory) { 
       ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>"); 
       currentCategory = item.category; 
      } 
      self._renderItem(ul, item); 
     }); 
    } 
}); 

$(function(){ //page load 
    $("#q").focus(); //set focus to search field 
    $("#q").catcomplete({ 
     source:"suggest.php", 
     minLength:2, 
     delay:10, 
     select: function(event, ui) { 
      window.location.assign(ui.item.searchUrl + ui.item.label); 
      //document.getElementById("q").value = ui.item.label 
      //$("#q").val(ui.item.value); 
      //$("#searchform").submit(); 
     } 
    }); 
}); 
</script> 
<style type="text/css"> 
.ui-autocomplete-category { 
    font-weight: bold; 
    font-size: 1em; 
    padding: .2em .2em; 
    margin: .4em 0 .2em; 
    line-height: 1.5; 
    color: #069; 
    border-bottom: 2px solid #069; 
} 
li.ui-autocomplete-category { 
    list-style-type: none; 
} 
</style> 
</head> 
<body> 
    <form id="searchform" name="form1" method="get" action="http://www.google.com/search"> 
     Search: 
     <input name="q" id="q" type="text" size="40" /> 
     <input name="submit" type="submit" value="Search" /> 
    </form> 
</body> 
</html> 

的PHP腳本:

<?php 
//Search term 
$term = $_REQUEST['term']; 
//Search Engine array 
$searchEngines = array(
    "Google" => array("http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&q=", "http://www.google.com/search?q="), 
    //"Bing" => array("http://api.bing.com/osjson.aspx?query=", "http://www.bing.com/search?q="), 
    //"Yahoo" => array("http://ff.search.yahoo.com/gossip?output=fxjson&command=", "http://search.yahoo.com/search?p="), 
    "Wikipedia" => array("http://en.wikipedia.org/w/api.php?action=opensearch&search=", "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search="), 
    //"Ebay" => array("http://anywhere.ebay.com/services/suggest/?q=", "http://shop.ebay.com/i.html?_nkw="), 
    "Amazon" => array("http://completion.amazon.com/search/complete?search-alias=aps&client=amazon-search-ui&mkt=1&q=", "http://www.amazon.com/s/field-keywords=") 

); 

//Combine Search Results 
$searchArray = array(); 
foreach($searchEngines as $engine => $urls){ 
    $url = $urls[0] . rawurlencode($term); 
    try{ 
     //$json = file_get_contents($url); 
     $json = get_url_contents($url); 
     $array = json_decode($json); 
     $array = $array[1]; //$array[1] contains result list 
     if(count($array) > 0){ 
      $array = getFormattedArray($array, $engine, $urls[1]); 
      $searchArray = array_merge($searchArray, $array); 
     } 
    } catch (Exception $e){ /* Skip the exception */ } 
} 

//Output JSON 
header('content-type: application/json; charset=utf-8'); 
echo json_encode($searchArray); //Convert array to JSON object 

//Format array to add category (search engine name) 
function getFormattedArray($array, $engine, $searchUrl){ 
    $newArray = array(); 
    foreach($array as $a){ 
     $newArray[] = array('label' => $a, 'searchUrl' => $searchUrl, 'category' => $engine); 
    } 
    return $newArray; 
} 

//Read URL contents 
function get_url_contents($url) 
{ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 
    $ip=rand(0,255).'.'.rand(0,255).'.'.rand(0,255).'.'.rand(0,255); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("REMOTE_ADDR: $ip", "HTTP_X_FORWARDED_FOR: $ip")); 
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/".rand(3,5).".".rand(0,3)." (Windows NT ".rand(3,5).".".rand(0,2)."; rv:2.0.1) Gecko/20100101 Firefox/".rand(3,5).".0.1"); 
    $html = curl_exec($ch); 
    curl_close($ch); 
    return $html; 
} 
?> 
+0

你能提供一個PHP輸出的例子或樣例嗎? – Twisty

回答

1

我加入這個作爲一個評論,不是答案,在目前,我打算更新它,因爲我們解決問題。

首先,我可以複製你的代碼,並在這裏的錯誤:https://jsfiddle.net/xatu48sc/2/

我使用的是常規(非minified的)版本。我遇到的錯誤上5836線:

5826 item = ui.item.data("ui-autocomplete-item"); 
5827 if (false !== this._trigger("focus", event, { item: item })) { 
5828 
5829  // use value to match what will end up in the input, if it was a key event 
5830  if (event.originalEvent && /^key/.test(event.originalEvent.type)) { 
5831   this._value(item.value); 
5832  } 
5833 } 
5834 
5835 // Announce the value in the liveRegion 
5836 label = ui.item.attr("aria-label") || item.value; 
5837 if (label && $.trim(label).length) { 
5838  this.liveRegion.children().hide(); 
5839  $("<div>").text(label).appendTo(this.liveRegion); 
5840 } 

我看到的錯誤是:

TypeError: item is undefined jquery-ui.js (line 5836, col 13)

這就告訴我們,item沒有定義,從而item.value是不確定的,所以我包括以前在代碼它開始了。這會讓我們回到您的自定義小部件來呈現類別。

當我將它與https://jqueryui.com/autocomplete/#categories的示例進行比較時,我可以看到許多差異。沒有_create方法,而在_renderMenu方法中,沒有爲項目定義的li

這裏的某個地方是問題所在。

我也發現這個錯誤只是針對沒有分類的項目而引發的。

UPDATE

我用文字比較網站上發現在你的代碼的問題。這裏是問題:

self._renderItem(ul, item);

在示例頁面的命令是:它不使用_renderItem()

li = that._renderItemData(ul, item);

,但是這似乎是一個未公開的擴展點:_renderItemData()

基於此:Difference between jQuery autocomplete renderItem and renderItemData您正在正確使用擴展點。

當我做你的代碼這個微小的變化,它的工作原理沒有錯誤:

$.widget("custom.catcomplete", $.ui.autocomplete, { 
    _renderMenu: function(ul, items) { 
    var self = this, currentCategory = ""; 
    $.each(items, function(index, item) { 
     var li; 
     if (item.category != currentCategory) { 
     ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>"); 
     currentCategory = item.category; 
     } 
     li = self._renderItemData(ul, item); 
    }); 
    } 
}); 

工作例如:https://jsfiddle.net/xatu48sc/6/

我懷疑有兩個之間的範圍問題。如果這不好,你真的想用_renderItem(),那麼我可以看看它。使用_renderItemData()確實有效。