My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

miercuri, 11 februarie 2015

JSF 2.2 - Writing a JSF theme (contract)

Starting with JSF 2.2 we have more control on writing custom themes for JSF. In order to write a basic theme, you have to know a few things, as follows:

1.       Themes are known in JSF as contracts
2.       Contracts are placed in a folder named, contracts under the Web root of the application, or under the META-INF folder that resides in a JAR file
3.       We can alter the location and the name of this folder via WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME context parameter in web.xml
4.       Commonly, under the contracts folder, we define a subfolder for each contract
5.       The subfolder's name represents the contract's name
6.       A contract contains the contract's artifacts such as the CSS, JS, images, and XHTML templates

If we follow a simple <ui:insert> - <ui:define> construction:

<!-- in template file -->
<ui:insert name="content"/>

<!-- in page that uses the template -->
<ui:define name="content">   
...
</ui:define>

Then we can simply isolate the CSS classes from below - basically, we style the HTML rendered by JSF:

.content {}                                     /* main div */
.content div {}                                 /* <h:panelGroup> */
.content table {}                               /* <h:dataTable>, <h:panelGrid> *>
.content table td,.content table th {}
.content table thead th {}
.content table thead th:first-child {}
.content table tbody td {}
.content table tbody .alt td {}
.content table tbody td:first-child {}
.content table tbody tr:last-child td {}
.content table tfoot td div {}
.content table tfoot td {}
.content table tfoot td ul {}
.content table tfoot li {}
.content table tfoot li a {}
.content table tfoot ul.active,.content table tfoot ul a:hover {}
.content input[type=text] {}                    /* <h:inputText> */
.content input[type=password] {}                /* <h:inputsecret> */
.content input[type=submit] {}                  /* <h:commandButton> */
.content textarea {}                            /* <h:inputTextarea> */
.content label {}                               /* <h:outputLabel> */
.content select {}                              /* <h:selectOneMenu>,
                                                <h:selectOneListbox>,
                                                <h:selectManyMenu>,
                                                <h:selectManyListbox> */
.content input[type=radio] {}                   /* <h:selectOneRadio> */
.content input[type=checkbox] {}                /* <h:selectManyCheckbox> */
.content input:hover {}
.content input:active {}
.content input[type=radio] + label {}
.content input[type=radio]:checked + label {}
.content input[type=checkbox] + label {}
.content input[type=checkbox]:checked + label {}

You can easily add CSS classes for the rest of UI components.

Now, you can provide your custom CSS code and obtain a basic JSF theme.

Per example, let's see the output of a JSF page without using CSS code (of course, you can use some CSS snippets to align things and provide a decent look, but we want a theme component's width and/or height):

