JSF Internationalization JSF has full support for Java I18n - - PowerPoint PPT Presentation

jsf internationalization
SMART_READER_LITE
LIVE PREVIEW

JSF Internationalization JSF has full support for Java I18n - - PowerPoint PPT Presentation

JSF Internationalization JSF has full support for Java I18n Backing beans can load messages through standard ResourceBundle loading techniques faces-config entries allow for internationalization in the View JSF detects the


slide-1
SLIDE 1

JSF Internationalization

  • JSF has full support for Java I18n
  • Backing beans can load messages through standard

ResourceBundle loading techniques

  • faces-config entries allow for internationalization in the View
  • JSF detects the browser locale and loads the corresponding

resource bundle (if available)

<!-- JSF 1.2 allows for resource bundles to be declared in faces config

JSF Resource bundle declaration

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<!-- JSF 1.2 allows for resource bundles to be declared in faces config instead of <f:loadBundle />--> <resource-bundle> <base-name>Msgs</base-name> <var>msgs</var> </resource-bundle> <h:outputText styleClass="propertyLabel" value="#{msgs['component.title']}" />

JSF Resource bundle usage

slide-2
SLIDE 2

Localized Application Messages

  • JSF handles localized error and informational messages that
  • ccur as a result of conversion, validation, or other application

actions during the request processing lifecycle.

  • Default required=“true” message:

javax.faces.component.UIInput.REQUIRED = {0}: Validation Error: Value is required

  • The specification says: Replace the last parameter substitution

token with the input component’s label attribute. If the input

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

token with the input component’s label attribute. If the input component’s label attribute is not specified, use the component’s client identifier.

  • This will produce an undesirable message like this in the GUI:

j_id1:firstName: Validation Error: Value is required.

slide-3
SLIDE 3

Override Standard Application Messages

  • Create JSF-override_en.properties
  • Override message(s):

javax.faces.component.UIInput.REQUIRED=Value is required

  • Supply a <message-bundle> element in the application

configuration resources by adding the following entry to the <application> section of faces-config.xml:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<application> section of faces-config.xml:

<message-bundle>JSF-override</message-bundle>

slide-4
SLIDE 4

Exercise: Overview

  • The goal of this exercise is to implement

internationalization

  • We will do this by changing the value attributes of each of

the h:outputLabel components to a ValueBinding

  • Each ValueBinding will correspond to an entry in a resource

bundle

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

bundle

slide-5
SLIDE 5

Step 1: Create Resource Bundle

  • Create a file in the “src” folder named

Msgs_en.properties and paste the following into it: firstName=First Name lastName=Last Name travelPercentage=Travel Percentage

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

travelPercentage=Travel Percentage dateOfBirth=Date of Birth submitApplication=Submit Application

slide-6
SLIDE 6

Step 2: Create Value Bindings

  • In the faces-config.xml file, add the resource bundle to the

application node:

<!-- JSF 1.2 allows for resource bundles to be declared in faces config instead of <f:loadBundle />--> <resource-bundle> <base-name>Msgs</base-name>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<base-name>Msgs</base-name> <var>msgs</var> </resource-bundle>

slide-7
SLIDE 7

Step 2: Create Value Bindings

In the applicantForm.xhtml file, change the value attribute of each h:outputLabel:

<h:outputLabel for="firstName" value="#{msgs.firstName}" /> <h:outputLabel for=“lastName" value="#{msgs.lastName}" />

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

/> <h:outputLabel for=“travelPercentage" value="#{msgs.travelPercentage}" /> <h:outputLabel for=“dateOfBirth" value="#{msgs.dateOfBirth}" /> <h:commandButton action="#{applicantForm.submit}" value="#{msgs.submitApplication}" />

slide-8
SLIDE 8

Step 3: Override Standard JSF Messages

  • Sometimes it is desirable to change the default values of

standard JSF error messages

  • Create a file in the “src” folder named

JSF-override_en.properties and paste the following into it:

javax.faces.component.UIInput.REQUIRED=Value is required

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Open the faces-config.xml file in the IDE
  • Add the following entry to the <application> section:

<message-bundle>JSF-override</message-bundle>

  • JSF 1.2 message keys are listed in the JSF-
  • verride_en.properties in the exercise solutions folder.
slide-9
SLIDE 9

Step 4: Run Application

  • Re-publish/deploy the jobApplication project
  • Run the application in the browser and verify that the

labels look correct

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Change some of the label values in the Msgs_en.properties

file and verify that the changes show up in the browser

slide-10
SLIDE 10

JSF Value Change Listeners

  • JSF provides two ways to detect when values change inside
  • f components that implement EditableValueHolder:

– Add the valueChangeListener attribute to the component – Add the f:valueChangeListener component as a child of the component

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-11
SLIDE 11

Exercise: Overview

  • The goal of this exercise is to demonstrate usage of the

valueChangeListener attribute on an h:inputText component

  • We will add three new fields to the form:

– City – Province

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

– Province – Postal Code

  • When the user types a postal code, the

valueChangeListener will be called which will populate the City and Province fields

slide-12
SLIDE 12

Step 1: Add id attribute to form

  • Open the applicantForm.xhtml file in the IDE
  • Add the following attribute to the h:form tag:

id="applicantForm"

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-13
SLIDE 13

Step 2: Add City Markup

  • Paste the following table row in applicantForm.xhtml:

<tr> <td><h:outputLabel for="city" value="#{msgs.city}" /></td> <td><h:inputText id="city" required="true" value="#{applicant.city}" /></td> <td><h:message for="city" /></td> </tr>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-14
SLIDE 14

Step 3: Add Province Markup

  • Paste the following table row in applicantForm.xhtml:

<tr> <td><h:outputLabel for="province" value="#{msgs.province}" /></td> <td><h:inputText id="province" required="true" value="#{applicant.province}" /></td> <td><h:message for="province" /></td> </tr>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-15
SLIDE 15

Step 4: Add Postal Code Markup

  • Paste the following table row in applicantForm.xhtml:

<tr> <td><h:outputLabel for="postalCode" value="#{msgs.postalCode}" /></td> <td><h:inputText id="postalCode" immediate="true"

  • nchange="this.form.submit()" required="true"

value="#{applicant.postalCode}" valueChangeListener="#{applicantForm.postalCodeListener}" /></td> <td><h:message for="postalCode" /></td> </tr>

  • Note the onchange attribute:

– This will submit the form via JavaScript when the user enters a postal code

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

– This will submit the form via JavaScript when the user enters a postal code and tabs out of the field

  • Note the immediate attribute:

– This is the first step in bypassing Process Validations phase, since it causes ValueChangeListeners to fire earlier in the lifecycle – The second step is to call FacesContext.renderResponse() in the listener – Typical use case for the immediate attribute is a “cancel” button

  • Note the valueChangeListener attribute:

– Specifies an EL MethodBinding that listens to the ValueChangeEvent

slide-16
SLIDE 16

Step 5: Add New Fields

  • Open the Applicant.java file in the IDE
  • Add the following fields:

private String city; private String province; private String postalCode;

  • Generate getters and setters for these fields

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Generate getters and setters for these fields
slide-17
SLIDE 17

Step 6: Add ValueChangeListener

  • Paste the following in ApplicantForm.java:

public void postalCodeListener(ValueChangeEvent valueChangeEvent) { FacesContext facesContext = FacesContext.getCurrentInstance(); UIViewRoot uiViewRoot = facesContext.getViewRoot(); String newPostalCode = (String) valueChangeEvent.getNewValue(); if ("32801".equals(newPostalCode)) { UIInput cityInputText = (UIInput) uiViewRoot.findComponent("applicantForm:city"); String city = "Orlando"; cityInputText.setValue(city);

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

cityInputText.setValue(city); cityInputText.setSubmittedValue(city); UIInput provinceInputText = (UIInput) uiViewRoot.findComponent("applicantForm:province"); String province = "FL"; provinceInputText.setValue(province); provinceInputText.setSubmittedValue(province); facesContext.renderResponse(); } }

  • This is the listener code that will populate the City and

Province fields accordingly

slide-18
SLIDE 18

Step 7: Add Locale Messages

  • Paste the following table row in Msgs_en.properties:

city=City province=State postalCode=ZIP Code

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-19
SLIDE 19

Step 8: Run Application

  • Run the application in the browser
  • Click in the Postal Code field
  • Type 32801 and press the tab key
  • The City field should contain “Orlando”
  • The Province field should contain “FL”

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-20
SLIDE 20

Comments

  • Instead of having JavaScript submit the form and cause a

full browser refresh, Ajax techniques like ICEfaces partialSubmit can be used to greatly improve the end- user experience

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-21
SLIDE 21

JSF Action Listeners

  • JSF provides two ways to detect when the user interacts

with a component that implements UICommand, such as the h:commandButton and h:commandLink components:

– Add the actionListener attribute to the component – Add the f:actionListener component as a child of the component

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-22
SLIDE 22

Exercise: Overview

  • The goal of this exercise is to demonstrate usage of the

actionListener attribute on an h:commandLink component

  • We will add a new field named “resume” to the form, which

is an editable text area

  • We will also add “Show Resume” and “Hide Resume”

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • We will also add “Show Resume” and “Hide Resume”

comand links

  • When the user clicks on “Show Resume” the resume will be

displayed

  • When the user clicks on “Hide Resume” the resume will be

removed

slide-23
SLIDE 23

Step 1: Add Resume Field

  • Add the following field to Applicant.java:

private String resume;

  • Generate getters and setters for this new field

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-24
SLIDE 24

Step 2: Paste Show/Hide Controls

  • Paste the following markup in the applicantForm.xhtml file:

<table> <tr> <td> <h:commandLink actionListener="#{applicantForm.toggleResume}" immediate="true" rendered="#{!applicantForm.resumeRendered}" value="#{msgs.showResume}" /> <h:commandLink actionListener="#{applicantForm.toggleResume}" immediate="true" rendered="#{applicantForm.resumeRendered}" value="#{msgs.hideResume}" /> </td> </tr>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

</table>

  • Note the actionListener attribute
  • Note the immediate attribute
  • Note the rendered attribute – only one h:commandLink will be

displayed at any given time

slide-25
SLIDE 25

Step 3: Paste Resume Markup

  • Paste the following markup in the applicantForm.xhtml

file:

<h:panelGroup rendered="#{applicantForm.resumeRendered}"> <table> <tr> <td><h:outputLabel for="resume" value="#{msgs.resume}" /></td> </tr> <tr> <td><h:inputTextarea id="resume" cols="50" rows="10" value="#{applicant.resume}" /></td>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

/></td> </tr> </table> </h:panelGroup>

  • Note the rendered attribute on the h:panelGroup
slide-26
SLIDE 26

Step 4: Add Toggle Field

  • Add the following field to ApplicantForm.java:

private boolean resumeRendered = false;

  • Generate a getter and setter for this new field

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-27
SLIDE 27

Step 5: Add ActionListener

  • Add the following method to ApplicantForm.java:

public void toggleResume(ActionEvent actionEvent) { this.resumeRendered = !this.resumeRendered; }

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • This is the actionListener that gets called when the user

clicks on the show/hide links

  • The actionListener will simply toggle the renderability of the

h:panelGroup

slide-28
SLIDE 28

Step 6: Add Locale Messages

  • Paste the following table row in Msgs_en.properties:

resume=Resume: showResume=Show Resume hideResume=Hide Resume

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-29
SLIDE 29

Step 7: Run Application

  • Re-publish/deploy the

jobApplication project

  • Run the application in the

browser

  • Click on Show Resume
  • Click on Hide Resume

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Click on Hide Resume
  • Note that there is some

