За последние 24 часа нас посетили 19395 программистов и 1650 роботов. Сейчас ищут 1125 программистов ...

Ajax в строке поиска на PHP.RU

Тема в разделе "Поисковая система php.ru", создана пользователем vb, 8 сен 2006.

  1. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
    В народ...

    Код (Text):
    1. <!--
    2.  
    3.             AJAX Implementation by Vladimir S. Bredihin <vb dog php dot ru>
    4.  
    5.             Based on Subsys_JsHttpRequest_Php: PHP backend for JavaScript DHTML loader.
    6.             (C) 2005 Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/
    7.  
    8.             Adaptation by 440hz < 440hz dog php dot ru>
    9.  
    10.             2006 (c) Expi-Web
    11.  
    12.         -->
    13. <div id="pu_search" class="pu_search"></div>
    14. <div id='pu_search_description' class="pu_search_decription"></div>
    15. <input type=text style="width:100%; padding-left: 3px" maxlength="200" name=QS class=in id="query"  autocomplete="off">
    Javascript, с учетом что количество блоков может быть увеличено...
    Код (Text):
    1.  
    2. /**
    3.  * Vladimir S. Bredihin <vb dog php.ru> 2006-08-27
    4.  *
    5.  * 2006-08-29 - 440hz - adapting design colors and height block
    6.  * 2006-08-31 - vb - Version 1.1. Added description, onkeydown,
    7.  *                   debug onclick hidden.
    8.  * 2006-09-08 - vb - Version 1.2. Optimize scripts. Debug debug onclick for browser Opera
    9.  *
    10.  */
    11.  
    12. var pu_search;
    13. var obj_id = 'pu_search';
    14. var objs = new Array ();
    15. var ajax = '/ajax/pu_search.php';
    16. var timeout = null;
    17. var timeout_descr = null;
    18.  
    19. function show_help() { 
    20.     var query = '' + document.getElementById('query').value;
    21.     var req = new Subsys_JsHttpRequest_Js();
    22.  
    23.     req.onreadystatechange = function() {      
    24.         if (req.readyState == 4) {
    25.             if (req.responseJS) {              
    26.  
    27.                 // comment: name pu_search == popup_search.
    28.                 var data = '';
    29.                 var tmp = objs[0].row_from + objs[0].row_limit;
    30.                 var count_items =  req.responseJS.fnc_names.length;
    31.                 var obj = document.getElementById(obj_id);
    32.                 objs[0].clear();
    33.                 var started = false;
    34.                 for (var i = 0; i < count_items; i++)
    35.                 {  
    36.                     objs[0].add(req.responseJS.fnc_names[i], req.responseJS.fnc_names[i], req.responseJS.fnc_descriptions[i]);
    37.                     if (!started && tmp <= i) {objs[0].show();started = true;}
    38.                 }
    39.                 if (!started) objs[0].show ();
    40.             }
    41.         }
    42.     }
    43.     if (query!='')
    44.     {
    45.         req.caching = true;
    46.         req.open('POST', ajax, true);
    47.         req.send({ q: query });
    48.     }
    49.     else objs[0].hide();
    50.     clearTimeout(timeout);
    51. }
    52.  
    53. function load_active_description (){
    54.     var req = new Subsys_JsHttpRequest_Js();
    55.  
    56.     req.onreadystatechange = function() {      
    57.         if (req.readyState == 4) {
    58.             if (req.responseJS) {              
    59.                 objs[0].items[objs[0].active].description =  req.responseJS.fnc_description;
    60.                 clearTimeout(timeout_descr);
    61.                 objs[0].items[objs[0].active].descr_canload = 0;
    62.                 puShowDescription0();
    63.             }
    64.         }
    65.     }
    66.     req.caching = true;
    67.     req.open('POST', ajax, true);
    68.     req.send({ l: objs[0].items[objs[0].active].label });
    69. }
    70.  
    71. function puLoadUp() {
    72.     if (timeout) clearTimeout(timeout);
    73.     timeout = setTimeout(show_help, 1000);
    74. }
    75.  
    76. function puSubmit(){
    77.     if (document.getElementById(obj_id).style.display == 'block')
    78.         return false;
    79.     else return true;
    80. }
    81.  
    82. onload = function(){
    83.     objs[0] = new puClass (0, 'pu_search', 'query');
    84.     obj0 = document.getElementById('query');
    85.     obj0.onkeyup= function(Key){       
    86.         if (Key) event = Key;
    87.  
    88.         if (event.keyCode == 13)
    89.         {
    90.             var tmp = obj0.value; //special for IE
    91.             var visible = objs[0].isShowed();
    92.             if (visible) puSelected (0,-1);
    93.             puHide(0);
    94.             if (!visible) obj0.value = tmp; //special for IE
    95.         }
    96.         else if (event.keyCode == 27)
    97.             puHide (0);
    98.         else if (event.keyCode == 38 || event.keyCode == 40)
    99.             puTimeoutDescription0();
    100.         else if (event.keyCode != 38 && event.keyCode != 40 && event.keyCode != 37 && event.keyCode != 39 //arrows
    101.             && event.keyCode != 9 && event.keyCode != 16 && event.keyCode != 17 && event.keyCode != 18 //shift,ctrl,alt,tab
    102.             && event.keyCode != 35 && event.keyCode != 36) //end, home
    103.         {
    104.             objs[0].row_from = 0;
    105.             objs[0].row_limit = 15;
    106.             puLoadUp();
    107.         }
    108.     }
    109.     obj0.onkeydown = function (Key){
    110.         if (Key) event = Key;
    111.             if (event.keyCode == 38)
    112.             {
    113.                 puPrev(0, -1);             
    114.             }
    115.             else if (event.keyCode == 40)
    116.             {
    117.                 puNext(0, -1);
    118.             }
    119.             if (timeout_descr) clearTimeout(timeout_descr);
    120.     }
    121. }
    122. onclick = function (){
    123.     var i
    124.     for ( i = 0; i < objs.length; i++)
    125.         objs[i].hide();
    126. }
    127.  
    128. puItemClass = function (id_obj, label, value, description, number){
    129.    
    130.     var active;
    131.     var label;
    132.     var value;
    133.     var number;
    134.     var id_obj;
    135.     var li_style;
    136.     var description;
    137.     var descr_canload;
    138.    
    139.     this.id_obj = id_obj;
    140.        
    141.     this.label = label;
    142.     this.value = value;
    143.    
    144.     if (description && description != 'Y') this.description = description;
    145.     else this.descr_canload = 1;
    146.    
    147.     this.number = number;
    148.     this.active = 0;
    149.     this.li_style ='';
    150.    
    151.     this.show = function (){
    152.         var noactive;
    153.         if (this.active == 0) noactive = "this.className=\"pu_noactive\"";
    154.         return "<li"
    155.             +" onclick=\"puSelected('"+this.id_obj+"','"+this.number+"')\""
    156.             +" onmouseout='"+noactive+"' "
    157.             +" onmouseover='this.className=\"pu_active\"' "
    158.             +" class='"+this.li_style+"'>"+this.label+"</li>";
    159.     }
    160.     this.deactivate = function(){
    161.         this.active = 0;
    162.         this.li_style = "pu_noactive";
    163.     }
    164.     this.activate = function(){
    165.         this.active = 1;
    166.         this.li_style = "pu_active";
    167.     }
    168. }
    169.  
    170. puClass = function (obj_number, id_select, id_input){
    171.     var active;
    172.     var obj_number;
    173.     var items; 
    174.     var id_select;
    175.     var id_input;
    176.     var row_limit;
    177.     var row_from;
    178.     var pause;
    179.        
    180.     this.active = -1;
    181.     this.obj_number = obj_number;
    182.     this.items = new Array ();
    183.     this.id_input   = id_input;
    184.     this.id_select  = id_select;
    185.    
    186.     this.add = function (label, value, description){
    187.         this.items[this.items.length] =
    188.             new puItemClass (this.obj_number, label, value, description, this.items.length);
    189.         if (this.active < 0)
    190.         {
    191.             this.active = this.items.length-1;
    192.             this.items[this.active].activate();
    193.         }
    194.     }
    195.        
    196.     this.clear = function()
    197.     {      
    198.         this.items.length = 0;
    199.         this.active=-1;
    200.     }
    201.    
    202.     this.show = function()
    203.     {
    204.         document.getElementById(this.id_select).innerHTML = '';
    205.         if (this.items.length > 0)
    206.         {
    207.             count_items = this.items.length;
    208.             var limit = this.row_limit;
    209.             if (limit > count_items) limit = count_items;
    210.             if (this.row_from > 0 && count_items-this.row_from < limit)
    211.                 this.row_from = count_items - limit;
    212.             var inner = '<ul>';
    213.             for (var i = this.row_from; i < limit+this.row_from; i++)
    214.                 inner += this.items[i].show();
    215.             inner += '</ul>';
    216.  
    217.             document.getElementById(this.id_select).innerHTML = inner;
    218.             document.getElementById(this.id_select).style.display='block';
    219.             this.showDescription();
    220.         }
    221.         else
    222.             this.hide();
    223.     }
    224.  
    225.     this.hide = function(){
    226.         this.hideDescription();
    227.         document.getElementById(this.id_select).style.display='none';
    228.     }
    229.    
    230.     this.isShowed = function (){
    231.         if (document.getElementById(this.id_select).style.display=='block') return true; else return false;
    232.     }
    233.    
    234.     this.showDescription = function(){
    235.         if (this.items[this.active].description)
    236.         {
    237.             document.getElementById(this.id_select+'_description').innerHTML = this.items[this.active].description;
    238.             document.getElementById(this.id_select+'_description').style.top = document.getElementById(this.id_select).offsetTop+document.getElementById(this.id_select).offsetHeight;
    239.             document.getElementById(this.id_select+'_description').style.display='block';
    240.         }
    241.     }
    242.     this.hideDescription = function(){
    243.         document.getElementById(this.id_select+'_description').style.display='none';
    244.     }
    245.    
    246.     this.selected = function (number){
    247.         if (number < 0) number = this.active;
    248.         document.getElementById(this.id_input).value = this.items[number].value;
    249.     }
    250.     this.next = function (number){
    251.         if (number < 0)
    252.         {
    253.             if (this.active>=0 && this.items.length > this.active+1)
    254.             {
    255.                 this.hideDescription();
    256.                 this.items[this.active].deactivate()
    257.                 this.active++;
    258.                 this.items[this.active].activate();
    259.                 if (this.row_from + this.row_limit <= this.active) this.row_from = this.active-this.row_limit+1;
    260.                 this.show();
    261.             }
    262.         }
    263.     }
    264.     this.prev = function (number){
    265.         if (number < 0)
    266.         {
    267.             if (this.active>0)
    268.             {
    269.                 this.hideDescription();
    270.                 this.items[this.active].deactivate()
    271.                 this.active--;
    272.                 this.items[this.active].activate();
    273.                 if (this.row_from > this.active) this.row_from = this.active;
    274.                 this.show();
    275.             }
    276.         }
    277.     }
    278. }
    279.  
    280. function puSelected (obj_number, number){
    281.     objs[obj_number].selected(number);
    282. }
    283. function puNext (obj_number, number){
    284.     objs[obj_number].next(number);
    285. }
    286. function puPrev (obj_number, number){
    287.     objs[obj_number].prev(number);
    288. }
    289. function puHide (obj_number){
    290.     objs[obj_number].hide();
    291. }
    292. function puShowDescription0 (){
    293.     objs[0].showDescription();
    294. }
    295. function puTimeoutDescription0(){
    296.     if (timeout_descr) clearTimeout(timeout_descr);
    297.     if (objs[0].active>=0 && objs[0].items && objs[0].items[objs[0].active].descr_canload == 1)
    298.     {
    299.         timeout_descr = setTimeout(load_active_description, 1000);
    300.     }
    301. }
    PHP:
    1. <?php
    2.  
    3. /**
    4.  * Vladimir S. Bredihin vb <vb@php.ru> 2006-08-26
    5.  *
    6.  
    7. /*
    8.  
    9. 29.08.2006 - 440hz
    10. адаптировано под текущую систему
    11.  
    12. 1.08.2006 - vb
    13. адаптировано под версию 1.1. (теперь помимо имени забирается описание)
    14.  
    15. 8.09.2006 - vb
    16. Если количество записей запроса
    17. больше 20 (запрос не точный), то пользователю возвращаются описания только по
    18. наиболее точно написанным функциям.
    19. Добавлена обработка запроса на одно описание.
    20. */
    21.  
    22. include_once('start.inc');
    23.  
    24. require_once('./subsys_ajax.php');
    25.  
    26. $JsHttpRequest =& new Subsys_JsHttpRequest_Php("utf-8");
    27.  
    28. if (isset ($_REQUEST['q'])) {
    29.     $query = addslashes($_REQUEST['q']);   
    30.     $type = 'all';
    31. }
    32. if (isset ($_REQUEST['l'])) {
    33.     $query = addslashes($_REQUEST['l']);   
    34.     $type = 'onedescr';
    35. }
    36.  
    37.  
    38. $result = array ();
    39. if(!empty($query)) {
    40.    
    41.     $result = array ('names'=>array (), 'descriptions'=>array ());
    42.    
    43.     switch($query) {
    44.  
    45.         case 'жопа':
    46.             $result['names'][] = '';
    47.             $result['names'][] = 'не ... такое не ищем &copy; php.ru';
    48.             $result['names'][] = '';
    49.             break;
    50.         default:
    51.             if ($type == 'all')
    52.             {
    53.                 $desc_limit = strlen($query)+2; //Если данных очень много то будем выводить информацию только
    54.                         //по тем функциям, которые написаны/написаны без нескольких символов  
    55.                 $query = str_replace ('_', '\_', $query);   //Экранируем _, чтобы mysql искал этот символ
    56.                 $where = "name LIKE '{$query}%'";
    57.             }
    58.             else //onedescr
    59.                 $where = "name = '{$query}' LIMIT 0,1";
    60.             $objs = $OOPSGlobal['SES']->db->QueryObjects("SELECT name, description FROM php_manual_link_search WHERE {$where}");
    61.             if ( count ($objs) < 20 ) $alldesc = true; else $alldesc = false;
    62.             foreach($objs as $obj)
    63.             {
    64.                 $result['names'][] = $obj->name;
    65.                 if ($alldesc || strlen($obj->name) <= $desc_limit) $result['descriptions'][] = $obj->description;
    66.                 elseif ($obj->description) $result['descriptions'][] = 'Y';
    67.                 else $result['descriptions'][] = null;
    68.             }
    69.             break;
    70.     }
    71. }
    72.  
    73. // возврат
    74. if ($type == 'all')
    75. {
    76.     $_RESULT = array(
    77.         'fnc_names' =>$result['names'],
    78.         'fnc_descriptions'=>$result['descriptions']
    79.     ); 
    80. }
    81. else  //onedescr
    82. {
    83.     $_RESULT = array(
    84.         'fnc_description'=>@$result['descriptions'][0]
    85.     );     
    86. }
    87.  
    88. exit();
    89.  
    90. ?>
    Если у кого-то есть желание доработать, велкАм :)