donderdag 3 maart 2011

How to convert input to uppercase

Technology: ADF11g
Developed in: JDeveloper 11.1.1.3.0
Browsers tested: Firefox 3.6.13 and Internet explorer 7 (7.0.6002.18005)
Used database schema: HR
Used tables: EMPLOYEES


Summary

In this blog four different solutions are provided to convert text to uppercase:
  • Convert to uppercase in the model layer
  • Convert to uppercase with java script
  • Convert to uppercase in a java bean
  • Convert to uppercase using a converter
The first and last two solutions only change the complete text to uppercase when the user leaves the input field. The second solution immediately changes each letter the user types to uppercase.

The third and fourth solution is created for the scenario that the input field is not bound to the model layer. But they can also be used if they are bound to the model.

Setup example application

For this blog the EMPLOYEES table of the HR schema is used. An input form containing a few input fields of this table is created.

Model layer

Create the following entities:

Entity name Based on table of HR schema Customizations made
Employee EMPLOYEES None


Create the following view objects:

View object name Based on entities Customizations made
EmployeesView Employee None


Create an application module HrAppModule which exposes the EmployeesView.


Form page

The form page is created by drag and drop from the Data Controls. The form is dropped as ADF Form only the FirstName, LastName, Email, PhoneNumber and JobId items are displayed (the text items).



Employee bean

In the form page we will make references to a java bean class. This bean class is defined in the unbound task flow:

Managed bean property Value
Name employeeBean
Class nl.hr.demo.view.beans.EmployeeBean
Scope Request

Solution 1: Convert to uppercase in the model layer

This solution will be applied to the first and last name attributes. To create a generic solution a new java class is created in a Common project. The Model and ViewController projects contain dependencies to this Common project.

The java class created is called HrEntityObjectImpl and it extends EntityImpl. The Employee entity object extends HrEntityObjectImpl.

HrEntityObjectImpl

The implementation of this class:

package nl.hr.demo.model.common;



import oracle.jbo.AttributeDef;

import oracle.jbo.server.EntityImpl;



public class HrEntityObjectImpl extends EntityImpl {

public HrEntityObjectImpl() {

super();

}



@Override

protected void setAttributeInternal(int i, Object object) {

AttributeDef attrDef = getEntityDef().getAttributeDef(i);

if (attrDef != null && attrDef.getJavaType().getName().equals("java.lang.String")) {

String caseProperty = getEntityDef().getAttributeDef(i).getProperty("CASE").toString();

if (caseProperty != null && !caseProperty.equals("")) {

String value = (String)object;

if (caseProperty.equals("UPPER")) {

value = value.toUpperCase();

} else if (caseProperty.equals("LOWER")) {

value = value.toLowerCase();

}

object = value;

}

}

super.setAttributeInternal(i, object);

}

}

The overridden method looks for each attribute if it contains a CASE property. If it contains this property and the value is UPPER then the value is set to uppercase, if it is LOWER than the value is set to lower case.

Employee entity

Let the Employee entity extend the created HrEntityObjectImpl class. This can be done in the Java tab, click edit and then Classes Extend:



For the FirstName and LastName attributes create a custom property CASE with value UPPER, this can be done in the Attribute tab, double click on the attribute and add a Custom Property:



Form page

In the form page adjust the FirstName and LastName attributes, set the autoSubmit and partialTrigger property. When the user leaves the field the attribute will be submit to the model layer and refreshed.

Set the autoSubmit property to true and the partialTrigger to its own id. Example of LastName:

<af:inputText value="#{bindings.LastName.inputValue}"

label="#{bindings.LastName.hints.label}"

required="#{bindings.LastName.hints.mandatory}"

columns="#{bindings.LastName.hints.displayWidth}"

maximumLength="#{bindings.LastName.hints.precision}"

shortDesc="#{bindings.LastName.hints.tooltip}"

id="it6"

autoSubmit="true"

partialTriggers="it6">

<f:validator binding="#{bindings.LastName.validator}"/>

</af:inputText>

The result when the user is typing:


And after leaving the field:


Solution 2: Convert to uppercase with java script

This solution will be applied to the email attribute. To create a generic solution a java script file is created instead of defining the java code in the page.