undesirable behavior – the Postal/ZIP Code gets a validation failure

slide-30
SLIDE 30

Immediate Attribute “Gotcha”

  • The reason why the Postal/ZIP code is getting a “Value is

required” validation failure (and the other fields don’t) is because it has immediate=“true”

  • The JSF API JavaDoc for the UIInput.processDecodes()

method states:

– “In addition to the standard processDecodes behavior inherited

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

– “In addition to the standard processDecodes behavior inherited from UIComponentBase, calls validate() if the immediate property is true”

  • So even though the PROCESS_VALIDATIONS phase is

getting skipped, any input fields with immedate=“true” will be validated anyway!

slide-31
SLIDE 31

Step 8: Implement Workaround

  • The workaround for this problem is to clear out all the

FacesMessages from the FacesContext for all input components in the tree that have immediate=“true”

  • Create the following Java class in the IDE:

– training.jobapplication.helper.FacesContextHelper

  • Find the FacesContextHelper.java file in the solution folder

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Find the FacesContextHelper.java file in the solution folder
  • Copy the contents of the solution file into the IDE
slide-32
SLIDE 32

Step 9: Use Workaround

  • Open the ApplicantForm.java file in the IDE
  • Replace the toggleResume() method with the following

code:

public void toggleResume(ActionEvent actionEvent) { this.resumeRendered = !this.resumeRendered; FacesContext facesContext =

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

FacesContext facesContext = FacesContext.getCurrentInstance(); FacesContextHelper.clearImmediateFacesMessages(faces Context); }

slide-33
SLIDE 33

Step 10: Run Application

  • Re-publish/deploy the

jobApplication project

  • Run the application in the

browser

  • Click on Show Resume
  • Click on Hide Resume

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Click on Hide Resume
  • Note that there the

validation failure is gone, and the application works as expected

slide-34
SLIDE 34

Selection Components

  • The JSF API provides several different types of selection components:

<h:selectOneListbox /> <h:selectOneMenu /> <h:selectOneRadio /> <h:selectBooleanCheckbox /> <h:selectManyCheckbox /> <h:selectManyListbox />

  • The JSF API provides several different types of selection components:

<h:selectOneListbox /> <h:selectOneMenu /> <h:selectOneRadio /> <h:selectBooleanCheckbox /> <h:selectManyCheckbox /> <h:selectManyListbox />

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<h:selectManyMenu />

  • The most frequently used component h:selectOneMenu, because it

renders itself as a drop down list

  • Screen shots of selection components can be found at

www.corejsf.com

<h:selectManyMenu />

  • The most frequently used component h:selectOneMenu, because it

renders itself as a drop down list

  • Screen shots of selection components can be found at www.corejsf.com
slide-35
SLIDE 35

Select Items

  • JSF components like h:selectOneMenu present lists of data, called select

items

  • Select items can be specified in two different ways:

<!-- List items bound to model bean via EL --> <h:selectOneMenu> <f:selectItems value="#{modelBean.selectItems}" /> </h:selectOneMenu>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<!– Hard coded list of items in the view --> <h:selectOneMenu> <f:selectItems> <f:selectItem itemLabel="Red" itemValue="red" /> <f:selectItem itemLabel="Green" itemValue="green" /> <f:selectItem itemLabel="Blue" itemValue="blue" /> </f:selectItems> </h:selectOneMenu>

slide-36
SLIDE 36

Model Bean Select Items

  • When selection components like h:selectOneMenu get

select items from a model bean, the list is typically the result of a database query

  • Rather than query the database directly, the best practice

is to introduce a service layer that provides the list as the result of a service call

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

result of a service call

slide-37
SLIDE 37

Exercise: Overview

  • The goal of this exercise is to convert the Province field

from h:inputText to h:selectOneMenu

  • The select items will be hard-coded in the

applicantForm.xhtml file for now

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-38
SLIDE 38

