Фильтр по первой букве алфавита [РЕШЕНО]

Всем добрый день.
Суть задачи:
1. Вывести из таблицы web_user_attributes веб-пользователей, всех и без группировки по буквам и с возможностью задания сортировки обычным способом.
2. Вывести буквы для фильтра.
3. Пагинация.

По вопросам 1 и 2 взял за основу этот топик с DLFirstChar (спасибо авторам за сниппет и пример применения). Но есть вопросы для реализации моей задачи:

а) У меня вывод из другой таблицы, поэтому пришлось в файле DLFixedPrepare.class.php поменять pagetitle на fullname, и теперь вроде как первые буквы фамилий веб-пользователей выводятся.
Но по моему мнению, это не очень хорошо, лучше бы был параметр в вызове сниппета. А может и есть такой параметр? но я не разобрался, подскажите, плз.

Получилось так
<ul id="filter">
<li class="current"><a href="#">ALL</a></li>
[!DLFirstChar? &idField=`id` &idType=`documents` &controller=`onetable` &table=`web_user_attributes` &extender=`user` &usertype=`web` &userFields=`internalKey` &dateFormat=`%d.%m.%Y в %H:%M` &dateSource=`createdon` &orderBy=`id DESC` &ignoreEmpty=`1` &selectFields=`*` 
&orderBy=`BINARY fullname ASC` 
&tpl=`@CODE:[+CharSeparator+][+OnNewChar+]` 
&tplOnNewChar=`@CODE:<li><a href="#">[+char+]</a></li>`!]
</ul>

<ul id="portfolio">	
[!DLFirstChar? &idField=`id` &idType=`documents` &controller=`onetable` &table=`web_user_attributes` &extender=`user` &usertype=`web` &userFields=`internalKey` &dateFormat=`%d.%m.%Y в %H:%M` &dateSource=`createdon` &orderBy=`id DESC` &ignoreEmpty=`1` &selectFields=`*` &display=`20` &id=`cat` &paginate=`pages` &pageLimit=`1` &pageAdjacents=`1`
&tplOnNewChar=`FCharTplOnNew`					
&tpl=`@CODE:[+OnNewChar+]  код чанка `!]
</ul>

FCharTplOnNew:
<li class="[[FCharToLower? &str=`[+char+]`]]">

б) Этот сниппет имеет 2 шаблона — собственно шаблон tpl, и шаблон обертка FCharTplOnNew, в который запихиваются шаблоны из tpl с одинаковыми первыми буквами. Первую букву в шаблон FCharTplOnNew подставляет плейсхолдер [+char+].
Так вот такая конструкция мне не нужна. В моем случае было бы лучше вообще исключить шаблон FCharTplOnNew, а чтобы плейсхолдер [+char+] срабатывал непосредственно в шаблоне tpl. Подскажите, как это сделать?

