Поиск с панелью предложений — различия между версиями

Материал из Umicms
Перейти к:навигация, поиск
 
(не показано 8 промежуточных версий 1 участника)
Строка 1: Строка 1:
  [[category:Вопросы и уроки разработки сайтов на UMI.CMS]]
+
  [[category:Вопросы и уроки разработки сайтов на UMI.CMS]][[Категория:Написание кастомных макросов]]
 +
'''Актуально для версии 2.9'''
  
 
'''Задача''':
 
'''Задача''':
Строка 28: Строка 29:
 
<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("core", "localhost", "umi", "umi", "umi");
+
     $pool->addConnection('core', $host, $login, $password, $dbname);
 
     $pool->init();
 
     $pool->init();
  
     $connection = $pool->getConnection("core");
+
     $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["word"]);
+
$words[$i] = strval($row['word']);
 
     }
 
     }
  
     $result = json_encode($words);
+
     return json_encode($words);
    return $result;
 
 
}
 
}
 
</source>
 
</source>
Строка 49: Строка 55:
 
Текст макроса размещаем в файле "/classes/modules/search/__custom.php", сразу после строчки "//TODO: Write your macroses here". Также нужно задать разрешения для макроса. Создаём в той же папке файл "permissions.custom.php" и в нём настраиваем разрешения:
 
Текст макроса размещаем в файле "/classes/modules/search/__custom.php", сразу после строчки "//TODO: Write your macroses here". Также нужно задать разрешения для макроса. Создаём в той же папке файл "permissions.custom.php" и в нём настраиваем разрешения:
 
<source lang="php">
 
<source lang="php">
$permissions = Array(
+
<?php
    'search' => Array('wordsArray')
+
  $permissions = Array(
);
+
      'search' => Array('wordsArray')
 +
  );
 +
?>
 
</source>
 
</source>
 
</p>
 
</p>
Строка 124: Строка 132:
 
Ограничиваем максимальную высоту виджета в 250 пикселей, скрываем горизонтальный скроллбар и настраиваем отображение вертикального скроллбара по необходимости.
 
Ограничиваем максимальную высоту виджета в 250 пикселей, скрываем горизонтальный скроллбар и настраиваем отображение вертикального скроллбара по необходимости.
 
</p>
 
</p>
 +
<br />
 
<table align="center">
 
<table align="center">
 
<tr>
 
<tr>
Строка 132: Строка 141:
 
<tr>
 
<tr>
 
<td style="font-color: darkblue; font-weight: bold; text-align: center;">
 
<td style="font-color: darkblue; font-weight: bold; text-align: center;">
Результат реализации
+
Пример работы Autocomplete
 
</td>
 
</td>
 
</tr>
 
</tr>
 
</table>
 
</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.png

Пример работы Autocomplete