Поиск с панелью предложений — различия между версиями
Kalexey (обсуждение | вклад) м (переименовал «Реализуем автодополнения для текстовых полей» в «Реализуем автодополнение для текстовых полей») |
Mad grant (обсуждение | вклад) |
||
(не показано 12 промежуточных версий 1 участника) | |||
Строка 1: | Строка 1: | ||
− | [[category:Вопросы и уроки разработки сайтов на UMI.CMS]] | + | [[category:Вопросы и уроки разработки сайтов на UMI.CMS]][[Категория:Написание кастомных макросов]] |
+ | '''Актуально для версии 2.9''' | ||
'''Задача''': | '''Задача''': | ||
Строка 7: | Строка 8: | ||
'''Решение''': | '''Решение''': | ||
<p> | <p> | ||
− | Одно из решений для реализации данной возможности - применение плагина [http://jqueryui.com/demos/autocomplete/ jQuery UI Autocomplete] (client side) и использование | + | Одно из решений для реализации данной возможности - применение плагина [http://jqueryui.com/demos/autocomplete/ jQuery UI Autocomplete] (client side) и использование кастомного макроса, который будет "вытаскивать" массив проиндексированных слов (server side). |
</p> | </p> | ||
<p> | <p> | ||
− | Поскольку Autocomplete уже входит в состав UMI.CMS, нам остаётся только описать стиль для данного виджета. | + | Поскольку Autocomplete уже входит в состав UMI.CMS (файл "/js/jquery/jquery-ui.js"), нам остаётся только описать стиль для данного виджета. |
<table align="center" width="100%"> | <table align="center" width="100%"> | ||
<tr> | <tr> | ||
Строка 24: | Строка 25: | ||
</p> | </p> | ||
<p> | <p> | ||
− | Пишем | + | Пишем кастомный макрос, который будет возвращать массив проиндексированных слов из базы данных (подробнее про написание кастомных макросов Вы можете прочитать в [http://api.umi-cms.ru/ документации]): |
</p> | </p> | ||
<source lang="php"> | <source lang="php"> | ||
public function wordsArray() { | public function wordsArray() { | ||
+ | $config = mainConfiguration::getInstance(); | ||
+ | $host = $config->get('connections', 'core.host'); | ||
+ | $login = $config->get('connections', 'core.login'); | ||
+ | $password = $config->get('connections', 'core.password'); | ||
+ | $dbname = $config->get('connections', 'core.dbname'); | ||
$pool = ConnectionPool::getInstance(); | $pool = ConnectionPool::getInstance(); | ||
− | $pool->addConnection( | + | $pool->addConnection('core', $host, $login, $password, $dbname); |
$pool->init(); | $pool->init(); | ||
− | $connection = $pool->getConnection( | + | $connection = $pool->getConnection('core'); |
$sql = "SELECT word FROM cms3_search_index_words"; | $sql = "SELECT word FROM cms3_search_index_words"; | ||
$query = $connection->query($sql, true); | $query = $connection->query($sql, true); | ||
+ | $pool->closeConnection('core'); | ||
for($i = 0, $numrows = mysql_num_rows($query); $i < $numrows; $i++) { | for($i = 0, $numrows = mysql_num_rows($query); $i < $numrows; $i++) { | ||
$row = mysql_fetch_assoc($query); | $row = mysql_fetch_assoc($query); | ||
− | $words[$i] = strval($row[ | + | $words[$i] = strval($row['word']); |
} | } | ||
− | + | return json_encode($words); | |
− | |||
} | } | ||
</source> | </source> | ||
+ | <p> | ||
+ | Текст макроса размещаем в файле "/classes/modules/search/__custom.php", сразу после строчки "//TODO: Write your macroses here". Также нужно задать разрешения для макроса. Создаём в той же папке файл "permissions.custom.php" и в нём настраиваем разрешения: | ||
+ | <source lang="php"> | ||
+ | <?php | ||
+ | $permissions = Array( | ||
+ | 'search' => Array('wordsArray') | ||
+ | ); | ||
+ | ?> | ||
+ | </source> | ||
+ | </p> | ||
<p> | <p> | ||
Для подключения плагина и стиля необходимо написать следующий код в '''основном''' шаблоне: | Для подключения плагина и стиля необходимо написать следующий код в '''основном''' шаблоне: | ||
<source lang="html4strict"> | <source lang="html4strict"> | ||
<link href="/css/jquery-ui-1.8.20.custom.css" type="text/css" rel="stylesheet" /> | <link href="/css/jquery-ui-1.8.20.custom.css" type="text/css" rel="stylesheet" /> | ||
+ | <script src="/js/jquery/jquery-ui.js" type="text/javascript"></script> | ||
<script type="text/javascript"> | <script type="text/javascript"> | ||
$(document).ready(function() { | $(document).ready(function() { | ||
Строка 101: | Строка 118: | ||
</p> | </p> | ||
<p> | <p> | ||
− | Также хорошо бы добавить скроллбар для виджета, так как количество элементов может быть довольно большим. Для | + | Также хорошо бы добавить скроллбар для виджета, так как количество элементов может быть довольно большим. Для этого нам нужно подправить стиль "ui-autocomplete" в файле "jquery-ui-[версия].custom.css" (либо в Вашем собственном файле стилей): |
<source lang="css"> | <source lang="css"> | ||
.ui-autocomplete { | .ui-autocomplete { | ||
Строка 115: | Строка 132: | ||
Ограничиваем максимальную высоту виджета в 250 пикселей, скрываем горизонтальный скроллбар и настраиваем отображение вертикального скроллбара по необходимости. | Ограничиваем максимальную высоту виджета в 250 пикселей, скрываем горизонтальный скроллбар и настраиваем отображение вертикального скроллбара по необходимости. | ||
</p> | </p> | ||
+ | <br /> | ||
+ | <table align="center"> | ||
+ | <tr> | ||
+ | <td style="border: 1px solid black; padding: 5px;"> | ||
+ | [[Файл:autocomplete.png]] | ||
+ | </td> | ||
+ | </tr> | ||
+ | <tr> | ||
+ | <td style="font-color: darkblue; font-weight: bold; text-align: center;"> | ||
+ | Пример работы Autocomplete | ||
+ | </td> | ||
+ | </tr> | ||
+ | </table> |
Текущая версия на 11:54, 5 июня 2013
Актуально для версии 2.9
Задача:
Реализовать автодополнение при наборе текста в текстовых полях.
Решение:
Одно из решений для реализации данной возможности - применение плагина jQuery UI Autocomplete (client side) и использование кастомного макроса, который будет "вытаскивать" массив проиндексированных слов (server side).
Поскольку Autocomplete уже входит в состав UMI.CMS (файл "/js/jquery/jquery-ui.js"), нам остаётся только описать стиль для данного виджета.
Совет.
Удобнее всего скачать уже готовый стиль (тему) с официального сайта jQuery UI по ссылке: http://jqueryui.com/download. Нас интересует только Autocomplete, поэтому можно убрать все флажки кроме "Autocomplete" в разделе "Widgets". Из скачанного архива нам понадобится только файл вида "jquery-ui-[версия].custom.css" в папке "/css/[название_темы]/" (по-умолчанию используется тема "ui-lightness"). Его необходимо скопировать в папку "/css". В дальнейшем в данном файле можно подредактировать стиль вручную (настроить шрифт, цвет, добавить скроллбар для выпадающего списка и т.д.). |
Пишем кастомный макрос, который будет возвращать массив проиндексированных слов из базы данных (подробнее про написание кастомных макросов Вы можете прочитать в документации):
public function wordsArray() {
$config = mainConfiguration::getInstance();
$host = $config->get('connections', 'core.host');
$login = $config->get('connections', 'core.login');
$password = $config->get('connections', 'core.password');
$dbname = $config->get('connections', 'core.dbname');
$pool = ConnectionPool::getInstance();
$pool->addConnection('core', $host, $login, $password, $dbname);
$pool->init();
$connection = $pool->getConnection('core');
$sql = "SELECT word FROM cms3_search_index_words";
$query = $connection->query($sql, true);
$pool->closeConnection('core');
for($i = 0, $numrows = mysql_num_rows($query); $i < $numrows; $i++) {
$row = mysql_fetch_assoc($query);
$words[$i] = strval($row['word']);
}
return json_encode($words);
}
Текст макроса размещаем в файле "/classes/modules/search/__custom.php", сразу после строчки "//TODO: Write your macroses here". Также нужно задать разрешения для макроса. Создаём в той же папке файл "permissions.custom.php" и в нём настраиваем разрешения:
<?php
$permissions = Array(
'search' => Array('wordsArray')
);
?>
Для подключения плагина и стиля необходимо написать следующий код в основном шаблоне:
<link href="/css/jquery-ui-1.8.20.custom.css" type="text/css" rel="stylesheet" />
<script src="/js/jquery/jquery-ui.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#search').autocomplete({ source: %search wordsArray()% });
});
</script>
В данном случае мы подключаем Autocomplete для текстового поля с идентификатором "search". Можно подключать Autocomplete к конкретным полям через их идентификатор, либо воспользоваться специальным классом для таких полей:
<script type="text/javascript">
$(document).ready(function() {
$('.autocomplete').autocomplete({ source: %search wordsArray()% });
});
</script>
Подключаем Autocomplete для всех полей с классом "autocomplete".
Про настройки для Autocomplete можно прочитать в официальной документации виджета (вкладка "Options").
Важно.
Для сайтов с большим количеством контента необходимо применять опцию "minLength". Она позволяет настроить минимальное число символов для активации Autocomplete. Иначе скрипт может "подвисать" на достаточно большое время. В данной статье механизм тестировался на сайте с числом уникальных проиндексированных слов ~50000 и параметром "minLength" равным 3. |
<script type="text/javascript">
$(document).ready(function() {
$('.autocomplete').autocomplete({
source: %search wordsArray()%,
minLength: 3
});
});
</script>
Пример использования параметра "minLength".
Также хорошо бы добавить скроллбар для виджета, так как количество элементов может быть довольно большим. Для этого нам нужно подправить стиль "ui-autocomplete" в файле "jquery-ui-[версия].custom.css" (либо в Вашем собственном файле стилей):
.ui-autocomplete {
position: absolute;
cursor: default;
max-height: 250px;
overflow-x: hidden;
overflow-y: auto;
}
Ограничиваем максимальную высоту виджета в 250 пикселей, скрываем горизонтальный скроллбар и настраиваем отображение вертикального скроллбара по необходимости.
Пример работы Autocomplete |