The code behind this screenshot is listed below (notice that there is no CSS inline/defined in code below, but you can do it if you need to override someting from the theme (e.g.components width and/or height):

                      <h:panelGrid columns="4">
                        <f:facet name="header">
                            <h:graphicImage library="default" name="images/rafa.png"/>
                        </f:facet>      
                        <h:form enctype="multipart/form-data">
                            <h:panelGrid columns="2">
                                <f:facet name="header">
                                    Upload photos with first three ATP players
                                </f:facet>                               
                                <h:outputLabel for="fileToUploadId" value="Select photos:"/>
                                <h:inputFile id="fileToUploadId" value=""/>       
                                <h:outputLabel for="playerPhotoId" value="Players names:"/>                               
                                <h:selectManyListbox id="playerPhotoId" value="">
                                    <f:selectItem itemValue="RN" itemLabel="RAFAEL NADAL" />
                                    <f:selectItem itemValue="RF" itemLabel="NOVAK DJOKOVIC" />
                                    <f:selectItem itemValue="NJ" itemLabel="DAVID FERRER" />                                  
                                </h:selectManyListbox>
                                <h:outputLabel for="selectId" value="Convert to:"/>                               
                                <h:selectOneMenu id="selectId" value="">
                                    <f:selectItem itemValue="PNG" itemLabel="Portable Network Graphics (PNG)" />
                                    <f:selectItem itemValue="JPG" itemLabel="Joint Photographic Experts Group (JPG)" />
                                    <f:selectItem itemValue="BMP" itemLabel="Bitmap (BMP)" />                                   
                                </h:selectOneMenu>                                                               
                            </h:panelGrid>
                        </h:form>                            
                        <h:form>
                            <h:panelGrid columns="1">
                                <f:facet name="header">
                                    Download your photos
                                </f:facet>                               
                                <h:outputLabel for="sizeId" value="Select size:"/>                               
                                <h:panelGroup id="downloadDivId" layout="block">
                                    <h:selectOneRadio id="sizeId" value="">
                                        <f:selectItem itemValue="16x16" itemLabel="16x16" />
                                        <f:selectItem itemValue="250x250" itemLabel="250x250" />
                                        <f:selectItem itemValue="1280x720" itemLabel="1280x720" />
                                    </h:selectOneRadio>   
                                </h:panelGroup>
                                <h:commandButton value="Download"/>
                            </h:panelGrid>
                        </h:form>
                        <h:form>                       
                            <h:panelGrid columns="2">
                                <f:facet name="header">
                                    Log in
                                </f:facet>
                                <h:outputLabel for="emailId" value="E-mail:"/>
                                <h:inputText value=""/>
                                <h:outputLabel for="passwordId" value="Password:"/>
                                <h:inputSecret value=""/>                               
                            </h:panelGrid>
                        </h:form>
                        <h:form>
                            <h:panelGrid columns="2">
                                <f:facet name="header">
                                    Contact Us
                                </f:facet>
                                <h:outputLabel for="subjectId" value="Subject:"/>
                                <h:inputText id="subjectId" value=""/>
                                <h:outputLabel for="messId" value="Message:"/>
                                <h:inputTextarea id="messId" cols="100"/>
                                <f:verbatim/>
                                <h:commandButton value="Send"/>
                            </h:panelGrid>
                        </h:form>
                    </h:panelGrid> 

                    <h:panelGrid columns="1">
                        <f:facet name="header">
                            ATP Singles Today
                        </f:facet>
                        <h:dataTable value="#{playersBean.data}" var="t" border="1">
                            <h:column>
                                <f:facet name="header">
                                    Ranking
                                </f:facet>
                                #{t.ranking}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Name
                                </f:facet>
                                #{t.player}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Age
                                </f:facet>
                                #{t.age}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Birthplace
                                </f:facet>
                                #{t.birthplace}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Residence
                                </f:facet>
                                #{t.residence}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Height (cm)
                                </f:facet>
                                #{t.height}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Weight (kg)
                                </f:facet>
                                #{t.weight}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Coach
                                </f:facet>
                                #{t.coach}
                            </h:column>
                            <h:column>
                                <f:facet name="header">
                                    Born
                                </f:facet>
                                <h:outputText value="#{t.born}">               
                                    <f:convertDateTime pattern="dd.MM.yyyy" />
                                </h:outputText>
                            </h:column>
                            <f:facet name="footer">                           
                                <div id="paging">
                                    <ul>
                                        <li>
                                            <a href="#">
                                                <span>Previous</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#" class="active">
                                                <span>1</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#">
                                                <span>2</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#">
                                                <span>3</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#">
                                                <span>4</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#">
                                                <span>5</span>
                                            </a>
                                        </li>
                                        <li>
                                            <a href="#">
                                                <span>Next</span>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </f:facet>
                        </h:dataTable>
                    </h:panelGrid>

Now, we have populate the CSS classes listed earlier in a file arbitrary named, styles.css. This CSS file and a template file are added under a folder named, jsftheme. This is the JSF contract. Now, we can use it like this:

1.       load the styles.css in template file (template.xhtml)

<h:body>
 <!-- the styles.css contains the theme CSS -->
 <h:outputStylesheet name="styles.css"/>       
  <div class="content">
   <ui:insert name="content"/>
  </div>      
</h:body>

2.       in the main page (index.xhtml) use the template (template.xhtml) and indicate the theme (jsftheme)

<h:body>
 <f:view contracts="jsftheme">
  <ui:composition template="/template.xhtml">                                 
    <ui:define name="content">   
     ... <!-- the JSF page code listed earlier -->
    </ui:define>              
  </ui:composition>                       
</f:view>
</h:body>

The result is in figure below:
So, now you know how to write a simple theme.

The complete code is on GitHub [StylingJSF]

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors