Вернуться к примеруТестовый скроллер

Приступая к созданию проекта, будь то галерея, гостевая книга или форум, сталкиваешься с проблемой написания скроллера. Столкнувшись примерно 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