Как сделать поиск с подсказками?

Всем привет!

Есть задача реализовать поисковую строку на сайте, которая бы работал не просто как поиск, а при попытке введении запроса выдавала бы подсказки-ссылки на конкретные разделы сайта. Соответственно переход в итоге должен осуществляться на конкретный раздел, а не на список релевантных страниц.

Например, начинает пользователь вводить в строке «до...», и тут появляется всплывающее окно (аля подсказки Яндекса) с возможными вариантами: "дом в пригороде", "домашняя мебель", "домашние животные" — это все существующие разделы сайта, пользователю потребуется что-то выбрать.

Можно ли такое реализовать, какие сниппеты использовать?

Заранее спасибо за ответы!
Сергей
28 июля 2015, 07:33
modx.pro
1
15 710
0

Комментарии: 18

Василий Наумкин
28 июля 2015, 10:46
+1
Платный mSearch2 это умеет. Проверить можно на этом сайте, в строке поиска справа.
    Сергей
    28 июля 2015, 10:59
    0
    Принял, спасибо!
    Максим Кузнецов
    28 июля 2015, 10:51
    +2
    — Через jquery на событие keyup вешается функция отправки уже введенных пользователем данных при помощи ajax'a на php-скрипт (+ здесь же можно реализовать проверку того, что алгоритм начнет работать только если пользователь ввел 3 или более символов)
    — Пишется пхп, который находит в базе данных или из введенного вами перечня (можно даже из файла) подходящие результаты.
    — Через аякс возвращаются результаты.

    Пример:
    <form id="form">
    	<input type="text" id="searchForm">
    	<ul id="searchHelper" style="display: none;"></ul>
    </form>
    
    <script type="text/javascript">
    	$('#searchForm').keyup(function(){
    		if($(this).val().length>3){
    			//заместо адреса можно перенаправлять на текущую страницу, при условии что на ней вызывается сниппет, перехватывающий ajax-значения
    			$.get('адрес_до_пхп_файла',{'query':$(this).val()},function(data){
    				data = eval('('+data+')');
    				if(data.length!=undefined && data.length>0){
    					$("#searchHelper").html('');
    					for(i in data){
    						$('#searchHelper').append('<li>'+data[i]+'</li>');
    					}
    					$('#searchHelper').css('display', 'block');
    				}
    			});
    		}
    	});
    
    	$('#searchHelper > li').live('click',function(){
    		$('#searchForm').val($(this).text());
    		$('#form').submit();
    	});
    
    </script>
      Сергей
      28 июля 2015, 10:56
      0
      Спасибо, попробую!
        Сергей
        28 июля 2015, 21:41
        0
        То что надо! Спасибо!
        Роман Садоян
        28 июля 2015, 11:49
        +1
        Делал через jQuery.autocomplete, но предварительно распарсил базу по ключам, для вывода связанных ключей:
        --Ключ1:
        ---------Ключ1.1
        ---------Ключ1.2
        --------------------Ключ 1.2.1
        --------------------Ключ 1.2.2
        --------------------Ключ 1.2.3
        ---------Ключ1.3
        --Ключ2
        --Ключ3
        Делал давно еще на Evo, буквально неделю переносил подобное на Revo.
        Делал при помощи своего снипета, форму вывел через AjaxForm
          Сергей
          28 июля 2015, 21:41
          0
          Ага, понял, что jQuery.autocomplete — то что нужно, спасибо!
          Сергей
          29 июля 2015, 06:56
          0
          В итоге решил остановиться на варианте с использованием jQuery.autocomplete — пока получается:

          <script>
          	$(function() {
          		$("#tags").autocomplete({
          		source: tags.php,
          		minLength: 3
          		});
          	});
          </script>
          <input class="input_window" type="text" id="tags" />

          Теперь вопрос:
          1. Как мне в tags.php запихнуть массив с тегами, которые задаются в админке при создании новой страницы через дополнительное поле.
          2. Как реализовать действие, чтобы при нажатии на пункт (тег) в выпадающем поле автоподстановки, загружалась страница с соответствующим тегом?

          Заранее спасибо!
            Максим Кузнецов
            29 июля 2015, 08:05
            0
            1. Вам необходимо в файле вызвать службы модкса, после чего реализовать выборку.
            <?php
            	define('MODX_API_MODE', true);
            
            	require 'адрес_до_корневого_index.php_модкс';
            	
            	// Запускает нужные службы MODX
            	$modx->getService('error','error.modError');
            	$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
            	$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
            
            	//здесь запускаем сниппет, который вернет нам результаты (например, tagLister)

            2. Опять же tagLister, как вариант. Или можно создать отдельную страницу с поиском по тегам, например вот так.
              Сергей
              29 июля 2015, 08:33
              0
              //здесь запускаем сниппет, который вернет нам результаты (например, tagLister)
              Вот здесь можно подробнее? Я представляю себе это как обращение к БД, где можно вытащить массив нужного доп. поля, но как это сделать — ума не приложу.

              Спасибо.
                Максим Кузнецов
                29 июля 2015, 08:42
                0
                Допустим, у нас есть сниппет, который потенциально может иметь вид: [[!name@config? &param1=`value1` &param2=`value2`]]. Вот как его вызов можно транспонировать в код:

                <?php
                	//объявляем массив параметров сниппета name:
                	$allParams = array();
                	
                	//если у сниппета есть параметры, вынесенные в системные наборы параметров c названием config:
                	$configProperty = $modx->getObject('modPropertySet', array ('name' => 'config')); 
                	$allParams = $configProperty->getProperties();
                	
                	//перечисляем обычные параметры сниппета для вызова:
                	$allParams['param1'] = 'value1';
                	$allParams['param2'] = 'value2';
                
                	//запускаем сниппет name с заданным массивом параметров:
                	$result = $modx->runSnippet('name', $allParams);
                
                	//возвращаем
                	return $result;

                — Т.е. вы можете писать как прямые запросы к базе через pdo (об этом лучше почитать отдельно), так и запускать через php целенаправленные сниппеты и возвращать результат.
          Сергей
          30 июля 2015, 02:58
          1
          0
          В общем заработало у меня вот как:

          <script>
          	$(function() {
          		var availableTags = [
          			[[pdoResources? &tpl=`tplTags` &limit=`0` &depth=`0` &parents=`1` &includeTVs=`tag`]]
          		];
          		$( "#tags" ).autocomplete({
          		source: availableTags,
          		minLength: 2,
          		select:function(e,ui) {
          			location.href = ui.item.the_link;              
          			}
          		});
          	});
          </script>
          Чанк tplTags содержит:

          {label:"[[+tv.tag]]", the_link:"/[[~[[+id]]]]"},

          И все бы хорошо, но теперь встали следующие два вопроса:

          1. Как вынести этот скрипт в файл .js? (pdoResources из файла .js не запускается)
          2. Если пользователь вбивает значение, отсутствующее в tv.tag, как вывести сообщение аля: «По Вашему запросу ничего не найдено»?

          Спасибо!
            Максим Кузнецов
            30 июля 2015, 03:42
            0
            1. Ajax. Или оставлять в шаблоне.

            2. Проверять перед добавлением длину результата скрипта и ставить соответствующее условие на вывод.

            $(function() {
            	$("#tags").autocomplete({
            		//ваши параметры        
            		response: function(event, ui) {
            			if (ui.content.length === 0) {
            				$("#empty").text("Результатов по запросу не найдено").css("display", "block");
            			}
            			else {
            				$("#empty").text("").css("display", "none");
            			}
            		}
            	});
            });​
              Сергей
              30 июля 2015, 04:50
              0
              1. Ajax — это как?
              2. Что-то не запустилось — вот что в коде сейчас:
              <script>
              	$(function() {
              		var availableTags = [
              			[[pdoResources? &tpl=`tplTags` &limit=`0` &depth=`0` &parents=`1` &includeTVs=`tag`]]
              		];
              		$( "#tags" ).autocomplete({
              			source: availableTags,
              			minLength: 2,
              			select:function(e,ui) {
              				location.href = ui.item.the_link;              
              			}
              			response:function(event,ui) {
              				if (ui.content.length === 0) {
              					$("#empty").text("Результатов по запросу не найдено").css("display", "block");
              				}
              				else {
              					$("#empty").text("").css("display", "none");
              				}
              			}
              		});
              	});
              </script>
              Верно?

              Выпадающее меню с тегами перестало отображаться.
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            18