ADF Code Corner Implementing auto suggest functionality in ADF Faces. Abstract:

Similar documents
ADF Code Corner How-to show a glasspane and splash screen for long running queries. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 016-How-to customize the ADF Faces Table Filter. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 71. How-to integrate Java Applets with Oracle ADF Faces. Abstract: twitter.com/adfcodecorner

ADF Code Corner. Oracle JDeveloper OTN Harvest 01 / Abstract: twitter.com/adfcodecorner

ADF Mobile Code Corner

ADF Code Corner How-to use the af:autosuggestbehavior component tag with ADF bound data sources. Abstract: twitter.

ADF Code Corner How-to enforce LOV Query Filtering. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 70. How-to build dependent list boxes with Web Services Business Services. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to bind custom declarative components to ADF. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to launch a popup upon rendering of a page fragment in a region using JSF 2. Abstract: twitter.

ADF Code Corner How-to declaratively build a master-detail behavior with DVT components. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to further filter detail queries based on a condition in the parent view using ADF BC. Abstract: twitter.

ADF Code Corner. 90. Filtering ADF bound lists. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 97. How-to defer train-stop navigation for custom form validation or other developer interaction. Abstract: twitter.

ADF Code Corner. Oracle JDeveloper OTN Harvest 02 / Abstract: twitter.com/adfcodecorner

ADF Code Corner How to cancel an edit form, undoing changes with ADFm savepoints

ADF Mobile Code Corner

ADF Code Corner. 65. Active Data Service Sample Twitter Client. Abstract: twitter.com/adfcodecorner

ADF Mobile Code Corner

ADF Mobile Code Corner

ADF Code Corner How-to restrict the list of values retrieved by a model driven LOV. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 64. How-to implement a Select Many Shuttle with pre- selected values. Abstract: twitter.com/adfcodecorner

ADF Code Corner. 048-How-to build XML Menu Model based site menus and how to protect them with ADF Security and JAAS. Abstract:

1 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

ADF Code Corner How-to build a reusable toolbar with Oracle ADF Declarative Components. Abstract: twitter.com/adfcodecorner

ADF Code Corner How-to use Captcha with ADF Faces and Oracle ADF. Abstract: twitter.com/adfcodecorner

ADF Code Corner. Oracle JDeveloper OTN Harvest 12 / Abstract: twitter.com/adfcodecorner

Using JavaScript in ADF Faces Rich Client Applications

Functional. Pattern Embeding Regions inside PopUp Windows

Oracle Fusion Middleware 11g: Build Applications with ADF I

ADF Region Interaction: External Train Navigation

ADF Code Corner. Oracle JDeveloper OTN Harvest 09 / Abstract: twitter.com/adfcodecorner

ADF Hands-On. Understanding Task Flow Activities / 2011 ADF Internal Enterprise 2.0 Training. Abstract:

<Insert Picture Here> Advanced ADF Faces. Frank Nimphius Principal Product Manager

Oracle Fusion Middleware 11g: Build Applications with ADF Accel

Oracle Fusion Middleware 11g: Build Applications with ADF I

Oracle Developer Day

1 Copyright 2011, Oracle and/or its affiliates. All rights reserved.

Rich Web UI made simple Building Data Dashboards without Code

Overview. Principal Product Manager Oracle JDeveloper & Oracle ADF

ADF Code Corner. Oracle JDeveloper OTN Harvest 10 / Abstract: twitter.com/adfcodecorner

A demo Wakanda solution (containing a project) is provided with each chapter. To run a demo:

ADF OAF Who Cares? You Do! Oracle Applications Framework / Application Development Framework - Which way do I go?

Oracle Middleware 12c: Build Rich Client Applications with ADF Ed 1 LVC

Lab 20: UI Customization

If you wish to make an improved product, you must already be engaged in making an inferior one.

How-to Build Card Layout Responses from Custom Components

SSJS Server-Side JavaScript WAF Wakanda Ajax Framework

Achieving the Perfect Layout with ADF Faces RC

DESIGN AND IMPLEMENTATION OF SAGE DISPLAY CONTROLLER PROJECT

Practic Pr al actic Dynamic Actions Intro Jorge Rimblas 1. 1