Because using the af:resource tag in a page template resulted in not finding the java script method the Trinidad tag is used instead to include the java script:

<trh:script source="../../common/javaScript/hrScript.js" id="hrScript"></trh:script>

Note: to include the Trinidad tag library open the project properties of the ViewController, go to the JSP Tag Library tab and includeTrinidad Components 1.2 (prefix tr) and Trinidad HTML Components 1.2 (prefix trh) in the jsp root of the page (template) add:

xmlns:trh=http://myfaces.apache.org/trinidad/html

The java script method will be executed for each keyboard button. Convert the input the uppercase is only necessary when the button is a letter. The java script method:

function isLetter(keyCode) {

if ( keyCode == "A" || keyCode == "B" || keyCode == "C" || keyCode == "D"

|| keyCode == "E" || keyCode == "F" || keyCode == "G" || keyCode == "H"

|| keyCode == "I" || keyCode == "J" || keyCode == "K" || keyCode == "L"

|| keyCode == "M" || keyCode == "N" || keyCode == "O" || keyCode == "P"

|| keyCode == "Q" || keyCode == "R" || keyCode == "S" || keyCode == "T"

|| keyCode == "U" || keyCode == "V" || keyCode == "W" || keyCode == "X"

|| keyCode == "Y" || keyCode == "Z") {

return true;

}

return false;

}



function convertCase(event) {

var keyChar = AdfKeyStroke.getKeyStroke(event.getKeyCode()).toMarshalledString();

if (isLetter(keyChar)) {

var field = event.getCurrentTarget();

var value = field.getSubmittedValue();

field.setValue(value.toUpperCase());

return true;

}

}

In the page we have to trigger this java script method. This is done by adding a clientListener to the email attribute that triggers the java script everytime the user releases a key:

<af:inputText value="#{bindings.Email.inputValue}"

label="#{bindings.Email.hints.label}"

required="#{bindings.Email.hints.mandatory}"

columns="#{bindings.Email.hints.displayWidth}"

maximumLength="#{bindings.Email.hints.precision}"

shortDesc="#{bindings.Email.hints.tooltip}"

id="it1">

<af:clientListener type="keyUp"

method="convertCase"/>

</af:inputText>

Now it’s impossible to make a screen shot of lower case letters:


Solution 3: Convert to uppercase in a java bean

For this solution the model is not used. In new inputText is added to the page instead:

<af:inputText value="#{employeeBean.transientField}"

autoSubmit="true"

partialTriggers="transientField"

label="Transient field"

id="transientField"/>

This item is bound to the employeeBean. A class variable transientField (String) is added and its accessors.

The result when the user is typing:


And after leaving the field:


Solution 4: Convert to uppercase using a converter

This solution will be applied to the job ID attribute.

A custom converter class is created which implements the Converter interface. This class converts given string to uppercase:

package nl.hr.demo.view.converters;



import javax.faces.component.UIComponent;

import javax.faces.context.FacesContext;

import javax.faces.convert.Converter;



public class UpperCaseConverter implements Converter {

public UpperCaseConverter() {

super();

}



public String getAsString(FacesContext fc, UIComponent uIComponent, Object object) {

return object.toString();

}

public Object getAsObject(FacesContext fc, UIComponent uIComponent, String string) {

return string.toUpperCase();

}

}

The converter is added to the faces-config.xml so it can be used in the pages:



In the form page adjust the JobId attribute, set the converter, autoSubmit and partialTrigger property. When the user leaves the field the attribute will be submit to the model layer and refreshed.

Set the converter to the created converter (id), autoSubmit property to true and the partialTrigger to its own id:

<af:inputText value="#{bindings.JobId.inputValue}"

label="#{bindings.JobId.hints.label}"

required="#{bindings.JobId.hints.mandatory}"

columns="#{bindings.JobId.hints.displayWidth}"

maximumLength="#{bindings.JobId.hints.precision}"

shortDesc="#{bindings.JobId.hints.tooltip}"

id="it2"

partialTriggers="it2"

autoSubmit="true"

converter="upperCaseConverter">


</af:inputText>

The result when the user is typing:


And after leaving the field:

2 opmerkingen: