sobota, 27 lutego 2010

Tworzenie własnych komponentów w Facelets

Tworzenie własnych komponentów w JSF (przynajmniej 1.2, z wersją 2.0 nie miałem się jeszcze okazji zapoznać) jest dość skomplikowane i wymaga poświęcenia trochę czasu. Trzeba utworzyć dwie klasy oraz deskryptor komponentu TLD, no i zarejestrować nowy komponent. W Facelets sprawa jest dużo prostsza i wymaga tylko utworzenia pliku .xhtml, w którym najzwyczajniej tworzymy komponent w HTMLu i rejestracji.
Stwórzmy przykładowy komponent o dość banalnym zadaniu: wyświetlanie pola tekstowego wraz z etykietą.
Czyli dla:
<cust:labeledInput value="#{myBean.name}" id="myInput" label="Podaj imię: " />
Ma się wygenerować:
<label for="myInput">Podaj imię: </label>
<input id="myInput" type="text" name="myInput" value="" />
Zacznijmy od pliku .xhtml tworząc to co normalnie byśmy pisali za każdym razem dla takich komponentów:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:f="http://java.sun.com/jsf/core">

 <ui:composition>
  <h:panelGroup>
   <h:outputLabel for="#{id}" value="#{label}"/>
   <h:inputText id="#{id}" value="#{value}" />
  </h:panelGroup>
 </ui:composition>
</html>
Jeśli przypisujemy do tagu atrybut np. label="napis" to w definicji komponentu odwołujemy się do jego wartości poprzez #{label}. Trzeba przyznać, że jest to dość wygodne.
Pozostało już tylko zarejestrować komponent. Należy najpierw utworzyć plik XML definiujący bibliotekę tagów. myTags.taglib.xml:
<?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://wookasz.blogspot.com/tags</namespace>
 <tag>
  <tag-name>labeledInput</tag-name>
  <source>LabeledInput.xhtml</source>
 </tag>
</facelet-taglib>
I ten plik należy dopisać w konfiguracji web.xml:
<context-param>
 <param-name>facelets.LIBRARIES</param-name>
 <param-value>
  /WEB-INF/facelets/tags/myTags.taglib.xml;
 </param-value>
</context-param>
I to starczy. Przykład użycia:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:cust="http://wookasz.blogspot.com/tags">

 <ui:composition>
  <f:view>
   <h:form>
    <cust:labeledInput value="#{myBean.name}" 
     label="Podaj imię: " id="nameInput"/>
   </h:form>
  </f:view>
 </ui:composition>
</html>
Po drobnej modyfikacji pliku komponentu:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:f="http://java.sun.com/jsf/core">

 <ui:composition>
  <h:panelGroup>
   <h:outputLabel for="#{id}" value="#{label}"/>
   <h:inputText id="#{id}" value="#{value}">
    <ui:insert/>
   </h:inputText>
   <h:message for="#{id}" />
  </h:panelGroup>
 </ui:composition>
</html>
Można będzie wstawiać inne węzły w węzeł komponentu. Umieszczane one będą w miejsce <ui:insert/>. Dodałem jeszcze wyświetlanie komunikatów błedów od walidatora co umożliwia takie użycie:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html" 
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:cust="http://wookasz.blogspot.com/tags">

 <ui:composition>
  <f:view>
   <h:form>
    <cust:labeledInput value="#{myBean.name}" 
     label="Podaj imię: " id="nameInput">
     <f:validateLength maximum="15" minimum="2"/>
    <cust:labeledInput>
   </h:form>
  </f:view>
 </ui:composition>
</html>
...i nie martwienie się oprócz etykiety także o komunikat walidacji.

Brak komentarzy:

Prześlij komentarz