2009 19 октября

Создаем AJAX поиск по сайту (jquery)

Итак, общие аспекты создания поиска по сайту с применением AJAX. В чем суть - при вводе\удалении каждого символа в поле поиска обращаемся к БД и показываем совпадения Рабочий пример http://www.rcoi.net/beta/ (справа вверху поле поиска) Автор идеи Marco Kuiper На деталях останавливаться не буду, кому интересно без проблем разберутся
1 - подключаем Jquery (я беру с гугля версию 1.3.2)
1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
2 - в HEAD шаблона подключаем следующий JS
1
23
45
67
89
1011
1213
14
function lookup(inputString) {
        if(inputString.length == 0) {                $('#suggestions').fadeOut(); 
        } else {                        $.post("index.php?option=com_pbajax&task=ajaxsearch&no_html=1", {queryString: ""+inputString+""}, function(data) { 
                        $('#suggestions').fadeIn();                        $('#suggestions').html(data); 
                });        }
         $("input").blur(function(){
                $('#suggestions').fadeOut();         });
}
В моем случае я использую собственный компонент com_pbajax с набором определенных тасков, один из которых ajaxsearch и обрабатывает результаты поиска его код ниже 3 - модифицируем шаблон модуля поиска, в моем случае он выглядит так (готовый хтмл на выходе)
1
23
45
<form action="index.php"  method="post" class="search" name="zform">
        <input name="searchword" id="inputString" onkeyup="lookup(this.value);" maxlength="20" class="inputbox" type="text" size="20" value="поиск по сайту"  onblur="if(this.value=='') this.value='поиск по сайту';" onfocus="if(this.value=='поиск по сайту') this.value='';" />        <input type="hidden" name="option" value="com_search" />
        <input type="hidden" name="task"   value="search" /></form>
То есть по событию onkeyup вызываем нашу функцию lookup и отдаем ей на обработку введенное значение 4 - и собственно код обработчика (в моем случае это компонент com_pbajax и в нем кейс ajaxsearch
1
23
45
67
89
1011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
4445
4647
4849
5051
5253
5455
5657
5859
6061
6263
6465
6667
case 'ajaxsearch';
                $queryString    = JRequest::getVar( 'queryString', 1, 'post' ); 
                $db     = JFactory::getDBO();                $user   =& JFactory::getUser();
                 require_once(JPATH_SITE.DS.'components'.DS.'com_content'.DS.'helpers'.DS.'route.php');
                require_once(JPATH_SITE.DS.'libraries/phputf8/utf8.php'); 
                $nullDate       = $db->getNullDate();                $date           =& JFactory::getDate();
                $now            = $date->toMySQL(); 
                $query = 'SELECT a.*, '                . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'
                . ' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug'                . ' FROM #__content AS a'
                . ' INNER JOIN #__categories AS cc ON cc.id = a.catid'                . ' INNER JOIN #__sections AS s ON s.id = a.sectionid'
                . ' WHERE a.title LIKE "%'.$queryString.'%" OR a.introtext LIKE "%'.$queryString.'%" '                . ' AND a.state = 1'
                . ' AND cc.published = 1'                . ' AND s.published = 1'
                . ' AND a.access <= '.(int) $user->get( 'aid' )                . ' AND cc.access <= '.(int) $user->get( 'aid' )
                . ' AND s.access <= '.(int) $user->get( 'aid' )                . ' AND ( a.publish_up = '.$db->Quote($nullDate).' OR a.publish_up <= '.$db->Quote($now).' )'
                . ' AND ( a.publish_down = '.$db->Quote($nullDate).' OR a.publish_down >= '.$db->Quote($now).' )'                . ' ORDER BY title  LIMIT 10'
                ; 
                if ($queryString != '') {                        $db->setQuery($query);
                        $rows = $db->loadObjectList();                        $html = '<div id="searchresults">';
                $n = count($rows);                $i = '1';
                        if ($n) {                                $html .= '<ul class="searchresultsli">';
                                foreach ( $rows as $row )                                        {
                                                $link = ContentHelperRoute::getArticleRoute($row->slug, $row->catslug, $row->sectionid); 
                                                $class = '';                                                if ($i%'2'=='0') {
                                                        $class = 'odd';                                                } else {
                                                    $class = 'even';                                                }
                                                 $html .= '<li class="'.$class.'">';
                                                $html .= $i.' - ';                                                $title = str_replace($queryString, '<span class="highlight">'.$queryString.'</span>', utf8_strtolower($row->title));
                                                $html .= '<a href="'.$link.'">'.$title.'</a>';                                                $html .= '</li>';
                                                $i++;                                        }
                                $html .= '</ul>';                        } else {
                        $html .= 'По Вашему запросу ничего не найдено';                        }
                        $html .= '</div>';                } else {}
                 echo $html;
         break;
Чуть пошагово: 1 - подключили роутер контента и utf8.php для отработки utf8_strtolower (можете этого и не делать) 2 - запрос вытягивает заголовок материала и вступительный текст на предмет поиска совпадений с ключевым запросом $queryString 3 - регуляркой обрабатываем заголовок и подсвечиваем искомое слово в выдаче (в моем случае результат выдается только заголовком, потому если совпадение с $queryString найдено в introtext то в заголовке выдачи подсвечивать нечего) 4 - добавляем классы odd\even для чередования строк (можно и на квери делать, но почему то стало лень) 5 - в нужное место вешаем див для показа результатов поиска, у меня он висит в индексе шаблона
1
<div id="suggestions"></div>
И оформляем CSS стили положение блока и собственно результатов поиска
1
23
45
67
89
/* AJAX search */
#suggestions { position: absolute; width:350px; display:none; z-index: 100; right: 20px; top: 75px;}#suggestions {border: 1px solid #ABD2DE; background-color: #DEEFF4; padding: 10px;text-align: left; color: #1F579A; font-size: 12px;}
#suggestions a, #suggestions li {color: #1F579A; font-size: 12px; text-decoration: none;}#suggestions a:hover {text-decoration: underline;}
ul.searchresultsli, ul.searchresultsli li {margin: 0px; padding: 0px; background-image: none; list-style: none;}ul.searchresultsli li {padding: 7px 5px 7px 3px;}
ul.searchresultsli li.odd {background-color: #F4F1E1;}a.highlight {color: #FE9500 !important; font-weight: bold;}
После этого получаем красивый поиск и пищу для дальнейших модификаций Мопед не мой, автор идеи Marco Kuiper, за что ему отдельное спасибо Готового модуля делать не буду, разобраться думаю не составляем проблем Тема на Joomlaforum P.S. обращаю внимание, что парсер моего блога перевирает одинарные кавычки, потому просто копи\паст работать не будет

Комментарии

0 Димон пишет нам 21.10.2009 00:02
>P.S. обращаю внимание, что парсер моего блога перевирает одинарные кавычки, потому просто копи\паст работать не будет это как?
Сообщить модератору
0 Beliyadm отвечает 21.10.2009 00:40
Попробуйте скопировать кусок кода и вставить в редактор
Сообщить модератору

Недостаточно прав для комментирования