Wednesday, January 11, 2012

Bit #38 - Creating a custom ADF Faces client-side converter

You can create a custom ADF Faces client-side converter by ensuring that your converter class implements the org.apache.myfaces.trinidad.convert.ClientConverter interface. This is done in addition to implementing the javax.faces.convert.Converter interface, which implements the custom converter on the server. To implement the ClientConverter interface you need to provide implementation for the getClientConversion() and getClientScript() methods. The getClientConversion() implementation should return the JavaScript constructor of the client converter. The getClientScript() implementation on the other hand should return the actual JavaScript code that implements the client converter.

Example:

public class CustomConverter implements javax.faces.convert.Converter,
                             org.apache.myfaces.trinidad.convert.ClientConverter {
 
    // implement the javax.faces.convert.Converter interface for server-side conversion
  
    // implement the org.apache.myfaces.trinidad.convert.ClientConverter interface for
    // client-side conversion

    // return the JavaScript client converter
    public String getClientConversion(FacesContext context, UIComponent component) {
        return "new CustomConverter()";
    }

    // return the actual client converter JavaScript code
    public String getClientScript(FacesContext context, UIComponent component) {
        return null;
    }
}

For a complete implementation of an ADF Faces client converter take a look at this reference from an older Oracle documentation: http://docs.oracle.com/cd/B25221_05/web.1013/e18745/devguide/clientValidation.html#Client-side%20Validators. Unfortunately, this example is not part of the latest documentation.

Context:

ADF Faces

Sunday, January 8, 2012

Bit #37 - Preventing client events from propagating to the server

ADF Faces client events, i.e. events delivered and implemented on the browser using JavaScript,  by default do propagate to the server. There might be cases however that you don't want this default propagation. For instance, consider an af:commandButton component that defines a clientListener but has no actionListener defined. In this case propagating the client event to the server would be unnecessary. To stop the client event from propagating to the server use the cancel() method of the event class. Event classes are subclasses of the AdfBaseEvent class.

You listen to client events by using the af:clientListener component to call a JavaScript method in response to a client event. The af:clientListener component is used as a child of the ADF Faces component that generates the event.

Finally, note that in order to be able to cancel an event from propagating to the server, the event must be cancelable. You can determine whether an event is cancelable or not by calling the event isCancelable() method. This method returns true if event propagation can be canceled.

Example:

function customClientListener(event)
{

    // cancel event propagation to the server
    if (
event.isCancelable()) {
        event.cancel();
    }

    // do client event processing
}


Context:

ADF Faces

Saturday, January 7, 2012

Bit #36 - Preventing client UI input during server event processing

To prevent any client UI input during the server processing of an event use the AdfCustomEvent preventUserInput() method in your JavaScript client listener. Calling this method prior to queuing the event will display a glass pane covering the browser window and will prevent further user input until the server event processing is complete. To use this method in a client listener first construct an AdfCustomEvent and and then call preventUserInput() on it before calling queue() to propagate the event to the server. Add custom client and server listeners using the af:clientListener and af:serverListener ADF Faces components as children of the component generating the client event.

To make this a generic implementation, think about providing your own custom queue() JavaScript method that accepts among others a boolean indicator called preventInput to indicate whether client UI input is to be prevented or not during the server event processing. For instance: queue(source,serverListener,params,immediate,ppr,preventInput).

Here is an example client listener demonstrating how to use preventUserInput():

Example:

function customClientListener(event)
{

    // get the event source
    var source = event.getSource();

  
    // create the event
    var customEvent = new AdfCustomEvent
(source, "customServerListener", {}, true);
    // call preventUserInput() to block UI input
    customEvent.preventUserInput();

    // send the event to the server
    customEvent.queue(true);
}


Context:

ADF Faces

Friday, January 6, 2012

Bit #35 - Using client behavior tags with ADF Faces

Partial page rendering (PPR) is supported in ADF Faces through the use of the partialTrigers attribute and the AdfFacesContext addPartialTarget() method (see Bit #10 - Selectively enabling Partial Page Rendering programmatically). PPR however can also be achieved in ADF Faces applications using the JSF 2.0 client behavior API and the use of client behavior tags such as the f:ajax tag. This tag is added as a child tag to an ADF Faces component and allow for the execution of PPR in response to a component client event. The specifications of the f:ajax tag is shown below:

<f:ajax event="..." render="..." execute="..." listener="..." ...

event is a string indicating on which events an Ajax request will be fired,
render is a string indicating the identifiers of the components to render
execute is a string indicating the identifiers of the components to be processed on the server
listener indicates a method to invoke during the Ajax request

Complete documentation on the f:ajax tag can be found here: http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/f/ajax.html.

Here is an example of how to use the f:ajax tag to achieve PPR of an af:outputText based on a value change event originating from an af:inputText component:

Example:

<af:inputText ...
    <f:ajax name="change" render="ot" execute="@this" />
</af:inputText>
<af:outputText id="ot" ...


The @this value for the execute attribute indicates that only the component that triggered the Ajax request will be processed on the server.

Context:

ADF Faces

Monday, January 2, 2012

Bit #34 - Using JavaScript partitioning

JavaScript partitioning is the way ADF Faces partitions and delivers JavaScript code to the client. ADF Faces groups its ADF Faces components JavaScript code into so called features and then packages and delivers related features in so called JavaScript partitions. There are two files involved in the delivery of JavaScript partitions to the client: adf-js-features.xml and adf-js-partitions.xml. The first lists the JavaScript classes that make up a feature and its relationships with other features. The second groups the JavaScript features in partitions.

Of course JavaScript can also be delivered to the client by directly adding the JavaScript code to the page or referencing a JavaScript library in the page. Bundling all of your JavaScript code in a few JavaScript Libraries will result in longer download time, while adding JavaScript directly to each page will result in more roundtrips to the server. This is why partitioning is used, as an alternative to specifically tune and customize the JavaScript requirements on a per-application basis.

Here are some examples of the adf-js-features.xml and adf-js-partitions.xml JavaScript partitioning files:

Example:

META-INF/adf-js-features.xml

<?xml version="1.0" encoding="utf-8" ?>
<adf-js-features xmlns="http://xmlns.oracle.com/adf/faces/feature">
  <features xmlns="http://xmlns.oracle.com/adf/faces/feature">
    <feature>
      <feature-name>CustomComponent</feature-name>
      <feature-class>js/custom/CustomComponent.js</feature-class>
      <feature-class>js/custom/CustomComponentEvent.js</feature-class>
      <feature-dependency>AdfRichPopup</feature-dependency>
    </feature>

  </features>
</adf-js-features> 


WEB-INF/adf-js-partitions.xml

<?xml version="1.0" encoding="utf-8" ?>
  <partitions xmlns="http://xmlns.oracle.com/adf/faces/partition">
     <partition>
       <partition-name>CustomPartition</partition-name>
       <feature>CustomComponent</feature>
       <feature>CustomCommon</feature>
       <feature>CustomUtils</feature>
     </partition>

    </partitions>

Context:

ADF Faces
Related Posts Plugin for WordPress, Blogger...