Take Your Oracle Forms on the Road Using ADF Mobile. Mia Urman, OraPlayer & Denis Tyrell, Oracle Corporation

Manipulating Database Objects

Oracle Application Development Framework Overview

Java EE 6: Develop Web Applications with JSF

... AND UIX BEGAT ADF FACES: HOW RICH IS ADF FACES RICH CLIENT? Peter Koletzke, Quovera

ADF Mobile : Data Services Java Beans. Ma Ping

CISC 1600 Lecture 2.4 Introduction to JavaScript

Jquery Manually Set Checkbox Checked Or Not

Application Deployment System Guide Version 8.0 October 14, 2013

Developing Cross Device Mobile Applications

Developing Applications with Java EE 6 on WebLogic Server 12c

Introduction to JavaScript p. 1 JavaScript Myths p. 2 Versions of JavaScript p. 2 Client-Side JavaScript p. 3 JavaScript in Other Contexts p.

Building Rich Enterprise JSF Applications with Oracle JHeadstart for ADF (11.1.1)

Mastering Oracle ADF Task Flows. Frank Nimphius Principal Product Manager Oracle JDeveloper / ADF

MyEclipse ER-Designer Quickstart

ORACLE JHEADSTART 12C for ADF

A Closer Look at XPages in IBM Lotus Domino Designer 8.5 Ray Chan Advisory I/T Specialist Lotus, IBM Software Group

<Insert Picture Here> Oracle Policy Automation Connector For Siebel Features and Benefits

<Insert Picture Here> Accelerated Java EE Development: The Oracle Way

BEAWebLogic. Portal. Overview

"Web Age Speaks!" Webinar Series

SAGE Computing Services. Trials & Tribulations of an Oracle Forms -> Apex Conversion

THE NEW ERA OF WEB DEVELOPMENT. qooxdoo. Andreas Ecker, Derrell Lipman

Oracle Digital Assistant: Strategies for Escaping the Validation Loop

edev Technologies integreat4tfs 2015 Update 2 Release Notes

The main differences with other open source reporting solutions such as JasperReports or mondrian are:

Oracle Fusion Middleware

MarkLogic Server. Query Console User Guide. MarkLogic 9 May, Copyright 2017 MarkLogic Corporation. All rights reserved.

IBM. IBM WebSphere Application Server Migration Toolkit. WebSphere Application Server. Version 9.0 Release

Manual Trigger Sql Server 2008 Examples Insert Update

Lab 7 Macros, Modules, Data Access Pages and Internet Summary Macros: How to Create and Run Modules vs. Macros 1. Jumping to Internet

MAKING THE BUSINESS CASE MOVING ORACLE FORMS TO THE WEB

An Oracle White Paper September Oracle Fusion Middleware MapViewer

Happy Birthday, Ajax4jsf! A Progress Report

End User s Guide Release 5.0

PHP / MYSQL DURATION: 2 MONTHS

Oracle Developer Day

ENRICHING PRIMO RECORDS WITH INFORMATION FROM WORDPRESS. Karsten Kryger Hansen Aalborg University Library

AJAX in Apache MyFaces A New Approach To Web Applications

Seam Tools Tutorial. Version: Final-SNAPSHOT

User Guide Using AuraPlayer

Oracle Retail Accelerators for WebLogic Server 11g

We didn t need dialogue. We had faces.

Database Developers Forum APEX

Embarcadero DB Optimizer 1.5 Evaluation Guide. Published: March 16, 2009

Customizing Oracle Identity Governance: Populating Request Attributes

Tivoli Common Reporting V Cognos report in a Tivoli Integrated Portal dashboard

Client Configuration Cookbook

JSF Tools Reference Guide. Version: M5

Transcription:

ADF Code Corner 004. Implementing auto suggest functionality in ADF Faces Abstract: No component represents Ajax and the Web 2.0 idea more than the auto suggest component. Auto suggest, or auto complete as it is referred to as well, shows a list of values in a drop down list that is filtered by the user input in a text text field. But its not the auto suggest component itself that represents the new web, its the behavior that demonstrates partial page updates the best. This articles explains an approach to implement auto suggest in ADF Faces Rich Client of Oracle JDeveloper 11g. twitter.com/adfcodecorner Note: Meanwhile ADF Faces has a suggest component that replaces what is explained in this paper (see sample #62 on ADF Code Corner. The content is no longer needed but is published for developers who like to read source code especially JavaScript samples for ADF Faces Author: Frank Nimphius, Oracle Corporation twitter.com/fnimphiu DD-MON-2010

Oracle ADF Code Corner is a loose blog-style series of how-to documents that provide solutions to real world coding problems. Disclaimer: All samples are provided as is with no guarantee for future upgrades or error correction. No support can be given through Oracle customer support. Please post questions or report problems related to the samples in this series on the OTN forum for Oracle JDeveloper: http://forums.oracle.com/forums/forum.jspa?forumid=83 Introduction A native auto suggest component for ADF Faces Rich Client is on the list of new features planned for a future release of Oracle JDeveloper. However, as mentioned before, its less the component than the functionality that is of interest and the functionality is what can be build with ADF Faces Rich client on-board means today. This articles explains the architecture and the JDeveloper 11g workspace of a first prototype that we plan to enhance to a declarative component to a later point in time. We decided to release our prototype with this article to make the suggest functionality available to ADF Faces customers in a guide for manual implementation. 2

Architecture The auto suggest functionality requires a client side and a server side implementation that communicate with each other using an asynchronous communication channel. On the server side we use logic to provide the list of values and to filter the list with each keystroke of the user. The list of values is chosen to display strings as labels and values. On the client side, of course, JavaScript is used to listen for the user keyboard input, to display the suggest list and to send the user entered characters as a payload to the server to filter the data. A Poor Man's Process Chart In this version of auto suggest, an af:inputtextfield is used as the data input component. As soon as the user starts typing into the field, a JavaScript event is captured by the af:clientlistener component, which passes the event on to a JavaScript function to handle the request. The JavaScript function looks at the incoming key code and if it is a valid character, opens the popup dialog below the text field if it is not open. The list box queries the list data from a managed bean that we added as an abstraction layer between the view and the model to allow list data to be read from ADF, POJO and similar. The truth also is that we need this abstraction layer to keep the suggest functionality generic, because we want the developer to decide about the caching strategy for fetched data. In the sample we use ADF Business Components to query the data and here we have the option to tell it to perform follow up queries from memory instead of a database query. When the list data is refreshed, the list component is added as a 3

partial target to refresh at the end of the request. The input focus is put back to the input text field for the user to give us the next character. ADF Business Components The suggest list is retrieved from a client method that is exposed on the ADF Business Components Application Module. The method takes a string as an input argument to query the Jobs View Object and returns a List of strings back to the client. Managed Bean Two managed beans are used in this prototype: SuggestList and DemoAdfBcSuggestModel. The DemoAdfBcSuggestModel abstracts the ADF Business Components query and returns the list of strings to the SuggestList bean to provide the result to the client. If you plan to customize this sample to your needs, then you need to replace the DemoAdfBcSuggestModel bean with your implementation. The SuggestList provides two key methods: public ArrayList<SelectItem> getjoblist() This method populates the suggest list. It is referenced from the f:selectitems element, which is a child element of the af:selectonelistbox element that resides in an af:popup component to suggest the values to the user. public ArrayList<SelectItem> getjoblist() { //first time query is against database if (joblist == null){ joblist = new ArrayList<SelectItem>(); List<String> filteredlist = null; filteredlist = suggestprovider.filteredvalues(srchstring, false); joblist = populatelist(filteredlist); return joblist; private ArrayList<SelectItem> populatelist(list<string> filteredlist) { ArrayList<SelectItem> _list = new ArrayList<SelectItem>(); for(string suggeststring : filteredlist){ SelectItem si = new SelectItem(); si.setvalue(suggeststring); si.setlabel(suggeststring); _list.add(si); return _list; public void dofilterlist On every user keystroke in the suggest input field, the browser client calls the dofilterlist method through the af:serverlistener component. public void dofilterlist(clientevent clientevent) { // set the content for the suggest list srchstring = (String)clientEvent.getParameters().get("filterString"); 4

List<String> filteredlist = suggestprovider.filteredvalues(srchstring, true); joblist = populatelist(filteredlist); RequestContext.getCurrentInstance().addPartialTarget(suggestList); The af:selectonelistbox is refreshed at the end of each call to the dofilterlist method so the new list value is populated JSF page markup The suggest field has two af:clientlistener components assigned that listen for the keyup and keydown event. All keyboard events on the suggest field are send to the handlekeyuponsuggestfield JavaScript function, which takes the event object as an input argument. The event object provides information about the event source, the component receiving the key stroke, and the keycode pressed. Using the ADF Faces RC client JavaScript APIs, we don't need to deal with browser differences, which is big relief. <!-- START Suggest Field --> <af:inputtext id="suggestfield" clientcomponent="true" 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"> <f:validator binding="#{bindings.jobid.validator"/> <af:clientlistener method="handlekeyuponsuggestfield" type="keyup"/> <af:clientlistener method="handlekeydownonsuggestfield" type="keydown"/> </af:inputtext> <!-- END Suggest Field --> The suggest list is defined as follows <!-- START Suggest Popup --> <af:popup id="suggestpopup" contentdelivery="immediate" animate="false" clientcomponent="true"> <af:selectonelistbox id="joblist" contentstyle="width: 250px;" size="15" valuepassthru="true" binding="#{suggestlistbean.suggestlist"> <f:selectitems value="#{suggestlistbean.joblist"/> <af:clientlistener method="handlelistselection" type="keyup"/> <af:clientlistener method="handlelistselection" type="click"/> </af:selectonelistbox> <af:serverlistener type="suggestserverlistener" method="#{suggestlistbean.dofilterlist"/> </af:popup> <!-- END Suggest Popup --> The af:selectonelistbox has two af:clientlistener defined that listen for the keyup and click event for the user to select a value (Enter key, click) or to cancel the action (Esc). The af:serverlistener is called from the JavaScript that is executed when the user enters a new character into the suggest input field. The af:serverlistener calls the dofilterlist method in the SuggestList bean. 5

JavaScript JavaScript has become popular with Ajax and also is an option to use with ADF Faces Rich Client. Unlike previous versions of ADF Faces, ADF Faces Rich Client has a real client side framework that by large is used internally, but also exposes public functions to prevent users from hacking the DOM tree. Disclaimer Before we get into JavaScript programming, we should mention that using JavaScript in ADF Faces is the second best solution. The best solution always is to use the JavaServer Faces programming APIs because this is what we have good chances to see migrated from one release to the other, which also includes new browser versions that today we don't know are coming. However, some use cases, like the suggest functionality, require JavaScript to put the logic where it is needed and to save network roundtrips where possible. In this version of Oracle JDeveloper 11g, JavaScript is added to the metacontainer facet of the af:document element. As soon as we see JDeveloper 11g R1 being productive, this part of the code may be changed to the new af:resource element. <f:facet name="metacontainer"> <af:group> <![CDATA[ <script> //****************************************************************** //PROTOTYPE: AUTO SUGGEST //STATUS: 1.0 //authors: Frank Nimphius, Maroun Imad //Functionality //==================================== // Implemented in v 1.0 //1 - Suggest window opens JOB_ID field //2 - Initial query is to database, follow up queries are in memory //3 - Enter list with down arrow //4 - Enter key and mouse click to select //5 - ESC to close //****************************************************************** function handlekeyuponsuggestfield(evt){ // start the popup aligned to the component that launched it suggestpopup = evt.getsource().findcomponent("suggestpopup"); inputfield = evt.getsource(); //don't open when user "tabs" into field if (suggestpopup.isshowing() == false && evt.getkeycode()!= AdfKeyStroke.TAB_KEY){ //We reference a DOM area by using getclientid()+"::content" //to position the suggest list. Shame //on use that we are doing this, but there is no other option 6

//we found. Keep in mind that using direct DOM references may //break the code in the future if the rendering of the //component changes for whatever reason. For now, we want to //feel safe and continue using it hints = {align:adfrichpopup.align_after_start, alignid:evt.getsource().getclientid()+"::content"; suggestpopup.show(hints); //disable popup hide to avoid popup to flicker on key press. //Note that we override the default framework behavior of the //popup component for this instance only. When hiding the popup, //we re-implement the default functionality. By all means, never //change the framework functionality on the prototype level as //this could have an unpredictable impact on all nstances of //this type suggestpopup.hide = function(){ //suppress server access for the following keys //for better performance if (evt.getkeycode() == AdfKeyStroke.ARROWLEFT_KEY evt.getkeycode() == AdfKeyStroke.ARROWRIGHT_KEY evt.getkeycode() == AdfKeyStroke.ARROWDOWN_KEY evt.getkeycode() == AdfKeyStroke.SHIFT_MASK evt.getkeycode() == AdfKeyStroke.END_KEY evt.getkeycode() == AdfKeyStroke.ALT_KEY evt.getkeycode() == AdfKeyStroke.HOME_KEY) { return false; //close the popup when teh ESC key is pressed if (evt.getkeycode() == AdfKeyStroke.ESC_KEY){ hidepopup(evt); return false; // get the user typed values valuestr = inputfield.getsubmittedvalue(); // query suggest list on the server. The custom event references the //af:serverlistener component which calls a server side managed bean //method. The payload we send is the current string entered // in the suggest field AdfCustomEvent.queue(suggestPopup,"suggestServerListener", // Send single parameter {filterstring:valuestr,true); // put focus back to the input text field. We set the timout to 400 //ms, which is not the final answer but a value that worked for us. //In a next version, we may improve this settimeout("inputfield.focus();",400); //TAB and ARROW DOWN keys navigate to the suggest popup we need to //handle this in the key down event as otherwise the TAB doesn't work. //Note that a TAB key cannot be used to navigate in the suggest list. //Use the arrow keys for this. The TAB key can be done to navigate the //list, but this requires some more JavaScript that we didn't complete //in time function handlekeydownonsuggestfield(evt){ if (evt.getkeycode() == AdfKeyStroke.ARROWDOWN_KEY) { 7

selectlist = evt.getsource().findcomponent("joblist"); selectlist.focus(); return false; else{ return false; //method called when pressing a key or a mouse button on the list. The //ENTER key or a mosue click select the list value and write it back to //the input text field (the suggest field) function handlelistselection(evt){ if(evt.getkeycode() == AdfKeyStroke.ENTER_KEY evt.gettype() == AdfUIInputEvent.CLICK_EVENT_TYPE){ var list = evt.getsource(); evt.cancel(); var listvalue = list.getproperty("value"); hidepopup(evt); inputfield = evt.getsource().findcomponent("suggestfield"); inputfield.setvalue(listvalue); //cancel dialog else if (evt.getkeycode() == AdfKeyStroke.ESC_KEY){ hidepopup(evt); //function that re-implements the node functionality for the popup //to then call it Please do as if you've never seen this code ;-) function hidepopup(evt){ var suggestpopup = evt.getsource().findcomponent("suggestpopup"); //re-implement close functionality suggestpopup.hide = AdfRichPopup.prototype.hide; suggestpopup.hide(); </script> ]]> </af:group> </f:facet> What's Next This is a first proofpoint that austosuggest functionality can be done with ADF Faces Rich Client. We are planning to continue improving this prototype and a little road map is available in the page source code of the sample. The most important improvement is to create a declarative component from this sample that is parameterizable and that allows developer to use multiple suggest instances on a single page without any java or JavaScript conflict. To this time we are open for feedback regarding new features and bug reports, but also do appreciate receiving code samples that have improvements implemented and bugs fixed. Download Sample The Oracle JDeveloper 11g sample works against the HR database schema and can be downloaded from the ADF Code Corner website: 8

http://www.oracle.com/technetwork/developer-tools/adf/learnmore/index-101235.html Note: Meanwhile ADF Faces has a suggest component that replaces what is explained in this paper. The content is no longer needed but is published for developers who like to read source code especially JavaScript samples for ADF Faces RELATED DOCOMENTATION af:autosuggestbehavior component - http://download.oracle.com/docs/cd/e15523_01/apirefs.1111/e12419/tagdoc/af_autosuggestbe havior.html 9