| Вернуться к примеру | Тестовый скроллер |
Приступая к созданию проекта, будь то галерея, гостевая книга или форум, сталкиваешься с проблемой написания скроллера. Столкнувшись примерно c той же проблемой, я решил написать скроллер который бы отвечал некоторым, на мой взгляд очевидным требованиям.
Вскоре Agat-у потребовались другие возможности и он дополнил пример, оформив его в класс.
Но и на этом я не остановился и еще раз переписал пример, немного упростив его и добавив в него следующие возможности:
Так же произведено небольшое изменение для постраничного вывода. В пределах первой страницы скроллер не перескакивает на середину.
Кортенько расскажу о вызове скроллера. C помощью $scroller[^scroller::create[параметры]] создаем объект класса, после чего вызываем метод ^scroller.draw[]
$selected_table[^table::create[$big_table;$.limit($scroller.limit) $.offset($scroller.offset)]]
^if($selected_table){
^selected_table.menu{$selected_table.item}[
]
^scroller.optimize[^scroller.draw[]]
}
Перед выводом скроллера, его необходимо оптимизировать, иначе, из-за несовершенства браузеров, могут возникнуть проблемы с переводами строк. На экране они отображаются как лишние пробельные символы.
Непосредственно сам класс.
# $Id: scroller.p,v 2.0.4.0 2006/06/26 Eugene Spearance Exp $
@CLASS
scroller
#######################################################################
# Конструктор @create[] задаёт основные параметры скроллера
#
# $scroller[^scroller::create[
# $.path_param[переменная_запроса]
# $.request[]
# $.table_count(число_записей_в_таблице)
# $.number_per_section[количество_элементов_секции]
# $.section_per_page[число_секций_на_странице]
# $.type[page/page_end/пусто]
# $.r_selector[правый_селектор_по_умолчанию_>>]
# $.l_selector[левый_селектор_по_умолчанию_<<]
# $.divider[разделитель_секций_по_умолчанию_пробел]
# $.r_divider[правый_разделитель_по_умолчанию_пусто]
# $.l_divider[левый_разделитель_по_умолчанию_пусто]
# ]
# ]
#
#######################################################################
########################################
# Конструктор класса
#####
@create[params][path_param;field;value]
^try{
^if(def $params && $params is "hash"){
^if(def $params.path_param){
$path_param[$params.path_param]
}{
^throw[scroller;path_param;^$.path_param must be defined]
}
^rem{* Проверяем значение количества записей в таблице *}
^if(def $params.table_count && ^params.table_count.int(0) > 0){
$table_count(^params.table_count.int(1))
}{
^throw[scroller;table_count;^$.table_count must be > 0]
}
^rem{* Возвращаем на место все поля формы *}
^if(def $params.request){
$path[?^params.request.foreach[field;value]{^if($field ne $path_param){$field=^taint[uri][$value]&^;}}$path_param=]
}{
$path[?^form:fields.foreach[field;value]{^if($field ne $path_param){$field=^taint[uri][$value]&^;}}$path_param=]
}
^rem{* Определяем тип скроллера page/page_end/пусто *}
$type[$params.type]
^rem{* Определяем сколько записей отображать *}
$number_per_section(^params.number_per_section.int(1))
^if($number_per_section < 1){$number_per_section(1)}
^rem{* Определяем текущее положение скроллера и делаем защиту от шаловливых рук *}
$record_number(^form:$path_param.int(1))
^if($record_number < 1){$record_number(1)}
^if($record_number > $table_count){$record_number($table_count)}
^rem{* Определяем количество секций на странице *}
^if(def $params.section_per_page){
$section_per_page(^params.section_per_page.int(1))
^if($section_per_page < 1){$section_per_page(1)}
}
$max_section(^math:ceiling($table_count / $number_per_section))
^rem{* Расчитываем сколько секций/страниц вывести на экран *}
^if($section_per_page){
^if($record_number < ($number_per_section * $section_per_page)){
$first_number(1)
}{
$first_number(($record_number \ $number_per_section - $section_per_page \ 2) * $number_per_section)
^if($number_per_section != 1){^first_number.inc[]}
}
$section($section_per_page)
}{
$first_number(1)
^if($number_per_section == 1){
$section($table_count)
}{
$section($max_section)
}
}
^rem{* Рассчитываем значение $first_number, от которого будут считаться ссылки секций/страниц *}
^if(($number_per_section != 1 && $section_per_page || $section_per_page) && ^math:ceiling(($table_count-$first_number) / $number_per_section) < $section){
$first_number(($table_count - $number_per_section * ($section_per_page - 1)) \ $number_per_section * $number_per_section)
^if($number_per_section != 1){^first_number.inc[]}
^if($table_count % $number_per_section == 0 && $number_per_section != 1){^first_number.dec($number_per_section)}
}
^if($first_number < 1){$first_number(1)}
$second_number($first_number + $number_per_section - 1)
^rem{* Левый селектор (по-умолчанию <<) *}
^if(def $params.l_selector){$l_selector[$params.l_selector]}{$l_selector[«^;]}
^rem{* Правый селектор (по-умолчанию >>) *}
^if(def $params.r_selector){$r_selector[$params.r_selector]}{$r_selector[»^;]}
^rem{* Разделитель между номерами секций (по-умолчанию пробел) *}
^if(def $params.divider){$divider[$params.divider]}{$divider[ ]}
^rem{* Разделитель между правым селектором и секциями (по-умолчанию отсутствует) *}
^if(def $params.r_divider){$r_divider[$params.r_divider]}{$r_divider[]}
^rem{* Разделитель между левым селектором и секциями (по-умолчанию отсутствует) *}
^if(def $params.l_divider){$l_divider[$params.l_divider]}{$l_divider[]}
}{
^throw[scroller;create;parameters must be defined]
}
}{
$exception.handled(1)
$error(^_error_codes[$exception.source])
}
### End @create[]
########################################
@GET_limit[]
$result($number_per_section)
### End @GET_limit[]
########################################
@GET_offset[]
$result($record_number - 1)
### End @GET_offset[]
########################################
# выводит скроллер на экран
#####
@draw[][f1;text_link]
^if($error){
$error
}{
^rem{* Выводим левый селектор и левый разделитель если они есть *}
^if($first_number > 1){
^print_selector[^eval($first_number - $number_per_section);$l_selector]
$l_divider
}{
^if(!def $type){$l_divider}
}
^rem{* Основной цикл рисования скроллера *}
^for[f1](1;$section){
^if($first_number <= $table_count){
^if($number_per_section == 1){
$text_link($first_number)
}{
^switch[$type]{
^case[page;page_end]{$text_link(^math:ceiling($first_number / $number_per_section))}
^case[DEFAULT]{
^if($second_number > $table_count){
$text_link{
^if($first_number != $table_count){
${first_number}-$table_count
}{
$first_number
}
}
}{
$text_link[${first_number}-$second_number]
}
}
}
}
^print_link[$text_link]
}
^first_number.inc($number_per_section)
^second_number.inc($number_per_section)
}{
^rem{* Выводим разделитель между секциями *}
^if(($first_number - $number_per_section) <= $table_count){$divider}
}
^rem{* Выводим последнюю секцию если надо *}
^if($type eq "page_end" && $text_link < $max_section){
&hellip^;${path}^eval($max_section * $number_per_section - $number_per_section + 1)" class="scroller_not_selected">$max_section
}
^rem{* Выводим правый селектор и правый разделитель если они есть *}
^if(($second_number - $number_per_section) < $table_count){
$r_divider
^print_selector[^eval($second_number - $number_per_section + 1);$r_selector]
}{
^if(!def $type){$r_divider}
}
}
### End @draw[]
########################################
# делает ссылки активными/неактивными
#####
@print_link[text_link]
^if($record_number >= $first_number && $record_number <= $second_number){
$result[$text_link]
}{
$result[${path}$first_number" class="scroller_not_selected">$text_link]
}
### End @print_link[]
########################################
@print_selector[first_number;text_link]
$result[${path}$first_number" class="scroller_selector">$text_link]
### End @scroller_selector[]
########################################
# 1 - не заданы параметры скроллера
# 2 - не определён $.path_param
# 3 - в таблице слишком мало записей
# 0 - ошибок в параметрах нет
#####
@_error_codes[source]
^switch[$source]{
^case[create]{$result(1)}
^case[path_param]{$result(2)}
^case[table_count]{$result(3)}
^case[DEFAULT]{0}
}
### End @_error_codes[]
########################################
# убиваем лишние переводы строк и символы табуляции
#####
@optimize[text]
$result[^text.match[[\n\t]][g]{}]
### End @optimize[]
| scroller.zip (27 июня 2006 г.) | |
класс скроллера |
| Powered by Parser 3 | Eugene Spearance |