Step 1: Rename province to provinceId

  • Open Applicant.java in the IDE
  • Delete the provice property
  • Delete the getProvince() method
  • Delete the setProvince() method
  • Add the following property:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

private Long provinceId;

  • Generate getter and setter for this new property
slide-39
SLIDE 39

Step 2: Modify language bundle

  • Open Msgs_en.properties in the IDE
  • Delete the province key
  • Add the following lines:

provinceId=State select=-- Select --

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-40
SLIDE 40

Step 3: Delete input component

  • Open the applicantForm.xhtml file in the IDE
  • Delete the following markup:

<td> <h:inputText id="province" binding="#{applicantForm.province}" required="true" value="#{applicant.province}" /> </td>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

slide-41
SLIDE 41

Step 4: Insert selection component

  • Insert the following markup in place of the h:inputText that was just deleted:

<td> <h:selectOneMenu id="provinceId" required="true" value="#{applicant.provinceId}"> <f:selectItem itemLabel="#{msgs.select}" itemValue="" /> <f:selectItem itemLabel="DE" itemValue="1" /> <f:selectItem itemLabel="GA" itemValue="2" /> <f:selectItem itemLabel="FL" itemValue="3" /> <f:selectItem itemLabel="MD" itemValue="4" />

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<f:selectItem itemLabel="MD" itemValue="4" /> <f:selectItem itemLabel="NC" itemValue="5" /> <f:selectItem itemLabel="NJ" itemValue="6" /> <f:selectItem itemLabel="NY" itemValue="7" /> <f:selectItem itemLabel="SC" itemValue="8" /> <f:selectItem itemLabel="VA" itemValue="9" /> </h:selectOneMenu> </td>

slide-42
SLIDE 42

Step 5: Fix Label and Message

  • Locate the h:outputLabel before the provinceId field the

and h:message component after the province field

  • Change the value of the for attribute of each one from

province to provinceId

  • Change the value of the value attribute from

#{msgs.province} to #{msgs.provinceId}

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

#{msgs.province} to #{msgs.provinceId}

slide-43
SLIDE 43

Step 6: Modify Backing Bean Processing

  • Replace the following code in the postalCodeListener()

method:

UIInput provinceInputText = (UIInput) uiViewRoot.findComponent("applicantForm:province"); String province = "FL"; provinceInputText.setValue(province); provinceInputText.setSubmittedValue(province);

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • With this code:

UIInput provinceInputText = (UIInput) uiViewRoot.findComponent("applicantForm:provinceId"); Long provinceId = 3L; provinceInputText.setValue(provinceId); provinceInputText.setSubmittedValue(Long.toString(provinceId));

slide-44
SLIDE 44

Step 7: Run Application

  • Re-publish/deploy the

jobApplication project

  • Run the application in the

browser

  • Click in the Postal Code

field

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

field

  • Type 32801 and press

the tab key

  • Note that FL is selected

in the drop down list

slide-45
SLIDE 45

Exercise: Overview

  • The goal of this exercise is to introduce a support

managed-bean to the jobApplication project

  • The support bean will exist to provide select items to the

provinceId h:selectOneMenu instead of hard-coding the select items in the applicantForm.xhtml file

  • The select items will be a ValueBinding to a list returned by

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • The select items will be a ValueBinding to a list returned by

the support bean

slide-46
SLIDE 46

Step 1: Create Province Transfer Object

  • Using the IDE, create the following Transfer Object class:

– training.jobapplication.transfer.Province

  • Add the following properties:

private long provinceId; private String provinceName;

  • Generate getters and setters for these new fields
  • Add the following constructor:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

  • Add the following constructor:

public Province(long provinceId, String provinceName) { this.provinceId = provinceId; this.provinceName = provinceName; }

slide-47
SLIDE 47

Step 2: Use ValueBinding for Select Items

  • Open the applicantForm.xhtml file in the IDE
  • Replace the hard-coded province select items with the

following ValueBinding:

