вторник, 29 июля 2008 г.

JBoss richfaces and true pagination (paging) [ENG]

Offcouse richfaces has own implimintation of paging component - rich:datascroller.
But it's manipulate only already fetching data, and every click send request to bean where probably you fetch data from database.
It is NOT true paging mechanism.
Let's me introduce my own (may be not clear, but fully working) paging.
What we must has, lets see: richfaces, jboss seam and offcouce facelets.
Start with facelets custom tag.
we has some facelets tag configuration file, for example: icust.taglib.xml
and must describe it in web.xml

<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>
/WEB-INF/icust.taglib.xml
</param-value>
</context-param>

in this configuration file, simply specify file name wich contains our tag.
For more information about facelets read facelets documentation

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.icust.ru/jsf</namespace>
<tag>
<tag-name>paging</tag-name>
<source>paging.xhtml</source>
</tag>
</facelet-taglib>

ok! we finish configure our tag =) lets see the tag code

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core">

<c:set var="maxpage" value="9"/>
<c:set var="interval" value="4"/>

<c:if test="${!empty errorlabel}">
<div>
<h:outputText value="#{errorlabel}" escape="false" styleClass="error"/>
</div>
</c:if>
<c:if test="${pagecount ge 2}">
<c:if test="#{! empty page}">
<c:set var="stop" value="${page + interval}" />
<c:if test="${stop le pagecount}">
<c:set var="stop" value="${page + interval}" />
<c:set var="start" value="${page - interval}" />
</c:if>
<c:if test="${stop ge pagecount}">
<c:set var="stop" value="${pagecount}" />
<c:set var="start" value="${pagecount - (2 *interval)}" />
</c:if>
<c:if test="${start le 2}">
<c:set var="start" value="1" />
<c:set var="stop" value="${maxpage}" />
</c:if>
</c:if>
<c:if test="#{page eq 0}">
<c:set var="start" value="1" />
<c:set var="stop" value="${maxpage}" />
<c:set var="page" value="1" />
</c:if>
<c:if test="#{stop ge pagecount}">
<c:set var="stop" value="${pagecount}" />
</c:if>
<div style="width: 100%; height: 27px; margin-top: 9px;">
<div style="float: left;">
<h:outputText value="#{label}"/>
</div>
<div style="float: right;">
<ul class="paging">
<c:if test="#{! (start eq 1)}">
<li>
<h:outputLink value="${url}&pageNo=" styleClass="pagingf">
<h:outputText value="←" escape="false"/>
</h:outputLink>
</li>
</c:if>
<c:forEach var="i" begin="${start}" end="${stop}">
<li>
<c:if test="#{page ne i}">
<h:outputLink value="${url}&pageNo=${i}">
<h:outputText value="${i}"/>
</h:outputLink>
</c:if>
<c:if test="#{page eq i}">
<h:outputLink value="#" styleClass="current">
<h:outputText value="${i}"/>
</h:outputLink>
</c:if>
</li>
</c:forEach>
<c:if test="#{(stop + 1) le pagecount}">
<li>
<h:outputLink value="${url}&pageNo=${pagecount}" styleClass="pagingl">
<h:outputText value="→" escape="false"/>
</h:outputLink>
</li>
</c:if>
</ul>
</div>
</div>
</c:if>
</ui:composition>

us you can see in code we has some additional parameters:
pagecount - total count pages
page - current page number
url - url for paging generate
errorlabel - label for nothing found
and
label - for found (possible found items) message
if page you place tag, for example:
<icust:paging pagecount="#{VideoList.paging.count}" page="#{VideoList.paging.current}" url="#{VideoList.paging.url}" errorlabel="#{VideoList.paging.errorlabel}" label="#{VideoList.paging.label}"/>

you need create simple Paging.class and initialize it in you bean.

