UMIhelp

Разработка сайта на UMI.CMS => Шаблоны XSLT => Тема начата: sergeron от 25 Апреля 2012, 15:36:10

Название: Две цены для одного товара (фильтрация)
Отправлено: sergeron от 25 Апреля 2012, 15:36:10
Есть такая задача:
У товара 2 цены. Например 100р и 200р. Одну пишем в поле price, вторую в дополнительное поле price2 (тоже с типом ЦЕНА). Как сделать фильтрацию, чтобы при запросе цены от 100 до 200, товар выводился? Т.е. отслеживать не четкую цену а коридор от минимума до максимума.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: KTI от 25 Апреля 2012, 16:49:19
про какую фильтрацию идет речь. Что значит отслеживать.
пишите подробнее, фильтровать можно много где: на сайте, xslt, php, js, sql и т.д.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 25 Апреля 2012, 17:00:45
Сайт Современный, xslt. Каталог товаров. Вверху выводится фильтр по цене От-До. Надо товару прописать 2 цены (например первая цена - 100, вторая - 200) . Если теперь в фильтре задать поиск от 100 до 150, он должен вывести товар, а также если задать от 150 до 300, тоже должен вывести.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: admin от 25 Апреля 2012, 17:10:46
то есть диапазон указанный в фильтре должен охватывать как минимум одно поле из тех, что вы прописываете товару (price и price2 например)?

а зачем вам 2 цены у товара, если не секрет?
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 25 Апреля 2012, 20:27:47
Прошу прощения за задержку с ответом, переезд не близкий. Да, с диапазоном все так. А две цены - это, например, стоимость проживания в гостинице (номера могу по-разному стоить, но гостиница должна попасть в выборку от мин до макс)
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: BaceH от 25 Апреля 2012, 22:41:17
при стоимости в 100 можно делать проверку +/- 50, то есть при поиске от 150 до 300, вы будете показывать результаты от 100 до 350.
с двумя ценами вы как то переборщили, если это только для подбора.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 25 Апреля 2012, 22:56:01
Так с двумя ценами это не я переборщил, а заказчик. Мне обход этой темы не нужен, мне решение нужно :)
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: admin от 26 Апреля 2012, 00:09:37
Прмерно таким был мой ответ изначально

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

Но если говорит про практическую сторону решения вопроса, то фактически umi api не даст вам возможность написать запрос, который будет проверять попадает ли в указанный диапазон 1 или 2 поле и если хотя бы одно попадает то выведет этот товар... И тут, скорее всего, придется писать прямой запрос в базу, что еще больше усложняет доработку и поддержание её работоспособности при обновлениях системы в будущем.

Так что я опять же подумал бы имеет ли смысл биться именно над этой реализацией.

но что-то дернуло покопаться))

Выяснилось что в usel протоколе появилась возможность задать  параметр объединения правил фильтрации. Один из параметров позволяет объединить правила фильтрации логичиским ИЛИ.
В итоге, создав файл фильтрации /usels/test.xml
<?xml version="1.0" encoding="utf-8"?>
<selection>
<target result="pages">
<type id="117" />
</target>
<option name="or-mode" value="1" />
<property name="price">
<min-value>{1}</min-value>
<max-value>{2}</max-value>
</property>
<property name="cena2">
<min-value>{1}</min-value>
<max-value>{2}</max-value>
</property>
</selection>

где type id = 117 это тип данных, в котором есть эти 2 поля цены (price и cena2). Если у тебя эти 2 поля с ценой есть во всех типах данных относящихся к базовому типу "Объект каталога", то пиши вместо строчки <type id="117" />, такую строчку <type module="catalog" method="object" />.

В итоге ты можешь проверить работоспособность данного usel запроса например создав товар у которого одно из полей цены имеет значение 302 и прописав вв адресной строке /usel/test/300/310 ты должен получить этот товар
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 26 Апреля 2012, 12:53:18
Гениально, запрос отработал четко. Осталось понять как подключить это к фильтру, буду пробовать.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: admin от 26 Апреля 2012, 13:00:37
чтобы подключить это к фильтру выводишь ручками <input/> от и до с произвольными именами в свой форме фильтрации, при нажатии на кнопку фильтровать система перекинет эти значения в адресную строку, ты их подхватываешь через глобальную <xsl:param> конструкцию, так же как и параметр p в файле /xsltTpls/default.xsl

а на  странице где выводишь результаты пишешь вызов usel протокола подставляя параметры которые ты определил шагом ранее и все работает.