<f:selectItems value="#{provinceSupport.selectItems}" />

  • The result should look like the following:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<h:selectOneMenu id="provinceId" required="true" value="#{applicant.provinceId}"> <f:selectItem itemLabel="#{msgs.select}" itemValue="" /> <f:selectItems value="#{provinceSupport.selectItems}" /> </h:selectOneMenu>

slide-48
SLIDE 48

Step 3: Create & Register Support Bean

  • Using the IDE, create the following Support Bean class:

– training.jobapplication.bean.support.ProvinceSupport

  • Paste the following markup into faces-config.xml in order

to register the new bean with the JSF managed bean facility:

<managed-bean>

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<managed-bean> <managed-bean-name>provinceSupport</managed-bean-name> <managed-bean- class>training.jobapplication.bean.support.ProvinceSupport</manag ed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

slide-49
SLIDE 49

Step 4: Add Simulated Query Results

  • Add the following method to ProvinceSupport.java,

which simulates getting the results from a database query:

public List<Province> getProvinces() { long provinceId = 1; ArrayList<Province> provinces = new ArrayList<Province>(); Province province = new Province(provinceId++, "DE"); provinces.add(province); province = new Province(provinceId++, "GA"); provinces.add(province); province = new Province(provinceId++, "FL"); provinces.add(province);

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

provinces.add(province); province = new Province(provinceId++, "MD"); provinces.add(province); province = new Province(provinceId++, "NC"); provinces.add(province); province = new Province(provinceId++, "NJ"); provinces.add(province); province = new Province(provinceId++, "NY"); provinces.add(province); province = new Province(provinceId++, "SC"); provinces.add(province); province = new Province(provinceId++, "VA"); provinces.add(province); return provinces; }

slide-50
SLIDE 50

Step 5: Add Primary Key Lookup

  • Add the following method, which will simulate a lookup of the primary key:

public long getProvinceId(String provinceName) { long provinceId = 0; List<Province> provinces = getProvinces(); for (Province province: provinces) {

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

if (province.getProvinceName().equals(provinceName)) { provinceId = province.getProvinceId(); break; } } return provinceId; }

slide-51
SLIDE 51

Step 6: Add Selection Item Results

  • Add the following method, which returns a list of select items that will

be used by a value binding:

public List<SelectItem> getSelectItems() { List<SelectItem> selectItems; selectItems = new ArrayList<SelectItem>(); List<Province> provinces = getProvinces(); for (Province province : provinces) {

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

for (Province province : provinces) { SelectItem selectItem = new SelectItem(province.getProvinceId(), province.getProvinceName()); selectItems.add(selectItem); } return selectItems; }

slide-52
SLIDE 52

Step 7: Perform Lookup of State of Florida

  • Open ApplicantForm.java
  • Add the following property:

private ProvinceSupport provinceSupport;

  • Generate getters and setters for this property (for injection via JSF

managed bean facility)

  • In the postalCodeListener() method, replace this line:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

Long provinceId = 3L;

  • With this one:

Long provinceId = getProvinceSupport().getProvinceId("FL");

slide-53
SLIDE 53

Step 8: Inject Support Bean into Backing Bean

  • Since the applicantForm backing bean needs to get access to the

provinceSupport bean, we need to inject it via the JSF managed-bean facility

  • Open the faces-config.xml file in the IDE
  • Paste the following managed-property markup into the definition of

the applicantForm managed-bean, after the applicant managed- property:

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

<!-- Inject the provinceSupport bean into the --> <!-- backing bean in order to promote loose coupling --> <managed-property> <property-name>provinceSupport</property-name> <value>#{provinceSupport}</value> </managed-property>

slide-54
SLIDE 54

Step 9: Run Application

  • Re-publish/deploy the

jobApplication project

  • Run the application in the

browser

  • Click in the Postal Code

field

ICESOFT TECHNOLOGIES INC.

www.icefaces.org

field

  • Type 32801 and press

the tab key

  • Note that FL is selected

in the drop down list