3. Как сделать пагинацию? Если использовать для фильтрации js, то какой лучше, чтобы был с пагинацией, у меня по этим скриптам не особо((
И можно ли сделать пагинацию средствами DocLister? Что было бы предпочтительнее.

И последний вопрос: а может я вообще не на том пути? Что еще есть в арсенале, что можно применить? Вот смотрел в сторону DLglossary, единственный пример вызова, который нашел, у меня не запустился и вообще не очень понятно, как такое можно применить в моем случае.

Спасибо.

UPD: Решение такое, привожу пример для документов как более общий случай, т.к. у меня более узкое назначение — веб-пользователи, но принцип тот же.

Все на одной странице.

1. Вывод первых букв, используется сниппет DLFirstChar

<form action="" method="get">
<button type="submit" name="char" value="all" >Все</button>
[!DLFirstChar? &parents=`2` &idType=`parents` &depth=`3`
&orderBy=`BINARY pagetitle ASC` 
&tpl=`@CODE: [+CharSeparator+][+OnNewChar+]` 
&tplOnNewChar=`@CODE: <button type="submit" name="char" value="[+char+]">[+char+]</button>`!]
</form>

2. Вывод результатов фильтрации

[!DLglossary? &tvPrefix=`` &frompost=`char` &field=`c.pagetitle` ®ister=`1` &display=`20` &paginate=`pages` &prepare=`priceformat,imgformat` &tvImg=`img` &phpthumb=`w=212,h=212,zc=1,bg=ffffff` &parents=`2` &depth=`3` &tvList=`img,price` &tpl=`item_tpl` 
&TplPrevP=`@CODE: <li><a href="[+link+]" class="page"><i class="fa fa-angle-left"></i></a></li>`
&TplPage=`@CODE: <li><a href="[+link+]" class="page">[+num+]</a></li>`
&TplCurrentPage=`@CODE: <li  class="active"><a>[+num+]</a></li>`
&TplNextP=`@CODE: <li><a href="[+link+]" class="page"><i class="fa fa-angle-right"></i></a></li>`
&TplDotsPage=`@CODE:<li><a href="[+link+]" class="page"> ... </a></li>`
&TplWrapPaginate=`@CODE: <ul class="pagination">[+wrap+]</ul>`
!]
[+pages+]

3. Что бы не было ошибки, когда никакая буква не выбрана (при старте, или когда выбрать «Все» в сниппете DLglossary удалил строки ( у меня 71-73)
if (is_null($char)) {
    $modx->sendErrorPage();
}

4. Если использовать вывод из другой таблицы, в моем случае из web_user_attributes, то в в файле DLFixedPrepare.class.php поменять pagetitle на fullname (или на какое нужно будет).

Спасибо Agel_Nash за сниппеты и за подсказки.

11 комментариев

avatar
пригодится любая информация
  • paic
  • 0
avatar
Интересный этот сниппет DLglossary (запустил).
Что известно по параметрам (по ссылке выше):
fromget – Брать ли данные из GET
frompost – Брать ли данные из POST
char – С какого символа должен начинаться текст
field – Поле по которому фильтровать, по умолчанию: c.pagetitle
setActive – Активировать наборы символов, по умолчанию: 0
regexpSep – Разделитель в наборах регулярок, по умолчанию: ||
regexp – Наборы поддерживаемых регулярок, по умолчанию: a-z||0-9||а-я
loadfilter – Какой фильтр загружать, по умолчанию: пусто
register – Чувствительность к регистру, по умолчанию: 0


т.е. в него параметры должны передаваться. Пока же для пробы вызвал так
[!DLglossary? &tvPrefix=`` &prepare=`priceformat,imgformat` &tvImg=`img` &phpthumb=`w=212,h=212,zc=1,bg=ffffff` &parents=`2` &depth=`3` &tvList=`img,price,sob,sjil,skuh,nroms,such,city,address` &field=`c.pagetitle` &char=`а` ®ister=`1` &tpl=`item_tpl` !]

и он вызвал (с загрузкой страницы) нужные документы на букву а.
Т.е. этот сниппет можно ставить на страницу вывода результатов поиска по букве.
Только не понятно, что должно быть в параметре char по умолчанию, потому что если он пустой, то кажет ошибку. Как по мне, неплохо бы иметь два таких значения — выводить все, или не выводить ничего. Но не ошибку.

Продолжаю разбираться и жду хоть каких-то подсказок.
  • paic
  • 0
avatar
Вы можете написать сниппет обертку. Получать значение символа из GET параметров. Если пусто — вызывать DocLister для вывода всего каталога или отдавать текст «Необходимо выбрать букву».
avatar
Спасибо, я так примерно уже и сделал, но оно мне не нравится.
Я сделал сниппет char
$char = $_GET['char'];
return $char;

пока вставил его в параметр
&char=`[[char]]`

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

<form action="" method="get" style="display: inline; position: relative; top: -3px">
	<select name="char" onchange="this.form.submit()">
		<option value="all" selected="selected">Все</option>
		<option value="А">А</option>
		<option value="Б">Б</option>
	</select>
</form>

В дальнейшем планирую в эту форму воткнуть DLFirstChar для формирования списка букв.
С POST пока не тестировал, но наверное будет примерно так же.
Все работает.
Но мне не нравится то, что я не знаю и не могу разобраться с назначением и порядком использования остальных параметров DLglossary, хотя комментарии в коде сниппета и есть, но мне наверное этого не достаточно((
Я так догадываюсь, что возможностей больше, чем мне удалось раскопать, может и еще где применю этот замечательный сниппет.

Пожалуйста, если не затруднит — несколько слов по параметрам.

А еще я искал и не нашел вывод по умолчанию, когда параметр char еще пуст, т.е. для ALL. Теперь понял, что такого нет и буду писать обертку.

Еще раз спасибо
avatar
Добрый день, подскажите по параметру addWhereList в DLglossary — он его не признает и выдает ошибку.
Вызов такой

[!DLglossary? 
&prepare=`imgformat` 
&tvImg=`photo` 
&phpthumb=`w=263,h=263,zc=1,bg=ffffff` 
&idField=`id` 
&idType=`documents` 
&setActive=`1` 
&frompost=`char` 
&field=`fullname` 
®ister=`1` //register
&controller=`onetable` 
&table=`web_user_attributes` 
&extender=`user` 
&usertype=`web` 
&userFields=`internalKey` 
&dateFormat=`%d.%m.%Y в %H:%M` 
&dateSource=`createdon` 
&orderBy=`id DESC` 
&ignoreEmpty=`1` 
&selectFields=`*` 
&display=`20` 
&id=`cat` 
&paginate=`pages` 
&pageLimit=`1` 
&pageAdjacents=`1` 
&addWhereList=`blocked=0`
&tpl=`@CODE:....!]

Без addWhereList все работает отлично (DLglossary используется совместно с DLFirstChar). Как можно поправить?
avatar
Что показывает debug? Какой текст ошибки?
avatar
« Evo Parse Error »
Execution of a query to the database failed — You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY `c`.`id` ) as `tmp`' at line 1
SQL > SELECT count(*) FROM (SELECT count(*) FROM `db206`.`evo_web_user_attributes` as `c` WHERE blocked=0 AND GROUP BY `c`.`id` ) as `tmp`

debug ничего не выводит, никакой реакции
avatar
Проверил для таблицы content — с ней addWhereList работает нормально, а вот для другой…
avatar
заработало! но причину так и не понял(( ковырялся в коде, пытаясь локализовать, отключая по участкам, и вдруг бах — пробило! Хотя в код никаких изменений не вносил.
avatar
В общем, все оказалось значительно проще.
В сниппете DLglossary есть такие строчки
if (is_null($char)) {
    $modx->sendErrorPage();
}

Если их удалить, сниппет работает при пустом параметре char (т.е. это стартовая страница, до выбора буквы) как обычный DocLister (выводит все), и никакого сниппета-обертки не надо.

Но это для моего случая, если у кого многомиллионный каталог, такого лучше не делать.
avatar
И прилепленный для экспериментов сниппет char тоже в данном случае не надо, так как передается значение из формы в параметре fromget или frompost.
Например, если в форме указан
method="get"
то в вызове DLglossary
указывается
&fromget=`char`
а frompost не нужен. И наоборот при методе post.
Параметр char из вызова DLglossary теперь тоже нужно удалить за ненадобностью.

В общем, осталось разобраться с параметрами setActive и loadfilter. В принципе, я свою задачу уже решил, просто интересно.

Может кто-то все-таки подскажет для сообщества, что это за setActive и loadfilter, и с чем их едят?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.