Имитируйте предложение Google с помощью AJAX и PHP

Я хочу имитировать предложение Google со следующим кодом, что означает:

шаг 1: Когда пользователь вводит в поле поиска, строка запроса будет обработана php-файлом сервера, и будет возвращена строка предложения запроса (с использованием объекта Ajax).

Шаг 2: Когда пользователь нажимает на предложение запроса, оно заполняет поле поиска (автозаполнение).

Шаг 1 достигается, а шаг 2 - нет. Я думаю, что проблема заключается в методе .click() (позже я использую .live(), но он все еще не работает). Я намерен использовать .live() или .click(), связывая событие onclick с динамически созданным элементом <li>. Любая идея?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script src="jquery-1.4.2.js">
</script>

<style>
#search,#suggest,ul,li{margin: 0; padding:0; width: 200px;}
ul{ list-style-type: none;}
.border{border: solid red 1px; }
</style>

<p>My first language is:</p>
<input type="text" width="200px" id="search" onkeyup="main(this.value)" value="" />
<ul id="suggest"></ul>

<script type="text/javascript">
$(function main(str)
{  //binding any forthcoming li element click event to a function
$('li').live('click', function(){ $("#search").val(array[i]);});
  //setup Ajax object 
  var request=new XMLHttpRequest();
  request.open("GET","language.php?q="+str,true)
  //core function
  request.onreadystatechange=function()
    {    
  if ( request.readyState==4 && request.status==200)
       {  if (str=="") {$('li').remove(); $('ul').removeClass('border');return;}
      $('li').remove();
      reply=request.responseText.split(",");
         for (i=0;i<reply.length;i++)
         {
          //create HTML element of <li>
         $('#suggest').append($('<li>',{id: 'li'+i, html: reply[i]}));
         //style ul
         $('ul').addClass('border');
              }       
      }
    }
  request.send(); 
})
</script>

PHP:

<?php
$q=$_GET[q];

$a[]='english';
$a[]='chinese';
$a[]='japanese';
$a[]='eeeeee';

//lookup all hints from array if length of q>0
if (strlen($q) > 0)
{
  $hint="";
  for($i=0; $i<count($a); $i++)
  {
    if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q))))
    {
      if ($hint=="")
      {
        $hint=$a[$i];
      }
      else
      {
        $hint=$hint." , ".$a[$i];
      }
    }
  }
}

// Set output to "no suggestion" if no hint were found
// or to the correct values
if ($hint == "")
{
  $response="no suggestion";
}
else
{
  $response=$hint;
}

//output the response
echo $response;
?>

person Philip007    schedule 06.06.2010    source источник


Ответы (5)


Вы ищете jQuery Автозаполнение.

person Gert Grenander    schedule 06.06.2010
comment
Спасибо, я изучаю это. Но я все еще хочу знать, что идет не так в моем коде. - person Philip007; 06.06.2010
comment

Вы правы в том, какая линия является проблемой. Вам не хватает # для поиска по ID.

$('li'+i).click(function(){ $("#search").html(array[i]);});

должно быть

$('#li'+i).click(function(){ $("#search").html(array[i]);});

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

person x1a4    schedule 06.06.2010

Кроме того, вы можете подождать, пока пользователь не будет бездействовать. Это предотвращает слишком много циклов. Это означало бы написать что-то вроде:

$("input").keyUp(function(e) {
  clearTimeout(updater);
  updater = setTimeout(whenReady, 200);
}

function whenReady() {
  // update the search box here...
}
person Tim    schedule 06.06.2010
comment
Хорошие мысли. Но я все еще работаю над запуском сценария. Я откладываю вопрос производительности на более поздний срок. - person Philip007; 07.06.2010

Я просмотрел ваш код, и в нем есть несколько проблем. 1) Если вы хотите привязать событие клика к динамически создаваемым элементам, вам следует использовать связыватель событий .live('click', function(){}). Эта функция jQuery будет привязывать событие щелчка к селектору, который будет создан позже в коде динамически, поэтому элементы li, поступающие с сервера, будут автоматически привязаны к событию щелчка, если вы напишете событие live() в функции готовности документа. Прочтите документы.

Вот пример кода

<script>
$(function() {
  $("#suggest li").live('click', function() {
    $("#search").val($(this).text()); // li inner html contains text that needs to put into search box
    alert($(this).text()); // or  alert(array[i]); in your code 
    //c what is the out put of above code. better if you change name of an array
  });
});
</script>

Также значения текстовых элементов ввода извлекаются с использованием функции .val() вместо функции .html в вашем коде $("#search").html(array[i]);

с уважением Аяз Алави

person Ayaz Alavi    schedule 06.06.2010
comment
Я изменил сценарий, как вы сказали. Но это все еще не работает. 1) изменить ('li'+i) на ('#li'+i) 2) изменить .html() на .val() 3) изменить .click на .live('click', function...) Там должны быть другие ошибки в скрипте. Это как-то связано с закрытием? проблема с вложенной функцией? - person Philip007; 07.06.2010
comment
чувак, тебе нужно написать функцию живого клика только для документа при загрузке функции один раз, а не каждый раз, когда ты делаешь ajax. Если вы сделаете это один раз, то каждый li, который позже будет вставлен в #suggest ul, будет автоматически привязан к событиям кликов. также, когда вы нажимаете на li, затем предупреждайте значение массива [i], чтобы увидеть, какое значение массива [i] вы вставляете во ввод (c моим отредактированным кодом выше). Лучше, если вы измените имя массива на другое, потому что это также ключевое слово, используемое Javascript. - person Ayaz Alavi; 07.06.2010
comment
также посмотрите ответ ajax через firebug, чтобы увидеть, правильно ли отвечает сервер. Также ваша иерархия функций в порядке. Я не думаю, что с вызовами функций что-то не так, но убедитесь, что событие keyup запускается через предупреждение или через оператор console.log(str). - person Ayaz Alavi; 07.06.2010
comment
Я помещаю '$' (сокращение от document.ready) перед функцией main(). и переместите перемещение .live за пределы ajax. Тем не менее это не работает. Я изменил сценарий в исходном посте, вы можете скопировать и запустить его на своем компьютере. Я никогда не использовал firebug, но я знаю, что это хорошая вещь, и я проверю ее. Кроме того, что такое оператор console.log(str)? - person Philip007; 08.06.2010

Если вы хотите, чтобы ваше приложение работало правильно, вы также должны кэшировать ответ, например, в случае возврата.

person Rob    schedule 06.06.2010