В данном уроке мы разберемся, как создать дополнительную функцию для поиска. Идея заключается в том, чтобы при вводе запроса производить поиск по списку отобранных заранее статей (или товаров) и предлагать посетителю подходящие к запросу пункты.
Предложения к поиску
В реализации данного функционала будут задействованы следующие техники: MySQL (база данных), HTML/CSS (разметка страницы и вывод на экран), PHP (для получения данных) и jQuery (для организации запроса AJAX).
В браузерах, которые поддерживают CSS3, результат предложений будет выводиться с тенью.
MySQL
Для работы нам понадобится две таблицы в базе данных. Вот запросы для их организации:
CREATE TABLE IF NOT EXISTS `categories` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`cat_name` varchar(255) NOT NULL,
`cat_url` text NOT NULL,
PRIMARY KEY (`cid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `search` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cat_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`img` varchar(255) NOT NULL,
`desc` text NOT NULL,
`url` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Структура таблиц достаточно простая и очевидная. Таблица categories содержит категории для пунктов списка предложений, а таблица search содержит сами предложения. В архиве с исходным кодом в файле DATABASE.sql содержатся запросы INSERT для заполнения таблиц.
Теперь рассмотрим интерфейс для работы с таблицами.
HTML
HTML код демонстрационной страницы очень прост. Имеется форма с одним полем ввода, даже без кнопки отправки.
<div>
<form id="searchform">
<div>
Что нужно найти? <input type="text" size="30" value="" id="inputString" onkeyup="lookup(this.value);" />
</div>
<div id="suggestions"></div>
</form>
</div>
Элемент div suggestions будет заполняться результатами поиска по таблицам с помощью jQuery.
Результат поиска будет иметь следующую разметку:
<p id="searchresults">
<span class="category">[КАТЕГОРИЯ_ИЗ_БД]</span>
<a href="[URL_ИЗ_БД]">
<img alt="" src="search_images/[ИМЯ_ИЗОБРАЖЕНИЯ_ИЗ_БД]"/>
<span class="searchheading">[ЗАГОЛОВОК_ИЗ_БД]</span>
<span>[ТЕКСТ_ИЗ_БД]</span>
</a>
<a href="[URL_ИЗ_БД]">
<img alt="" src="search_images/[ИМЯ_ИЗОБРАЖЕНИЯ_ИЗ_БД]"/>
<span class="searchheading">[ЗАГОЛОВОК_ИЗ_БД]</span>
<span>[ТЕКСТ_ИЗ_БД]</span>
</a>
<!-- еще предложения -->
<span class="category">[КАТЕГОРИЯ_ИЗ_БД]</span>
<a href="[URL_ИЗ_БД]">
<img alt="" src="search_images/[ИМЯ_ИЗОБРАЖЕНИЯ_ИЗ_БД]"/>
<span class="searchheading">[ЗАГОЛОВОК_ИЗ_БД]</span>
<span>[ТЕКСТ_ИЗ_БД]</span>
</a>
<!-- еще категории -->
<span class="seperator">
<a href="http://evgeniypopov.com/" title="Блог" target="_blank">Нет ничего интересного? Посмотрите на сайте.</a>
</span>
</p>
#searchresults - основной контейнер для результатов поиска по списку предложений.
.category - для разделения категорий.
.seperator - используется для ссылки на другой источник.
Все значения между [] будут подставляться из базы данных.
Теперь перейдем к заданию стилей.
CSS
/* Элементы HTML */
body { font-family:"Lucida Grande","Lucida Sans Unicode",Arial,Verdana,sans-serif;
background-color:#efefef; background-image:url(../images/bg.jpg); }
/* Общие классы */
.break { clear:both; }
/* Форма поиска */
#searchform { margin:50px 200px; font-size:18px; }
#searchform div { color:#eeeeee; }
#searchform div input { font-size:18px; padding:5px; width:400px; }
#suggestions{ position: relative; left:235px; width:400px; display:none; }
Внимание стоит обратить только на #suggestion. мы будем управлять его выводом на экран из JavaScript кода, поэтому изначально он отключен.
Стили для результата поиска предложений несколько сложнее:
/* Результаты поиска */
#searchresults { border-width:1px; border-color:#919191; border-style:solid; width:400px; background-color:#a0a0a0; font-size:10px; line-height:14px; }
#searchresults a { display:block; background-color:#e4e4e4; clear:left; height:80px; text-decoration:none; }
#searchresults a:hover { background-color:#b7b7b7; color:#ffffff; }
#searchresults a img { float:left; padding:5px 10px; }
#searchresults a span.searchheading { display:block; font-weight:bold; padding-top:5px; color:#191919; }
#searchresults a:hover span.searchheading { color:#ffffff; }
#searchresults a span { color:#555555; }
#searchresults a:hover span { color:#f1f1f1; }
#searchresults span.category { font-size:11px; margin:5px; display:block; color:#ffffff; }
#searchresults span.seperator { float:right; padding-right:15px; margin-right:5px;
background-image:url(../images/shortcuts_arrow.gif); background-repeat:no-repeat; background-position:right; }
#searchresults span.seperator a { background-color:transparent; display:block; margin:5px; height:auto; color:#ffffff; }
Панель предложений будет выглядеть следующим образом:
Панель предложений
PHP
Страница с формой поиска - статическая, а панель предложений формируется динамически. Вот полный код PHP, обеспечивающий нужный функционал:
<p id="searchresults">
<?php
// Реализация PHP5 - используем MySQLi.
// mysqli('localhost', 'имя_пользователя', 'пароль', 'база_данных');
$db = new mysqli('localhost', 'имя_пользователя', 'пароль', 'база_данных');
if(!$db) {
// Выводим сообщение об ошибке
echo 'Ошибка: Нет соединения с базой данных.';
} else {
$query = $db->query("SET character_set_connection=utf8");
$query = $db->query("SET character_set_client=utf8");
$query = $db->query("SET character_set_results=utf8");
$query = $db->query("SET NAMES utf8");
// Есть переданная строка запроса?
if(isset($_POST['queryString'])) {
$queryString = $db->real_escape_string($_POST['queryString']);
// Строка запроса имеет длину больше, чем 0?
if(strlen($queryString) >0) {
$query = $db->query("SELECT * FROM search s INNER JOIN categories c ON s.cat_id = c.cid WHERE name LIKE '%" . $queryString . "%' ORDER BY cat_id LIMIT 8");
if($query) {
// Пока есть результат запроса, обрабатываем его.
// Сохраняем ID категории
$catid = 0;
while ($result = $query ->fetch_object()) {
if($result->cat_id != $catid) { // Проверяем, изменилась ли категория
echo '<span class="category">'.$result->cat_name.'</span>';
$catid = $result->cat_id;
}
echo '<a href="'.$result->url.'" target="_blank">';
echo '<img src="search_images/'.$result->img.'" alt="" />';
$name = $result->name;
if(mb_strlen($name,'UTF-8') > 50) {
$name = mb_substr($name, 0, 50, 'UTF-8');
$name .= "...";
}
echo '<span class="searchheading">'.$name.'</span>';
$description = $result->desc;
if(mb_strlen($description, 'UTF-8') > 120) {
$description = mb_substr($description, 0, 120, 'UTF-8');
$description .= "...";
}
echo '<span>'.$description.'</span></a>';
}
echo '<span class="seperator"><a href="http://evgeniypopov.com/" title="Блог" target="_blank">Нет ничего интересного? Посмотрите на сайте.</a></span><br class="break" />';
} else {
echo 'Ошибка: Есть проблемы с запросом.';
}
} else {
// Ничего не делаем
}
} else {
echo 'Должно быть, у вас нет доступа к данному скрипту!';
}
}
?>
</p>
Несколько пояснений:
isset($_POST['queryString']) - когда PHP файл получает запрос POST с значением queryString, то он будет работать (в противном случае будет выдана предупреждающая надпись). Мы будем формировать запрос POST с помощью jQuery.
mysqli - данный скрипт использует реализацию MySQLi. Мы создаем объект базы данных. Нужно поменять значения (имя пользователя, пароль и название базы данных) для соединения с вашей базой данных.
$db->query - Здесь выполняется запрос. Таблица categories присоединяется для получения названия категории. Поиск выполняется только по полю name. Можно расширить возможности, добавив поиск по описанию.
mb_strlen($name, 'UTF-8') > 50 - в данной точке скрипт проверяет длину имени. Если она больше 50 символов, то мы обрезаем ее и добавляем в конец "...".
jQuery
Нам нужно изменить код так, чтобы браузер реагировал на нажатие клавиш, когда производится ввод текста в поле. Для этого добавим к input следующий код:
onkeyup="lookup(this.value);"
Затем определим функцию lookup, в которой будет генерироваться запрос:
function lookup(inputString) {
if(inputString.length == 0) {
$('#suggestions').fadeOut(); // Скрываем поле предложений
} else {
$.post("rpc.php", {queryString: ""+inputString+""}, function(data) { // Выполняем запрос AJAX
$('#suggestions').fadeIn(); // Выводим поле предложений
$('#suggestions').html(data); // Заполняем поле предложений
});
}
Если поле для ввода текста пустое, то панель предложений отключается. При наличии текста формируется запрос AJAX, а результат направляется для вывода на панели предложений.
Готово!