AJAX PHP поиск – часть 2: Prototype
Август 2nd, 2008В первой части урока мы рассмотрели организацию поиска по базе данных MySQL средствами AJAX, PHP и XML. Теперь я хочу показать этот же пример, только с использованием библиотеки prototype. Глобальных изменений не произошло, внешне работает абсолютно одинаково. В конце урока попытаемся подвести небольшую сравнительную характеристику двух этих методов.
Пример: http://logicerror.pp.ru/upload/ajax_search_prototype/
Сравните внешне с предыдущим примером:
http://logicerror.pp.ru/upload/ajax_search_xml/
Элементы всё те же:
- база данных MySQL
- внешний вид – index.html
- ajax скрипт – script.js
- php двигатель – search.php
- ну и собственно prototype.js
Скачать последнюю версию библиотеки prototype можно здесь: http://www.prototypejs.org/ (оф. сайт библиотеки)
Все файлы лежат у нас в одном каталоге. Кому удобнее, может распределить их по различным каталогам на своё усмотрение (js, css, include, …), только не забудьте сделать соответствующие изменения в коде. Итак, начнем!
MySQL database
База данных у нас осталась без изменений, причем лично я ее и не дублировал, то есть вы можете подключиться к той же базе, что и в предыдущем уроке. Тем кто опоздал дублирую структуру.
CREATE TABLE `articles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) collate utf8_unicode_ci NOT NULL, `content` text collate utf8_unicode_ci NOT NULL, `author` varchar(255) collate utf8_unicode_ci NOT NULL, `timestamp` int(11) NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
Ну и, конечно же, моя любимая ссылочка на мусор в базу данных ;) http://logicerror.pp.ru/upload/ajax_search_xml/junk.sql
HTML revised
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta http-equiv="Content-Language" content="ru"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>AJAX PHP search example - Prototype</title> <link rel="stylesheet" href="style.css" type="text/css"> <script src="script.js" type="text/javascript"></script> <script src="prototype.js" type="text/javascript"></script> </head> <body> <div id="wrap"> <form onsubmit="search(); return false;"> <input type="text" class="input" id="search_input" value=""> <input type="submit" class="button" id="search_button" value="» поиск"> </form><br> <div id="search_results"> </div> <div id="searching" style="display: none"> searching </div> </div> </body> </html> |
Здесь мы добавили одну строчку, для подключения библиотеки prototype (естественно при условии того, что файл лежит в том же каталоге, что и index.html):
<script src="prototype.js" type="text/javascript"></script>
Стиль поля searching изменился, пришлось вынести этот атрибут (display: none) из каскадных таблиц, а почему я объясню чуть ниже:
<div id="searching" style="display: none">
Ну и заголовок странички малость изменили ;)
AJAX “prototyping”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function search() { var sSearch = $F("search_input"); if (sSearch.length < 3) { alert("Запрос должен быть не короче 3-х символов."); return false; } $('search_results').hide(); $('searching').show(); new Ajax.Updater('search_results', 'search.php', { method: 'get', parameters: { search: sSearch }, onComplete: function () { $('search_results').show(); $('searching').hide(); } } ); } |
Коротко, правда? Разбираем.
1 2 3 4 5 6 7 | var sSearch = $F("search_input"); if (sSearch.length < 3) { alert("Запрос должен быть не короче 3-х символов."); return false; } |
Здесь осталось всё как есть, кроме обращения к текстовому полю с идентификатором search_input. В предыдущем уроке мы использовали родной document.getElementById().value, что в принципе и повторяет оператор $F в библиотеки prototype. Очень удобно и чисто.
$('search_results').hide(); $('searching').show();
В предыдущем уроке, поле search_results (результаты поиска) мы очищали через свойство .innerHTML. Здесь нам достаточно его спрятать (метод hide()), так как Ajax.Updater() у нас сам очистит это поле в нужный момент.
Ну и показываем поле searching методом .show(). Остановимся здесь на миг. Выше я говорил про атрибут display: none, который пришлось перенести в html из css. Дело в том, что, если этот атрибут хранится в css, то показать блок методом .show() мы не сможем (наверное это особенность prototype ;) ) – пришлось бы использовать .style.display = “block”, но так гораздо удобнее, согласитесь…
Далее следует AJAX запрос на обновление (Updater)
1 2 3 4 5 6 7 8 9 | new Ajax.Updater('search_results', 'search.php', { method: 'get', parameters: { search: sSearch }, onComplete: function () { $('search_results').show(); $('searching').hide(); } } ); |
Уже знакомый нам запрос, ничего сложного. Обновлять будем поле search_results (результаты поиска). Запрашивать будем search.php – наш двигатель. Используем метод GET, передавая переменную sSearch (наш поисковой запрос) в качестве параметра search (получается что-то вроде search.php?search=…).
Ну и прикручиваем обработчик события Complete (готово) – функцию, которая будет прятать строку “ищу” (searching) и показывать поле результатов поиска (search_results). Причем, здесь нам и не нужно ничего добавлять в поле результатов, так как, получив результат, данный вид запроса самостоятельно поместит его в поле search_results. Это особенность запроса на обновление – Ajax.Updater.
PHP двигатель
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?php $db = mysql_connect("localhost", "root", ""); mysql_select_db("ajax_search"); mysql_query("SET CHARACTER SET utf8"); header('Content-type: application/xml; charset=utf-8'); header('Cache-Control: no-cache'); $sString = mysql_real_escape_string($_GET["search"], $db); $sql="SELECT * FROM `articles` WHERE `title` LIKE '%$sString%' OR `content` LIKE '%$sString%' ORDER BY `id` DESC LIMIT 10"; $rs=mysql_query($sql,$db); if (mysql_num_rows($rs) > 0) { while ($row = mysql_fetch_array($rs)) { $content=htmlspecialchars(strip_tags($row["content"])); if (mb_strlen($content, "utf-8") > 250) $content = mb_substr($content, 0, 250, "utf-8") . "..."; ?> <div class="result"> <h1><?=htmlspecialchars($row["title"]);?></h1> <?=$content;?> </div> <? } } else { ?> <div class="result"> <h1> </h1> Ничего не найдено </div> <? } ?> |
В php у нас тоже мало чего изменилось, а именно представление данных. В предыдущем уроке мы использовали XML, а здесь мы используем уже готовый для вывода HTML. Надеюсь вопросов не возникнет. (Не забудьте вместе с XML убрать и его заголовки).
Кстати Content-type советую оставить application/xml, т.к. некоторые браузеры до сих пор не любят ajax запросы к иным форматам.
Вот и всё. Ниже подведена сравнительная характеристика двух методов.
XML vs. Prototype
XML
|
Prototype
|
Если кто-нибудь еще и скорость выполнения проверит – дайте знать.
Размер указан без учета каких-либо методов сжатия.
Отсюда следует вывод. Написание самой такой системы, конечно же легче с использованием prototype, тем самым вы избавляете себя от лишнего парсинга. Тем не менее, потратив чуть больше времени, можно уменьшить объем конечного результата в 9 раз, ну естественно если вы не использовали prototype в другом месте на своей странице (наверное нужно все эти библиотеки уже начать интегрировать в браузеры, и чтобы само-обновлялись).
Ну и конечно же, это еще и дело вкуса ;)

























статья очень помогла спасибо большое:)
Андрей, пожалуйста
у меня небольшой вопросик а как сделать чтобы после отправки запроса к серверу автоматом очищялось поле search_input
или лучше после получения ответа в данном случаи когда выводиться то что вписал в поиск то search_input недолжна очищаться а если ненанел ничего то должна ..вот так лучшебы было:)
Андрей:
$(”search_input”).value = “”;
добавьте к Ajax.Updater’у :) а для второго случая вам нужно будет сначала анализировать полученный результат, прежде чем выводить, и в зависимости от него очищать поле или нет.
просто мне очень нужна ваша помощь.. ваш сайт и статьи очень помогают для разработки приложения web// мне бы второй случай если несложно
Андрей, стукните мне в ICQ сегодня вечером – я постараюсь вам помочь.