Friday, 31 October 2014

Overriding defaults of PrimeFaces component properties

Introduction

The prime faces components can be customised with many options.  They can be specified by using the properties on the components.  For all these customisation possibilities, there are defaults active so that you don’t need to specify each option.

But what if that default value doesn’t fit for your project. What are your options?  I’ll show you how you can override the default in the case of the datable component.  but other components can be modified in the same way.

Paginator for dataTable.


The dataTable component can show the paginator bar to do navigation in a table with a lot of records.  By default, this bar is shown on top and at the bottom of the table.

But what can you do when you only want to show it at the bottom of the table?

Use the property


Of course, everywhere you place the table on a screen, you can specify the paginatorPosition property and set it to bottom.

    <p:dataTable value="#{personBean.persons}" var="person" paginator="true" rows="3" paginatorPosition="bottom"> 
        <p:column headerText="name"> #{person.name}

    </p:dataTable>

This will work of course but is more work and it can be forgotten by the developers. especially in larger scale applications.

And what happens if they decide that after all, they want to show it as it ways, on top and at the bottom? Change everything again?

CSS is everywhere

Since PrimeFaces relies heavily on CSS, a solution can be found in specifying some CSS style which hide the top paginator bar.

If you inspect the HTML in the browser, you can easily see that the top paginator has a style class with the name ui-paginator-top.

So the following CSS is able to hide the top paginator bar.

    <style type="text/css"> 
        .ui-paginator-top { 
            display: none; 
        } 
    </style>

But this solution is not ideal. The paginator is suppressed in a general way, so we don’t need to change the xhtml files individually.  But the server sends this information to the browser.  So the size of the response is too large because some parts aren’t shown anyway.

Change the defaults


There exists another way to achieve our goal.  You can alter the defaults of PrimeFaces quite easily since PrimeFaces is designed with extensibility in mind. 
The default values are coded in the class org.primefaces.component.datatable.DataTable.

There exists for example a method getPaginatorPosition() which retrieves the values specified in the xhtml file or, when not specified, returns the value “both” which is the default for this property.

So when you extend this class, you can overwrite this method and return, for instance always the value “bottom” and we now have override the default (well we basically ignore the property and always return the same value)

public class MyDataTable extends DataTable { 
    @Override 
    public String getPaginatorPosition() { 
        return "bottom"; 
    } 
}

Just overriding the method in the extended class is not enough.  You need to inform JSF that your version must be used as component class.

This can be done by specifying the following snippet in the faces-config.xml file.

    <component> 
        <component-type>org.primefaces.component.DataTable</component-type> 
        <component-class>be.rubus.web.primefaces.MyDataTable</component-class> 
    </component>

And if you now run the application, you will see that there is no top paginator bar and it isn’t even present in the generated HTML.

How can you know which value you need to use for component-type?  Look in the PrimeFaces faces-config.xml file (you can find it in the META-INF directory of the PrimeFaces jar) and look for the component class you override.  That is the value you need to use.

Conclusion


You can easily override the default values for the PrimeFaces component properties.  Just extend the PrimeFaces component class and put any value you like in the overriding method.  You just have to specify then your component class in the  faces-config.xml file.