P.S. Только если у тебя будут другие параметры, по которым нужно будет фильтровать... их надо тоже как-то в usel использовать, но там может получиться проблема, так как usel файле уже есть option который позволяет попасть в результаты любому товару, даже если он, например, по цене не подходит, но подходит по производителю.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 26 Апреля 2012, 13:36:54
Спасибо, пошел делать  :)
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 27 Апреля 2012, 16:11:51
Не вышло сделать. Попробуем по шагам, может так получится?
Цитировать
чтобы подключить это к фильтру выводишь ручками <input/> от и до с произвольными именами в свой форме фильтрации
Моя форма фильтрации определяется файлом search-filter модуля каталог, потому что мне нужны еще и другие фильтры, кроме ценового. Весь фильтр построен по принципу поиска по field, а в параметрах либо имена, либо типы. Код который выводит фильтр по типу данных "price", выглядит вот так:
<xsl:template match="field[@data-type = 'price' or @data-type = 'int' or @data-type = 'float']" mode="search">
<div class="grade">
<label class="right">
<span>
<xsl:text>&range-to;</xsl:text>
</span>
<input type="text" name="fields_filter[{@name}][1]" value="{value_to}" class="textinputs" />
</label>
<label>
<span>
<xsl:value-of select="@title" />
<xsl:text> &range-from;</xsl:text>
</span>
<input type="text" name="fields_filter[{@name}][0]" value="{value_from}" class="textinputs" />
</label>
</div>
</xsl:template>
вот вместо этого @data-type = 'price' мне нужно что-то загнать, но я не понимаю что именно.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: KTI от 28 Апреля 2012, 06:45:43
во первых вынеси @data-type = 'price' в отдельный шаблон. т.е. скопируй этот и удали все кроме @data-type = 'price', т.е.
<xsl:template match="field[@data-type = 'price']" mode="search">
у тебя будет отдельный шаблон для обработки поля цена
в нем input поставь например так
<input type="text" name="fields_filter['cena'][1]" value="{value_to}" class="textinputs" />
а подхват параметров с адресной строки я тоже ничего не знаю
где их подхватывать и как..
будем надеяться ув. admin нам подскажет
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 28 Апреля 2012, 10:43:37
это форма
<xsl:template match="field[@data-type = 'price']" mode="search">		
<div class="grade">
<label class="right">
<span>
<xsl:text>&range-to; </xsl:text>
</span>
<input id="amount_to" type="text" name="fields_filter[cena][1]" value="{value_to}" class="textinputs" />
</label>
<label>
<span>
<xsl:value-of select="@title" />
<xsl:text> &range-from; </xsl:text>
</span>
<input id="amount_from" type="text" name="fields_filter[cena][0]" value="{value_to}" class="textinputs" />
</label>
</div>
</xsl:template>
не уверен cena в кавычках ставится или без.

В шаблоне default вставил
<xsl:param name="cena">0</xsl:param>
и дальше, надо вставить в место вывода запрос usel.

Выводится видимо где-то здесь в файле category-view:
<xsl:template match="udata[@method = 'getObjectsList'][total]">
<xsl:apply-templates select="document('udata://catalog/search')" />
<div class="catalog_sort" />
<div class="catalog">       
<div class="objects" umi:element-id="{category_id}" umi:module="catalog" umi:method="getObjectsList" umi:sortable="sortable">
<xsl:apply-templates select="lines/item" mode="short-view">
<xsl:with-param name="cart_items" select="document('udata://emarket/cart/')/udata/items" />
</xsl:apply-templates>
<div class="clear" />
</div>
</div>
<div class="clear" />

<xsl:apply-templates select="total" />
</xsl:template>
и запрос надо вставить типа <xsl:apply-templates select="document(concat('usel://test/?cena=',$cena))/udata" />
Ох, че-то мне кажется, что все я неправильно написал  :)

Название: Re:Две цены для одного товара (фильтрация)
Отправлено: KTI от 28 Апреля 2012, 17:27:03
Да, кавычки не нужны.
Поле cena должно быть фильтруемым и видимым, и оно должно появится в форме фильтра. Появляется?
Вбиваешь туда цифры и жмешь "Применить", в строке браузера должны добавится твои поля, типа
?fields_filter[price][1]=&fields_filter[price][0]=&fields_filter[cena][1]=1000&fields_filter[cena][0]=5000
теперь их надо отловить в category-view, и подсунуть в usel вместо
<xsl:apply-templates select="document('udata://catalog/search')" />
Как-то так, мне кажется
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 28 Апреля 2012, 17:47:41
неее... у меня фильтр вот такой
<xsl:template match="field[@data-type = 'price']" mode="search">		
<div class="grade">
<label class="right">
<span>
<xsl:text>&range-to; </xsl:text>
</span>
<input id="amount_to" type="text" name="fields_filter[cena][1]" value="{value_to}" class="textinputs" />
</label>
<label>
<span>
<xsl:value-of select="@title" />
<xsl:text> &range-from; </xsl:text>
</span>
<input id="amount_from" type="text" name="fields_filter[cena][0]" value="{value_to}" class="textinputs" />
</label>
</div>
</xsl:template>
я по типу price фильтрую, у меня и так поля price и cena2, которые для товара заполнены, сюда попадают. Еще одно поле мне не нужно по-идее. Это новое поле "cena" (как админ писал - любое) нужно для того , чтобы данные полей price и cena2 в него подставлять.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: admin от 02 Мая 2012, 18:08:52
Исходный шаблон для поля типа "цена" не редактируй, то есть оставь его как дефолтный, а вот ниже него добавь свой например так (вывожу тобою приведенный дефолтный и новый ниже него)

<xsl:template match="field[@data-type = 'price' or @data-type = 'int' or @data-type = 'float']" mode="search">
<div class="grade">
<label class="right">
<span>
<xsl:text>&range-to;</xsl:text>
</span>
<input type="text" name="fields_filter[{@name}][1]" value="{value_to}" class="textinputs" />
</label>
<label>
<span>
<xsl:value-of select="@title" />
<xsl:text> &range-from;</xsl:text>
</span>
<input type="text" name="fields_filter[{@name}][0]" value="{value_from}" class="textinputs" />
</label>
</div>
</xsl:template>

<!--твой шаблон для поля цена-->
<xsl:template match="field[@name = 'cena']" mode="search">
<div class="grade">
<label class="right">
<span>
<xsl:text>&range-to;</xsl:text>
</span>
<input type="text" name="cena1" value="{value_to}" class="textinputs" />
</label>
<label>
<span>
<xsl:value-of select="@title" />
<xsl:text> &range-from;</xsl:text>
</span>
<input type="text" name="cena0" value="{value_from}" class="textinputs" />
</label>
</div>
</xsl:template>

после чего у тебя в фильтре появиться новое поле которые при использовании фильтра попадет в адресную строку в таком виде
?cena1=120&cena0=20

оттуда ты их можешь подхватить вставив в файл /xsltTpls/default.xsl

повыше <xsl:param name="p">0</xsl:param> свои параметры
<xsl:param name="cena0"></xsl:param>
<xsl:param name="cena1"></xsl:param>

после этого если ты где-то будешь вызывать usel запрос ты можешь использовать данные параметры и передавать их в usel.

И если ndqj usel лежит тут /usels/test.xml и выглядит так
<?xml version="1.0" encoding="utf-8"?>
<selection>
<target result="pages">
<type id="117" />
</target>
<option name="or-mode" value="1" />
<property name="price">
<min-value>{1}</min-value>
<max-value>{2}</max-value>
</property>
<property name="cena2">
<min-value>{1}</min-value>
<max-value>{2}</max-value>
</property>
</selection>
где type id = 117 это тип данных, в котором есть эти 2 поля цены (price и cena2). Если у тебя эти 2 поля с ценой есть во всех типах данных относящихся к базовому типу "Объект каталога", то пиши вместо строчки <type id="117" />, такую строчку <type module="catalog" method="object" />.

А вызов usel будет выглядеть примерно так:
<xsl:apply-templates select="document(concat('usel://test/',$cena0,'/',$cena1))/udata" mode="usel-result" />

и конечно шаблоны для результатов usel
 <xsl:template match="udata" mode="usel-result">
Результаты usel
<xsl:apply-templates select="page" mode="usel-result" />
</xsl:template>

<xsl:template match="page" mode="usel-result">
<h3><xsl:value-of select="position()"/>. <a href="{@link}"><xsl:value-of select="name" /></a></h3>
</xsl:template>


P.S. НО, опять же, проговорю что эту фильтрация по цене, которая должна попадать в диапазон 2 полей типа цена, заданных у объекта каталога, нельзя будет скомбинировать с другими полями для фильтрации.... смотри часть P.S. в моем посте выше (http://umihelp.ru/forum/index.php/topic,1185.msg4010.html#msg4010)
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 03 Мая 2012, 00:05:51
Спасибо admin, промежуточный результат достигнут, т.е.  фильтр по цене работает, но не живет с остальными фильтрами, как и было предсказано  :) Хороший пример получился, по передаче параметров и usel.
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: KTI от 05 Мая 2012, 09:11:43
я так не понял, зачем нужны эти дополнительные поля для фильтрации cena0, cena1. Если в запросе и в поле "price" и в поле "cena2" используются одни и те-же параметры. Почему нельзя было тогда просто price передать
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: sergeron от 05 Мая 2012, 12:29:31
Честно говоря сам не очень понимаю, видимо нельзя работать с полем price, а надо вместо него делать другое
Название: Re:Две цены для одного товара (фильтрация)
Отправлено: admin от 27 Мая 2012, 01:33:53
если я правильно помню, sergeron, то 2 цены нужны чтобы задавать стоимость минимальную у данного товара и максимальную, а вся задумкав том, чтобы при поиске по интервалу цен учитывались оба поля.

Как я уже и говорил, стоит попробовать сделать разные цены через механизм опционных свойств