Thursday, October 10, 2013

CSS - Search Box with Inline Symbol

In this post, let's try to display a simple search box with magnifying glass symbol.

First, create a CSS file with following entry.(also add search.png to img directory under public_html dir)

.filterField af|inputText::content
{
  background-image: url("../../img/search.png");
  background-position: right center;
  background-repeat: no-repeat;
}

Next add af:inputText component to page and refer the CSS class in styleClass property

                            <af:inputText id="it1"
                                          label="Search" styleClass="filterField"/>

If you run the page, the search box will be displayed as shown


You can implement similar pattern by adding necessary styles in contentStyle property. But creating a class in CSS will help you to reuse the style across application.

                            <af:inputText id="it1"
                                          contentStyle='background-image: url("../img/search.png");background-position: right center;background-repeat: no-repeat;'
                                          label="Search"/>

Wednesday, October 9, 2013

JQuery Usage in ADF - Simple Example

I just tried to use JQuery in ADF with simple DatePicker example. Refer following steps to show datepicker using JQuery.

  • Import required JQuery & CSS scripts into page using af:resource tag (In this example, I referred scripts from Google CDN & JQuery CDN):

            <af:resource type="javascript" source="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"/>
            <af:resource type="javascript"
                         source="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"/>
            <af:resource type="css" source="http://code.jquery.com/ui/1.10.3/themes/start/jquery-ui.css"/>

  • Add Java Script function to show datepicker: (Additional properties enabled for datepicker to change month, year etc)

            <af:resource type="javascript">
              function pickdate() {
                  $("input[name=it1]").datepicker({
                  showButtonPanel: true,
                  dateFormat: "DD, d MM, yy",
                  changeMonth: true,
                  changeYear: true
                  });
              }
            </af:resource>

  • Add af:inputText component with af:clientListener to trigger Java Script:

            <af:form id="f1">
                <af:panelStretchLayout id="psl1" styleClass="AFStretchWidth" dimensionsFrom="children">
                    <f:facet name="center">
                        <af:panelGroupLayout id="pgl1" halign="center" layout="horizontal">
                            <af:panelBox text="Test JQuery" id="pb1" showDisclosure="false" type="flow">
                                <f:facet name="toolbar"/>
                                <af:inputText label="Select Date" id="it1">
                                    <af:clientListener method="pickdate" type="mouseOver"/>
                                </af:inputText>
                            </af:panelBox>
                        </af:panelGroupLayout>
                    </f:facet>
                </af:panelStretchLayout>
            </af:form>

  • Run your page and click on Input text field to show Date Picker.


Character Count & Maximum Length Validation using JavaScript

In this post, let us discuss about displaying Character count and an alert when character count matches with maximum no of allowed characters.

First, add af:inputtext component to page surrounded with af:panelbox component.
Inside af:inputtext component, add af:clientListener & af:clientAttribute to trigger java script with required attributes. Add af:outputText component inside toolbar facet of af:panelbox to display Character count.

            <af:panelBox text="Character Count" id="pb1" clientComponent="true" showDisclosure="false"
                             partialTriggers="it1">
                    <f:facet name="toolbar">
                        <af:outputText id="CharCount" clientComponent="true" value=""
                                       inlineStyle="font-weight:normal;"/>
                    </f:facet>
                    <af:inputText label="Enter Name" id="it1" maximumLength="8" clientComponent="true" required="true"
                                  rows="1" columns="10">
                        <af:clientListener method="charCount" type="keyUp"/>
                        <af:clientAttribute name="Warning" value="You have reached maximum no of characters!!!"/>
                    </af:inputText>
                </af:panelBox>

Next add java script as shown below to count no of characters and display an alert when it reached to maximum no of characters.

            <af:resource type="javascript">
              function charCount(evt) {
                  var sourceId = evt.getSource().getClientId();
                  var source = evt.getSource();
                  var textfield = evt.getCurrentTarget();
                  var textfield_current_content = textfield.getSubmittedValue();
                  var textfield_current_content_length = textfield_current_content.length;
                  var maxLength = textfield.getMaximumLength();
                  var lengthdiff = maxLength - textfield_current_content_length - 1;
                  if (lengthdiff &gt;= 0) {
                     if(sourceId.indexOf("it1") != -1) {                  
                      var counter = source.findComponent("CharCount");
                     }
                   counter_value = counter.getValue();
                   counter.setValue(textfield_current_content_length + " characters (out of " + maxLength + ")");
                      showAlert = true;
                  }
                  else {
                     if(sourceId.indexOf("it1") != -1) {
                        var counter = source.findComponent("CharCount");
                        counter.setValue(textfield_current_content_length + " characters (out of " + maxLength + ")");
                        var warning = evt.getSource().getProperty('Warning');
                       }
                     if (showAlert == true) {
                        alert(warning);
                        showAlert = false;
                       }
                  }
              }
            </af:resource>

Now run the page and test the logic. An alert will be displayed when Character count in Input text field reaches to Maximum length.


Notes: 

  • Given java script contains some additional logic(if condition), which is not required when you have only one af:inputtext field. You can reuse same java script by adding additional if condtions based on af:inputtext ID, when you need same logic for few more af:inputtext fields.
  • af:clientAttribute -- If you want to display alert message from property bundle(i18n), just replace hard coded value with reference to key value in property bundle.
          <af:clientAttribute name="Warning" value="#{viewcontrollerBundle.WARNING_EN}"/>

Tuesday, October 8, 2013

Prevent User Input while Server Side Activity In Progress

Sometimes, we may need to block the user input in ADF application while server side activity is still active. Following post will help you to achieve this.

Case1:
  • First of all add a Popup (af:popup) ADF Faces component to the page with an embedded Dialog (af:dialog) component in it as shown below.
        <af:popup id="busyPopup" clientComponent="true" contentDelivery="immediate" childCreation="deferred">
            <af:dialog id="busyDialog" type="none" closeIconVisible="false" title="Loading, please wait..." contentWidth="250">
                <af:image source="/progress_bar.gif" shortDesc="Loading..." id="i2"/>
            </af:dialog>        
        </af:popup>   

            progress_bar.gif:
  • Next, add following java script to the page with af:resource tag of type 'javascript'.
        <af:resource type="javascript">
          function showBusyPopup(evt) {
              var popup = AdfPage.PAGE.findComponentByAbsoluteId('busyPopup');
              if (popup != null) {
                  AdfPage.PAGE.addBusyStateListener(popup, busyStateListener);
                  evt.preventUserInput();
              }
          }
          function busyStateListener(evt) {
              var popup = AdfPage.PAGE.findComponentByAbsoluteId('busyPopup');
              if (popup != null) {
                  if (evt.isBusy()) {
                      popup.show();
                  }
                  else if (popup.isPopupVisible()) {
                      popup.hide();
                      AdfPage.PAGE.removeBusyStateListener(popup, busyStateListener);
                  }
              }
          }
        </af:resource>

  • Next, add af:clientlistener component of type 'action' for af component in page and refer showBusyPopup as method to be triggered.
            <af:commandButton text="Show PopUp" id="cb1" partialSubmit="true">
               <af:clientListener method="showBusyPopup" type="action"/>                 
            </af:commandButton>

If we run the application with these changes, the popup will be displayed when you click on Button displayed on page. And the popup will get disappeared automatically when server side task get finished.

Popup:

I recommend to perform above mentioned steps 1 & 2 in template page, so that you can reuse same functionality across application.

Case2:

Now let us say, we want to prevent user input for each server side activity. To achieve this, remove af:clientlistener at component level and add it at page level with type 'load'.

<af:clientListener method="showBusyPopup" type="load"/>

I faced an issue when I tried to handle each server side activity i.e. case2. Its not working properly with pages having LOV's.

Case3:

If you want to just prevent the user input till event get completed, try following simple java script. No pop up will be displayed as in Case 1 & 2.

<af:resource type="javascript">
 function showBusyPopup(evt){
    evt.preventUserInput(); 
  }
 </af:resource>

Wednesday, October 2, 2013

Java Embedding Activity in BPEL 1.1 and BPEL 2.0

In this post, let us take a look at Java Embedding Activity usage in BPEL 1.1 and BPEL 2.0.

The Java Embedding Activity syntax in BPEL 2.0 is slightly different when compared to BPEL 1.1. The bpelx:exec extension and Java code are wrapped in an <extensionActivity> element.

Similarly the Custom Java classes import syntax also varies between both the versions.

BPEL 1.1:
   <bpelx:exec import="oracle.xml.parser.v2.XMLElement"/>
   <bpelx:exec name="Logging" version="1.5" language="java">
        <![CDATA[    
        try{        
           XMLElement input= (XMLElement)getVariableData("inputVariable", "payload","/client:process/client:input");              
           addAuditTrailEntry("Input Value is: " + input.getTextContent());    
           }      
           catch(Exception e)          
           {          
           e.printStackTrace();          
           }]]>
    </bpelx:exec>

BPEL 2.0:
    <import location="oracle.xml.parser.v2.XMLElement" importType="http://schemas.oracle.com/bpel/extension/java"/>
    <extensionActivity>
      <bpelx:exec name="Logging" language="java">
        <![CDATA[    
        try{        
           XMLElement input= (XMLElement)getVariableData("inputVariable", "payload","/client:process/client:input");              
           addAuditTrailEntry("Input Value is: " + input.getTextContent());    
           }      
           catch(Exception e)          
           {          
           e.printStackTrace();          
           }]]>
      </bpelx:exec>
    </extensionActivity>