Разделы

Выборочный поиск или фильтр док-тов на сайте! (checkbox)

Цель: сделать выборочный поиск по TV параметрам с помощью checkbox'ов,
где может быть выбран от одного до всех параметров фильтра.

Обчитался кучу статей про множественный поиск по TV параметрам через Ditto, но ничего подходящего не нашел, бился часов 5 чтоб не соврать, т.к. некоторые предложения (с помощью &filter=``) не корректно работают с чекбоксами и т.п.

Решил сделать новый но не через &filter, а через Теги (&tagData=``)

Выкладываю полностью свои чанки, TV, скрипты, кому надо сможет легко переделать под любые свои нужнды без особых навыков программирования.
Сам фильтр выглядит так:

Создаем необходимые нам TV:
Для моих целей необходимо было фильтр по 4-ем параметрам.
Назвал их след. образом:
collection_strana — Страны производители
collection_nazn — Назначение плитки
collection_poverh — Тип поверхности плитки
collection_color — Цвет коллекций плитки

«Тип ввода» TV, выбрал «Checkbox», т.к. может выть выбран как один параметр так и все, или вообще ни одного.
в «Возможные значения» указываем след. образом:
Бежевый==bejevyi||Белый==belyi||Голубой==goluboi||Желтый==jeltyi

ВАЖНО! Следует обратить внимание чтоб после ==belyi значение было точно таким же как в нашем чанке в checkbox поле value=«belyi».
Визуальный компонент не выбираем, т.к. нам нужен вывод просто текста.

Далее создаем чанк фильтра {{filter}}:
<form action="[*id*]" method="POST">
<div class="s">
 <label><input type="checkbox" value=""><b>Страна производитель</b><img id="arr" src="/images/arr_bottom.jpg" /></label>
 <div class="strana">
  <label><input type="checkbox" name="strana[]" value="rus">Россия</label>
  <label><input type="checkbox" name="strana[]" value="ukr">Украина</label>
  <label><input type="checkbox" name="strana[]" value="isp">Испания</label>
 </div>
</div>
<div class="m">
 <label><input type="checkbox" value=""><b>Назначение плитки</b><img id="arr" src="/images/arr_bottom.jpg" /></label>
 <div class="naznachenie">
  <label><input type="checkbox" name="nazn[]" value="kitchen">Для кухни</label>
  <label><input type="checkbox" name="nazn[]" value="bath">Для ванной</label>
  <label><input type="checkbox" name="nazn[]" value="roof">Для пола</label>
  <label><input type="checkbox" name="nazn[]" value="mosaic">Мозайка</label>
 </div>
</div>
<div class="p">
 <label><input type="checkbox" value=""><b>Тип поверхности</b><img id="arr" src="/images/arr_bottom.jpg" /></label>
 <div class="poverhnost">
  <label><input type="checkbox" name="poverh[]" value="matovyi">Матовая</label>
  <label><input type="checkbox" name="poverh[]" value="glyanec">Глянцевая</label>
 </div>
</div>
<div class="m">
 <label><input type="checkbox" value=""><b>По цвету</b><img id="arr" src="/images/arr_bottom.jpg" /></label>
 <div class="poverhnost">
  <label><input type="checkbox" name="color[]" value="bejevyi">Бежевый</label>
  <label><input type="checkbox" name="color[]" value="belyi">Белый</label>
  <label><input type="checkbox" name="color[]" value="goluboi">Голубой</label>
  <label><input type="checkbox" name="color[]" value="jeltyi">Желтый</label>
 </div>
</div>
<input id="button" type="submit" value="Подобрать">
</form>


Далее необходимо создать сниппет, который будет выбирать Теги из нашего запроса.
Пример запроса:
/filter/?strana=rus&strana=isp&nazn=kitchen&nazn=bath&color=goluboi&color=jeltyi


а в Ditto передаем:
rus,isp,kitchen,bath,goluboi,jeltyi