public class Paging {
private int count;
private int current;
private String url;
private String label;
private String errorlabel;

public Paging() {
}

public Paging(int count, int current) {
this.count = count;
this.current = current;
}

public int getCurrent() {
return current;
}

public void setCurrent(int current) {
this.current = current;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getLabel() {
return label;
}

public void setLabel(String label) {
this.label = label;
}

/**
* view error label only one
*
* @return
*/
public String getErrorlabel() {
String error = errorlabel;
return error;
}

public void setErrorlabel(String errorlabel) {
this.errorlabel = errorlabel;
}
}

request parameter for page number is pageNo
in bean you can get it by seam annotation:

@RequestParameter
private Integer pageNo;

in page you must create Paging instance BEFORE get value for table.

if you can simplify my solution you are welcome.

Working example you can see here:
http://dev.maryno.net/video/list.html?data=

some css styles for good look:

.paging {
font-size: 75%;
font-family: Arial, sans-serif;
display: inline;
list-style: none;
text-decoration: none;
}

.paging li {
display: inline;
}

.paging a {
padding: 6px 10px 6px 10px;
background: #fff;
text-align: center;
border: 1px solid #beb1b1;
text-decoration: none;
color: #777 !important;
margin-right: 2px;
margin-left: 2px;
height: 25px;
}

.paging a:HOVER {
text-decoration: none;
background: #e6e6e6;
}

.paging a.current {
border: 1px solid #beb1b1;
font-weight: bold;
background: #969696;
color: #fff !important;
}

.paging a.pagingf {
padding: 6px 8px 6px 8px;
margin-right: 8px;
}

.paging a.pagingl {
padding: 6px 8px 6px 8px;
margin-left: 8px;
}

четверг, 17 июля 2008 г.

Список станций московского метро через запятую [RUS]

Вот возникла необходимость добавить в базу все станции метро, а списка под рукой нет. Что бы было удобнее список представлен через запятую (легко проходится любым парсером) из которого легко можно сделать SQL запросы.

Итак вот он:
Авиамоторная,Автозаводская,Академическая,Александровский Сад,Алексеевская,Алтуфьево,Аннино,Арбатская,Аэропорт,Бабушкинская,Багратионовская,Баррикадная,Бауманская,Беговая,Белорусская,Беляево,Бибирево,Библиотека им.Ленина,Битцевский Парк,Борисово,Боровицкая,Боровское шоссе,Ботанический Сад,Братеево,Братиславская,Бульвар адмирала Ушакова,Бульвар Дмитрия Донского,Бунинская аллея,Варшавская,ВДНХ,Владыкино,Водный Стадион,Войковская,Волгоградский Проспект,Волжская,Волоколамская,Воробьевы Горы,Востриково,ВЦ,Выхино,Дегунино,Деловой центр,Динамо,Дмитровская,Добрынинская,Домодедовская,Достоевская,Дубровка,Жулебино,Зябликово,Измайловская,Калужская,Кантемировская,Каховская,Каширская,Киевская,Китай-Город,Кожуховская,Коломенская,Комсомольская,Коньково,Красногвардейская,Краснопресненская,Красносельская,Красные Ворота,Крестьянская Застава,Кропоткинская,Крылатское,Кузнецкий Мост,Кузьминки,Кунцевская,Курская,Кутузовская,Ленинский Проспект,Лихоборы,Лубянка,Люблино,Маркситская,Марьина роща,Марьино,Маяковская,Медведково,Международная,Менделеевская,Минская,Митино,Молодежная,Нагатинская,Нагорная,Нахимовский Проспект,Никулинская,Новогиреево,Новокосино,Новокузнецкая,Новокурьяново,Новопеределкино,Новослободская,Новые Черемушки,Октябрьская,Октябрьское Поле,Олимпийская деревня,Орехово,Останкино,Отрадное,Охотный Ряд,Павелецкая,Парк Культуры,Парк Победы,Партизанская,Первомайская,Перово,Петровско-Разумовская,Печатники,Пионерская,Планерная,Площадь Ильича,Площадь Революции,Площадь Суворова,Полежаевская,Полянка,Пражская,Преображенская Площадь,Пролетарская,Пронская,Проспект Вернадского,Проспект Мира,Профсоюзная,Пушкинская,Речной Вокзал,Рижская,Римская,Рязанский Проспект,Савеловская,Свиблово,Севастопольская,Селигерская,Семеновская,Серпуховская,Славянский бульвар,Смоленская,Сокол,Сокольники,Солнцево,Спортивная,Сретенский бульвар,Строгино,Студенческая,Сухаревская,Сходненская,Таганская,Тверская,Театральная,Текстильщики,Телецентр,Теплый Стан,Терешково,Тимирязевская,Третьяковская,Трубная,Тульская,Тургеневская,Тушинская,Улица 1905 года,Улица академика Королева,Улица Академика Янгеля,Улица Горчакова,Улица Милашенкова,Улица Остафьевская,Улица Подбельского,Улица Сергея Эйзенштейна,Улица Скобелевская,Улица Старокочаловская,Улица Старопотаповская,Университет,Филевский Парк,Фили,Фрунзенская,Царицыно,Цветной бульвар,Челобитьево,Черкизовская,Чертановская,Чеховская,Чистые Пруды,Чкаловская,Шаболовская,Шипиловская,Шоссе Энтузиастов,Щелковская,Щукинская,Электрозаводская,Юбилейная,Юго-Западная,Южная,Ясенево