Showing posts with label ADF Faces. Show all posts
Showing posts with label ADF Faces. Show all posts

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

Friday, December 30, 2011

Bit #33 - Using custom client attributes

To use a custom client attribute for an ADF Faces component use an af:clientAttribute component as a child component of that component and specify the name and value of the custom attribute. Then use the JavaScript AdfUIComponent.getProperty() method to retrieve the property value at runtime on the client.

Note that custom client attributes are not delivered to the server automatically. To do so you must create a custom event from the client to the server using an af:serverListener component and queue the event by calling AdfCustomEvent.queue().

Here is an example of adding a custom client attribute to an af:inputText component. We have added an af:clientListener to demonstrate calling the AdfUIComponent.getProperty() method.

Example:

            <af:inputText label="Label 1" id="it1">
                <af:clientAttribute name="customAttribute" value="Hello, world"/>
                <af:clientListener type="valueChange" method="onInputTextValueChange"/>
            </af:inputText>


....
            <af:resource type="javascript">
            function onInputTextValueChange(event) {
                var inputText = event.getSource();
                // retrieve and display the custom client attribute
                alert(inputText.getProperty("customAttribute"));
            }
            </af:resource>



Context:

ADF Faces

Wednesday, December 28, 2011

Bit #32 - Locating a component on the client

To locate a component on the client side of an ADF Faces application use any of the AdfUIComponent.findComponent() or AdfPage.PAGE.findComponentByAbsoluteId() methods. Both of these methods accept the component's identifier. The difference between the two is that while AdfUIComponent.findComponent() accepts a relative expression representing the component identifier, AdfPage.PAGE.findComponentByAbsoluteId() expects an absolute expression for the component's identifier. Absolute expressions use a fully qualified client identifier with a leading separator character, for example :container1:container2:componentId.

To guaranty that a client side instance of the component exists, ensure that you have set the component's clientComponent property to true. Alternatively, you can add a clientListener to the component instead.

Finally, do not use the AdfPage.PAGE.findComponent() method because its implementation may change from release to release.

Example:

function exampleFunc(actionEvent) { 
    var someComponent=actionEvent.getSource();
    // use findComponent() to locate a component relative to 'someComponent'
    var someOtherComponent=someComponent.findComponent("componentId");
    someOtherComponent.setValue("Hello") 


Context:

ADF Faces

Friday, May 6, 2011

Bit #30 - Displaying the current row on an af:table

You can display the current record number as you navigate an af:table by using certain information available on the table's iterator binding, namely the currentRowIndexInRange and rangeStart attributes. The current row can be calculated by the following EL expression: #{bindings.Iterator.rangeStart+bindings.Iterator.currentRowIndexInRange+1}, where Iterator is the table's bound iterator identifier. We add one because the row index is 0-based. You will need to surround the af:table with an af:panelCollection and use one of its facets - I suggest using the secondaryToolbar facet - to add an af:toolbar with an af:outputText inside it. For the current record count to be updated as you navigate the table, you will need to setup a partialTrigger on the af:outputText to the af:table. The example below shows this implementation.

Example:

<af:panelcollection ... >
<af:table id="tbl1" ... >
  </af:table>

    <f:facet name="secondaryToolbar">
      <af:toolbar id="t1">
        <af:group id="g1">
          <af:outputtext id="ot24" value="#{bindings.Employees1Iterator.rangeStart+bindings.Employees1Iterator.currentRowIndexInRange+1}/#{bindings.Employees1Iterator.estimatedRowCount} records">
                                         visible="#{bindings.Employees1Iterator.currentRow ne null}"
                                         partialTriggers="tbl1 ::qryId1"/>
        </af:group
>
      </af:toolbar>
    </f:facet>
  </af:panelcollection>

Here is what the output looks like:


Context:

JSF page

Thursday, March 24, 2011

Bit #29 - Dynamically configure ADF trace logs in WebLogic

ADF-specific logging can be dynamically configured in WebLogic via the wlst script. Ensure that you run the wlst script that is located in oracle common directory (and not the one in the WebLogic server home). Then connect to the administration server and use the setLogLevel() command to change the appropriate logger's level. To configure Business Components logs specify oracle.jbo as the logger. Similarly to configure the ADF Controller and ADF Faces logs use the oracle.adf.controller and oracle.adf.faces loggers respectively. For the example below, the ADF application is deployed on ManagedServer1. As mentioned, these changes to the logging configuration can be done at run-time without the need to re-start the server.


Example:

wlst
connect('weblogic','weblogic1', 't3://192.168.5.134:7001')
setLogLevel(target='ManagedServer1', logger='oracle.jbo', level='FINEST')


Context:

ADF BC
ADF Faces
ADF Controller


References:

http://jdeveloperfaq.blogspot.com/2011/03/faq-33-how-to-configure-adf-diagnostics.html

Saturday, June 12, 2010

Bit #19 - Downloading a file

Use an af:fileDownloadActionListener Rich Faces component to download data from the server to a client machine. Add the listener inside the component that will initiate the download, an af:commandButton for example, and specify the content type and the name of the file. Also specify a method in a backing bean that will be called to perform the download. In the backing bean method get the formated data to be saved from the model and use the supplied OutputStream to write the data.


Example:

In .jsf page:

<af:commandbutton id="buttonid"  " text="Download" ...
    <af:filedownloadactionlistener contenttype="application/octet-stream"
                method="#{backingBean.doDownload}"  filename="defaultFilename.txt"/>          
</af:commandButton>


In backing bean:

  public void doDownload(FacesContext facesContext, OutputStream outputStream) {
      // write the neccessary code to get the download data from the Model
      String data = getDownloadData();

      // save to the output stream
      try {
          OutputStreamWriter writer = new OutputStreamWriter(outputStream,"UTF-8");
           writer.write(data);
           writer.close();
          outputStream.close();
      } catch (IOException e) {
          // handle I/O exceptions
      }
  }


Context:

JSF Page
Backing Bean

Sunday, April 18, 2010

Bit #12 - Accessing the authenticated user's security roles from a backing bean

To access the authenticated user's security roles from a backing bean, first retrieve the SecurityContext from the current ADFContext instance and then call its getUserRoles() method. getUserRoles() returns a String array of all the roles defined for the user. To determine whether a specific role is assigned to the user, call the  SecurityContext  isUserInRole() method specifying the role as an argument. This method will return a boolean indicator of whether the role is assigned to the user or not.


Example:

    // in the context of a backing bean

    public String[] getUserRoles(){
        return ADFContext.getCurrent().getSecurityContext().getUserRoles();
    }

    public boolean isUserInRole(){
        return ADFContext.getCurrent().getSecurityContext().isUserInRole("RoleName");
    }


Context:

Backing Bean


Reference:

Oracle Fusion Middleware Java API Reference for Oracle ADF Share, getUserRoles

Saturday, April 17, 2010

Bit #11 - Accessing an object stored at the PageFlowScope from a backing bean

You can access the PageFlowScope from a backing bean, by getting the AdfFacesContext instance and calling its getPageFlowScope() method. This will return the Map of all objects stored in the PageFlowScope. To retrieve a specific object, call get() on the Map specifying the object identifier. Similarly, call the getViewScope() and getProcessScope() methods of the AdfFacesContext to retrieve the ViewScope and ProcessScope respectively.

Example:

        // in the context of a backing bean
        Object data = AdfFacesContext.getCurrentInstance().getPageFlowScope().get("objectID");


Context:

Backing Bean


Reference:

Oracle Fusion Middleware Java API Reference for Oracle ADF Faces, getPageFlowScope

Thursday, April 15, 2010

Bit #10 - Selectively enabling Partial Page Rendering programmatically

You can selectively enable Partial Page Rendering (PPR) programmatically from a backing bean, by calling the AdfFacesContext method addPartialTarget(). To do so, simply bind the target component to the backing bean, get the AdfFacesContext  and call its addPartialTarget() method passing the bound component as a parameter. This will in effect rerender the component. The advantage of calling addPartialTarget() is that it will rerender the component selectively for the specific events that you choose.

Example:

    // in the context of the backing bean

    // bind the component to the backing bean
    private RichPanelBox panel;

    public void setPanel(RichPanelBox panel) {
        this.panel = panel;
    }

    public RichPanelBox getPanel() {
        return panel;
    }

    // rerender the component
    private void rerenderComponent() {
        AdfFacesContext.getCurrentInstance().addPartialTarget(this.panel);
    }

Context:

Backing Bean

Reference:

Oracle Fusion Middleware Java API Reference for Oracle ADF Faces, addPartialTarget

Tuesday, April 6, 2010

Bit #5 - Accessing a resource bundle from a backing bean

You can access a resource bundle from a backing by calling the getResourceBundle() method on a javax.faces.application.Application object and specifying the bundle name. You get the Application object by calling getApplication() on the FacesContext. The getResourceBundle() returns a ResourceBundle object. To get some resource data from the bundle, call getString() on the ResourceBundle specifying the resource identifier. The example below illustrates the case.

Example:


        FacesContext fc = FacesContext.getCurrentInstance();
        ResourceBundle bundle = fc.getApplication().getResourceBundle(fc,"bundle_name");
        bundle.getString("resource_identifier");


Context:

Resource Bundle
Backing Bean


Wednesday, March 31, 2010

Bit #3 - Adding Javascript to a JSPX page

The recommended way to add scripting to your JSPX page is via the metaContainer <facet> tag. You add the metaContainer <facet> within the <af:document> tag. You can group your scripts within the metaContainer <facet> using an <af:group> tag. The actual script should be added within an <afh:script> or a <trh:script> tag. Adding Javascript to your JSPX page by directly placing a <script> tag is not recommended because it could have undesired side effects related to the proper resizing of the components in the page.

Example:

<f:facet name="metaContainer">
    <af:group>
        <afh:script source="/js/YourJsLibrary.js"/>
        <afh:script>
           function someFunction()
           {
                 …
           }
        </afh:script>
    </af:group>
</f:facet>

Context:

JSPX Page

Monday, March 29, 2010

Bit #1 - Adding Javascript to a template definition

The proper way to add scripting to a template definition is to add it in a <af:resource> tag of type javascript. This tag resides anywhere inside the template defition tag <af:pageTemplateDef>. Adding scripting to the template definition in any other way, for example by placing it inside a <script> tag, will produce undesired effects related to resizing of components within the template.

Example:

  <af:pageTemplateDef var="attrs" id="someId">
      <af:form id="formid">
          ...
      </af:form>
      <af:xmlContent>
         ...
      </af:xmlContent>
       <af:resource type="javascript">      
            function someFunction()
           {

               ...
           }   
     
</af:resource>

  </af:pageTemplateDef>

Context:

Template Definition JSPX

Reference:
Oracle® Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework 11g Release 1 (11.1.1) Part Number B31973-04 [Section 19.5 Adding Resources to Pages] 
 
Related Posts Plugin for WordPress, Blogger...