т.е. удаляем все лишнее, оставляем только выбранные пользователем Теги.
и назовем его к примеру [[filter]]
Код снипета:
<?php
$strana = $_POST["strana"]; //параметр поля  "name" checkbox но без "[]"
$nazn = $_POST["nazn"]; //параметр поля  "name" checkbox но без "[]"
$poverh = $_POST["poverh"]; //параметр поля  "name" checkbox но без "[]"
$color = $_POST["color"]; //параметр поля  "name" checkbox но без "[]"

if (!isset($strana)) 
	{ 
		$event = "";
	} 
else 
	{ 
		$lect = "";
		for ($i=0;$i<count($strana);$i++)
		{ 
			$k = $strana[$i];
			$lect = $lect . "$k,"; 
		}
		$event = $event . $lect . "</ul>";
		$str .= "$event";
	}

if (!isset($nazn)) 
	{ 
		$event = "";
	} 
else 
	{ 
		$lect2 = "";
		for ($i=0;$i<count($nazn);$i++)
		{ 
			$k = $nazn[$i];
			$lect2 = $lect2 . "$k,"; 
		}
		$event2 = $event2 . $lect2 . "</ul>";
		$str .= "$event2";
	}

if (!isset($poverh)) 
	{ 
		$event = "";
	} 
else 
	{ 
		$lect3 = "";
		for ($i=0;$i<count($poverh);$i++)
		{ 
			$k = $poverh[$i];
			$lect3 = $lect3 . "$k,"; 
		}
		$event3 = $event3 . $lect3 . "</ul>";
		$str .= "$event3";
	}

if (!isset($color)) 
	{ 
		$event = "";
	} 
else 
	{ 
		$lect4 = "";
		for ($i=0;$i<count($color);$i++)
		{ 
			$k = $color[$i];
			$lect4 = $lect4 . "$k,"; 
		}
		$event4 = $event4 . $lect4 . "</ul>";
		$str .= "$event4";
	}

//после этой строки вставлять обработку доп. параметров если необходимо

echo $str; // вывод тегов
?>


Если у вас более 4-ех параметров в фильтре, вы можете добавить еще любое кол-во обработки передаваемых параметров, т.е. дополнить сниппет след. кодом:

if (!isset($color)) // $color - меняете на name из checkbox'a но без []
	{ 
		$event = "";
	} 
else 
	{ 
		$lect4 = ""; //меняете цифру на след.
		for ($i=0;$i<count($color);$i++) // $color - меняете на name из checkbox'a но без []
		{ 
			$k = $color[$i]; // $color - меняете на name из checkbox'a но без []
			$lect4 = $lect4 . "$k,"; //меняете цифры на след.
		}
		$event4 = $event4 . $lect4 . "</ul>"; //меняете цифры на след.
		$str .= "$event4"; //меняете цифры на след.
	}


Далее создаем документ который будет являться страницей вывода результатов и самим фильтром и вызываем чанк и Ditto:

{{filter}}
[!Ditto? &startID=`2` &depth=`3` &tpl=`collection` &display=`all` &tagDelimiter=`,` &tags=`[[filter]]` &tagData=`tvcollection_strana,tvcollection_nazn,tvcollection_poverh,tvcollection_color` &tagMode=`onlyTags` &sortBy=`createdon` &sortDir=`ASC`!]

&startID=`2` — папка откуда беруться док-ты для фильтра
&depth=`3` — глубина поиска
&tpl=`collection` — шаблон вывода
&display=`all` — число отображаемых док-тов
&tagDelimiter=`,` — резделитель тегов (не менять)
&tags=`[[filter]]` — наш сниппет
&tagData=`tvcollection_strana,tvcollection_nazn,tvcollection_poverh,tvcollection_color` — изменить на свои TV (ОБЯЗАТЕЛЬНО добавляйте перед названием вашего TV-параметра — «tv»)

Ну вроде все!
ЗЫ, Извените за много букв)
  • +1
  • 24 января 2011, 16:24
  • maloy

Комментарии (13)

RSS свернуть / развернуть
0
т.е. нужно просто передачу параметров из этого вида
?strana=rus&strana=isp&nazn=kitchen&nazn=bath&color=goluboi&color=jeltyi
преобразовать в такой
?strana=rus,isp&nazn=kitchen,bath&color=goluboi,jeltyi

обыскался уже везде…
avatar

maloy

  • 24 января 2011, 16:28
0
А я дурак велосипед изобретал…
avatar

Zinich66

  • 7 февраля 2011, 17:06
0
Есть tv-параметры соответствующие определенному типу товара.
Как возможно сделать появление нужных чекбоксов при выборе какого-то товара из выпадающего списка?
avatar

drvirus

  • 16 февраля 2011, 14:21
0
Точнее, как такой фильтр с выпадающим списком обработать?
avatar

drvirus

  • 17 февраля 2011, 21:51
0
всё таки для формы Name-писать без квадратных скобок;

а что делает — $event?
avatar

doc555

  • 31 мая 2011, 03:57
0
может — $event2 / $event3 /…
avatar

doc555

  • 31 мая 2011, 03:58
0
Спасибо большое! Сам бы не разобрался! примечание: в документе, который будет являться страницей вывода результатов нужно снять галочку с «Кэшируемый». может я конечно что то не то сказал, но с ней у меня ничего не работало)
avatar

lollypops

  • 17 февраля 2012, 17:35
0
И у меня еще вопрос. Не подскажите полному нулю в php, как сделать так, чтобы запросы работали друг с другом?.. Объясняю: Выбираем допустим Страна: Россия, Назначение: для пола, Тип: матовая, цвет: голубой. Нажимаем — подобрать и выходят (лично у меня) все ресурсы, которые относятся к «России» и, допустим, все ресурсы «для пола». Но среди «для пола» есть, ресурсы, которые не относятся к запросу «Россия». Извиняюсь за тафтологию, но по другому не объяснить.
avatar

lollypops

  • 19 февраля 2012, 03:09
0
То есть, в идеале, фильтр должен работать так: запросы: Россия, для пола, матовая, голубой — результат: ресурсы с «Россия, для пола, матовая, голубой». Если таких нет — ничего не выдавать. То есть нужен последовательный фильтр. Не намекнете, хоть чуть чуть?))
avatar

lollypops

  • 19 февраля 2012, 03:12
0
подскажите почему может не работать фильтр?
вместо требуемой строки
/filter/?strana=rus&strana=isp&nazn=kitchen&nazn=bath&color=goluboi&color=jeltyi
выдаёт просто 3
тройка видимо startID
avatar

vitvlg

  • 29 февраля 2012, 15:08
0
Супер!

Но работает только при tagMode:
&tagMode=`onlyTags`

но почему-то не хочет при:
&tagMode=`onlyAllTags`

Надо, чтобы выдавались док-ты, у которых есть весь набор, отмеченный в форме.
Причём, что заметил, если вместо вызова сниппета в параметр «tags» поставить конкретный набор, к примеру:
&tags=`rus,kitchen,mozaic,bejevyi`

то все работает нормально и выдаются док-ты, у которых отмечены все эти параметры.
Но если ставим в Ditto вызов сниппета [[filter]], то не выдаёт ничего.

Танцы с бубном вокруг кеширования/некеширования ничего не дают.
Голый вызов сниппета [[filter]] (не в вызове Ditto) выдает правильно:
rus,kitchen,mozaic,bejevyi

Куда можно копнуть?
avatar

rpa-design

  • 12 марта 2012, 15:21
0
Можно копнуть в сторону запуска Ditto через runSnippet. Из плюсов способа — нормально работающая пагинация.

Можно так же копнуть в сторону экстендера andFilter, при его использовании фильтрация будет по-умолчанию только по конкретному набору тегов. Ресурс должен иметь строго заданный набор тегов, чтобы попасть в выборку.

У меня появился вот такой вопрос: как лучше сохранить отмеченные чекбоксы после отправки формы?

Поначалу сделал как тут modx-shopkeeper.ru/forum/viewtopic.php?id=1049 и все заработало, но смущает количество вызовов сниппета, ибо он вызывается некэшированным в каждом input`е формы.
avatar

zubikov

  • 30 марта 2012, 12:37
+1
Я чекаю все значения яваскриптом! Сначала передаю гет запросом все необходимые параметры, потом разбираю URI. И отмечаю чекбоксы или что-то другое.
avatar

vanchelo

  • 30 марта 2012, 16:06

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.