SlideShare a Scribd company logo
1 of 54
Download to read offline
ADF
How to Bring Common UI Patterns to ADF




Luc Bors, AMIS, The Netherlands
Wednesday, June 27, 2012
ODTUG KScope 12
San Antonio, Texas, USA
UI PATTERNS
FUSION APPS PATTERNS
RECOGNIZE THESE ?
RECOGNIZE THESE ?
TABBED NAVIGATION
TABBED NAVIGATION
CLOSE ALL / CLOSE OTHERS
CLOSE ALL / CLOSE OTHERS
CLOSE ALL / CLOSE OTHERS

• e
CAN YOU DO THIS IN ADF ?
CREATE THE CONTEXT MENU

<af:popup id="contextMenu" contentDelivery="lazyUncached"
           eventContext="launcher" launcherVar="source">
<af:menu id="men1" text="#{source.attributes.menuInvokedOnTab}">
    <af:commandMenuItem id="cmi1" text="close“
            actionListener="#{viewScope.jhsDynTabContext.closeThis}">
           <af:setPropertyListener
                from="#{source.attributes.menuInvokedOnTab}"
                to="#{viewScope.jhsDynTabContext.menuInvokedOnTab}"
                type="action"/>
    </af:commandMenuItem>
    <af:commandMenuItem id="cmi2" text="close others“
           actionListener="#{viewScope.jhsDynTabContext.closeOthers}">
…….
    </af:commandMenuItem>
    <af:commandMenuItem id="cmi3" text="close all“
            actionListener="#{viewScope.jhsDynTabContext.closeAll}">
  ……………..
    </af:commandMenuItem>
    </af:menu>
</af:popup>
INVOKING THE CONTEXT MENU

<af:navigationPane ...........>
  <af:commandNavigationItem ...............>
     <f:attribute name="tabId" value="#{tab.id}"/>
     <af:clientListener method="showMenu" type="contextMenu"/>
     <af:clientAttribute name="menuInvokedOnTab" value="#{tab.id}"/>
  </af:commandNavigationItem>
</af:navigationPane >




function showMenu(evt) {
      var popup = AdfPage.PAGE.findComponent("pt:contextMenu");
      ……………..
      popup.show(hints);
      evt.cancel();
}
USE EXISTING FUNCTIONALITY
CLOSE THIS TAB

public void closeThis(ActionEvent action) {

    String id = getMenuInvokedOnTab();
    List<String> tabsToRemove = new ArrayList();

    for (DynTab t : getActiveTabList()) {
         String x = t.getId();
         if (id == x) {
             tabsToRemove.add(x);
         }
    }
    for (String t : tabsToRemove) {
         removeTab(t);
    }
}
CLOSE OTHER TABS

public void closeOthers(ActionEvent action) {

    String id = getMenuInvokedOnTab();
    List<String> tabsToRemove = new ArrayList();

    for (DynTab t : getActiveTabList()) {
         String x = t.getId();
         if (id != x) {
             tabsToRemove.add(x);
         }
    }
    for (String t : tabsToRemove) {
         removeTab(t);
    }
}
CLOSE ALL

public void closeAll(ActionEvent action) {


    List<String> tabsToRemove = new ArrayList();

    for (DynTab t : getActiveTabList()) {
         tabsToRemove.add(t.getId());
    }
    for (String t : tabsToRemove) {
         removeTab(t);
    }
}
CLOSE ALL / CLOSE OTHERS
MOST RECENTLY USED (..HISTORY)
IMPLEMENTATION

•   Record activities
     – Use setPropertyListeners

•   Historybean (session scope) that manages the collection of
    navigation events
     – Display Label, Entity Type and Primary Key
     – bean calls …

•   BusinessService to record event in database for this user
     – (Optional) Also remove events for deleted records!
CREATE THE BEAN

      • Create History bean

<managed-bean id=“1">
   <managed-bean-name id=“2">
                recentHistoryBean</managed-bean-name>
   <managed-bean-class id=“3">
                nl.amis.jsf.history.beans.RecentHistoryBean
   </managed-bean-class>
   <managed-bean-scope id=“3">session</managed-bean-scope>
</managed-bean>
INTERCEPT ACTIVITY
<af:commandLink id="ot3" text="#{row.LastName}" action="edit"
     actionListener="#{recentHistoryBean.add}">

  <af:setPropertyListener from="#{row.EmployeeId}“
         to="#{recentHistoryBean.entityInstanceIdentifier}"
         type="action"/>
  <af:setPropertyListener from="#{row.LastName}“
         to="#{recentHistoryBean.entityInstanceDisplayLabel}"
         type="action"/>
   <af:setPropertyListener from="#{'EMP'}"
         to="#{recentHistoryBean.entityType}"
         type="action"/>
</af:commandLink>
RECORD ACTIVITY
public void add(ActionEvent actionEvent) {
   // Add event code here...

   recentHistory.add(new HistoryEvent(new oracle.jbo.domain.Date()
                   , entityType
                   , entityInstanceIdentifier
                   , entityInstanceDisplayLabel));

   HRServiceImpl hrAppMod = (HRServiceImpl)
      pageTemplateBc.getDataControl().getApplicationModule();
   hrAppMod.recordAndPersistHistoryEntry(recentHistory.get(0));
PERSIST ACTIVITY
public void recordAndPersistHistoryEntry(HistoryEvent event) {
  String statement =
     "RECENT_HISTORY_MANAGER.RECORD_AND_PERSIST_ENTRY(?,?,?,?)";

  callStoredProcedure(statement, new Object[]
            {event.getEntityType()
           , event.getKey().toString()
           , event.getDisplayLabel(), null});
    }
THE RESULT
DO YOU RECOGNIZE THIS ??
GOOGLE SEARCH
ADF QUERY COMPONENT ……
PREPARE THE DATABASE



 • Make sure that the HR user is allowed to use the
   ctxsys.ctx_ddl package


grant EXECUTE on CTXSYS.CTX_DDL to HR
CREATE A SEARCH PACKAGE


function get_emp_search_item ( p_rowid in rowid     ) return
varchar2 as
begin
   for b in (select e.first_name
                  , e.last_name
                  , e.email
                  , e.phone_number
                  , j.job_title
          from employees e left join jobs j
          using (job_id)
          where e.rowid = p_rowid)
        loop
           return b.first_name || ' ' || b.last_name ||
               ' (' || b.email || ', ' || b.phone_number
                    || ', ' || b.job_title || ')';
        end loop;
end get_emp_search_item;
CREATE THE ORACLE TEXT INDICES


-- Configure preferences...
ctx_ddl.create_preference('emp_datastore', 'user_datastore');
ctx_ddl.set_attribute('emp_datastore', 'procedure'
                    , 'ot_search.create_emp_search_item');




 -- Create the indices...
  execute immediate 'create index emp_search_index on
  employees(last_name)
  indextype is ctxsys.context
  parameters (''datastore emp_datastore wordlist wordlist lexer
  lexer stoplist stoplist sync (on commit)'')';
THE BASE CLASSES



• OracleTextSearchSupport:
   • Converts the given user input (the search command):
      <code>searchValue</code> to an Oracle Text search-string.

• BaseViewObjectImpl
   • overrides getCriteriaItemClause(ViewCriteriaItem vci)

• BaseViewDefImpl
   • implementation to provide the following custom properties on ViewObjects:
        •   ORACLE_TEXT_SEARCH_ATTRIBUTE: To mark the column in which the seach info
            is queried
        •   ORACLE_TEXT_INDEX_ATTRIBUTE: To mark the database column on which the
            index was defined in the database.
CREATE THE MODEL PROJECT
CREATE THE MODEL PROJECT
VIEWCONTROLLER : A BEAN
<managed-bean-name id="1">departmentsQuickSearch</managed-bean-name>
 <managed-bean-class id="4">
          adfplus.quicksearch.controller.bean.QuickSearchBean
 </managed-bean-class>
 <managed-bean-scope id="2">pageFlow</managed-bean-scope>
 <managed-property id=“8">
    <property-name id=“10">iteratorBindingName</property-name>
    <property-class>java.lang.String</property-class>
    <value id="9">DepartmentsVO1Iterator</value>
 </managed-property>
 <managed-property id="11">
    <property-name id="13">searchAttribute</property-name>
    <property-class>java.lang.String</property-class>
    <value id="12">DepartmentSearchString</value>
 </managed-property>
 <managed-property id="14">
   <property-name id="15">searchIteratorBindingName</property-name>
   <property-class>java.lang.String</property-class>
   <value id="16">DepartmentsVO1IteratorQuickSearch</value>
  </managed-property>
VIEWCONTROLLER : A SUBFORM

<af:subform id="s1" defaultCommand="cb7">
    <af:panelGroupLayout id="pgl4" layout="horizontal"
                          inlineStyle="margin:10px;">
    <af:inputText label="Search" id="it2“
         value="#{pageFlowScope.departmentsQuickSearch.searchValue}">
       <af:autoSuggestBehavior
            suggestItems=
            "#{pageFlowScope.departmentsQuickSearch.suggestItems}"
             maxSuggestedItems="10"/>
    </af:inputText>

    <af:commandButton text="Search" id="cb7"
            action="#{pageFlowScope.departmentsQuickSearch.go}"
            partialSubmit="true"/>
  </af:panelGroupLayout>
</af:subform>
VIEWCONTROLLER : SEARCH METHOD

private synchronized List<SelectItem> search(String searchValue) {

  DCIteratorBinding iter = getSearchIteratorBinding();
  applySearchCriteria(iter, searchAttribute, searchValue);

  translations.clear();
  lastSuggestList = new ArrayList<SelectItem>();
  lastSearchValue = searchValue;

  Row[] rows = iter.getAllRowsInRange();
    for (Row row : rows) {
       String description = (String)row.getAttribute(searchAttribute);
       lastSuggestList.add(new SelectItem(description));
       translations.put(description, row.getKey());
     }
return lastSuggestList;
  }
THE RESULT
REAL TIME UPDATES
THE CONCEPT
THE IMPLEMENTATION; THE DATABASE




grant change notification to <user>;
REGISTER FOR DBQRCN (STEP 1)


public void startChangeNotification(){
   DatabaseChangeRegistration dcr = null;
   String query = "SELECT * from DEPARTMENTS";
   Properties prop = new Properties();
   prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS
        ,"true");
prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION
        ,"true");
   try
    {
       dcr = conn.registerDatabaseChangeNotification(prop);
       RdbmsChangeEventListener listener =
             new RdbmsChangeEventListener(this);
       dcr.addListener(listener);
       ………..
REGISTER FOR DBQRCN (STEP 2)


// second step: add objects in the registration:
    Statement stmt = conn.createStatement();

((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
  ResultSet rs = stmt.executeQuery(query);
      while (rs.next()){}
             rs.close();
             stmt.close();
WHATS NEXT ….
SETUP ACTIVE DATA COMPONENT
public void setupActiveData() {
   ActiveModelContext context =
          ActiveModelContext.getActiveModelContext();
   Object[] keyPath = new String[0];
   context.addActiveModelInfo(
                    this
                  , keyPath
                  , "activemessage");
   System.out.println("add active bean as listener");
   databaseNotificationProcessor.registerAsListener(this);
}
SETUP THE ACTUAL UPDATE
public void triggerDataUpdate(String message) {
    this.message = message;
    counter.incrementAndGet();
    ActiveDataUpdateEvent event =
      ActiveDataEventUtil.buildActiveDataUpdateEvent(
                    ActiveDataEntry.ChangeType.UPDATE,
                    counter.get(),
                    new String[0], null,
                    new String[] { "activemessage" },
                    new Object[] { message });
     System.out.println("fireActiveDataUpdate");
     fireActiveDataUpdate(event);
    }
IMPLEMENTATION IN THE PAGE
 <af:activeOutputText
        value="#{pageFlowScope.trackChangesBean.updates}"
        id="aot1"
        visible="false">
   <af:clientListener method="activeDataCallback"
                      type="propertyChange"/>
</af:activeOutputText>




 <af:resource type="javascript">
    activeDataCallback = function (event) {
    var button =
    AdfPage.PAGE.findComponentByAbsoluteId("pt1:r1:0:cb1");
    button.setVisible(true);
    }
 </af:resource>
THE RESULT
PATTERNS UNDER INVESTIGATION

• Grouping Tabs
• Drag and Drop Tabs in UI Shell
   – dragSource and dropTarget




•   Duplicating Tabs
    – Restarting a new instance of a taskflow
PATTERNS UNDER INVESTIGATION

•   Adding Sticky Notes
    – dragSource and dropTarget
    – Contextual events




    – Concept : http://technology.amis.nl
        • Search for: adf-11g-dragn-drop-and-contextual-events/
RESOURCES
RESOURCES
SUMMARY
ADF
How to Bring Common UI Patterns to ADF


Luc Bors, AMIS, The Netherlands

Luc.Bors@amis.nl
LucBors@gmail.com
Follow me on Twitter : @lucb_


Wednesday, June 27, 2012
ODTUG KScope 12
San Antonio, Texas, USA

More Related Content

What's hot

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Cycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveCycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveEugene Zharkov
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashBret Little
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
A Tour to MySQL Commands
A Tour to MySQL CommandsA Tour to MySQL Commands
A Tour to MySQL CommandsHikmat Dhamee
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applicationsSkills Matter
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3markstory
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than WebHeiko Behrens
 

What's hot (20)

Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Cycle.js: Functional and Reactive
Cycle.js: Functional and ReactiveCycle.js: Functional and Reactive
Cycle.js: Functional and Reactive
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
 
Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3
 
Lodash js
Lodash jsLodash js
Lodash js
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
A Tour to MySQL Commands
A Tour to MySQL CommandsA Tour to MySQL Commands
A Tour to MySQL Commands
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
 

Similar to How te bring common UI patterns to ADF

EclipseCon2011 Cross-Platform Mobile Development with Eclipse
EclipseCon2011 Cross-Platform Mobile Development with EclipseEclipseCon2011 Cross-Platform Mobile Development with Eclipse
EclipseCon2011 Cross-Platform Mobile Development with EclipseHeiko Behrens
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access RunbookTaha Shakeel
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Kevin Octavian
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeMacoscope
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentationValdis Iljuconoks
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScriptkvangork
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascriptkvangork
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3Simon Su
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 

Similar to How te bring common UI patterns to ADF (20)

EclipseCon2011 Cross-Platform Mobile Development with Eclipse
EclipseCon2011 Cross-Platform Mobile Development with EclipseEclipseCon2011 Cross-Platform Mobile Development with Eclipse
EclipseCon2011 Cross-Platform Mobile Development with Eclipse
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
Knockoutjs UG meeting presentation
Knockoutjs UG meeting presentationKnockoutjs UG meeting presentation
Knockoutjs UG meeting presentation
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
XQuery Rocks
XQuery RocksXQuery Rocks
XQuery Rocks
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 

More from Getting value from IoT, Integration and Data Analytics

More from Getting value from IoT, Integration and Data Analytics (20)

AMIS Oracle OpenWorld en Code One Review 2018 - Blockchain, Integration, Serv...
AMIS Oracle OpenWorld en Code One Review 2018 - Blockchain, Integration, Serv...AMIS Oracle OpenWorld en Code One Review 2018 - Blockchain, Integration, Serv...
AMIS Oracle OpenWorld en Code One Review 2018 - Blockchain, Integration, Serv...
 
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: Custom Application ...
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: Custom Application ...AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: Custom Application ...
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: Custom Application ...
 
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: SaaS
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: SaaSAMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: SaaS
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 2: SaaS
 
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Data
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: DataAMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Data
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Data
 
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Cloud Infrastructure
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Cloud Infrastructure AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Cloud Infrastructure
AMIS Oracle OpenWorld en Code One Review 2018 - Pillar 1: Cloud Infrastructure
 
10 tips voor verbetering in je Linkedin profiel
10 tips voor verbetering in je Linkedin profiel10 tips voor verbetering in je Linkedin profiel
10 tips voor verbetering in je Linkedin profiel
 
Iot in de zorg the next step - fit for purpose
Iot in de zorg   the next step - fit for purpose Iot in de zorg   the next step - fit for purpose
Iot in de zorg the next step - fit for purpose
 
Iot overview .. Best practices and lessons learned by Conclusion Conenct
Iot overview .. Best practices and lessons learned by Conclusion Conenct Iot overview .. Best practices and lessons learned by Conclusion Conenct
Iot overview .. Best practices and lessons learned by Conclusion Conenct
 
IoT Fit for purpose - how to be successful in IOT Conclusion Connect
IoT Fit for purpose - how to be successful in IOT Conclusion Connect IoT Fit for purpose - how to be successful in IOT Conclusion Connect
IoT Fit for purpose - how to be successful in IOT Conclusion Connect
 
Industry and IOT Overview of protocols and best practices Conclusion Connect
Industry and IOT Overview of protocols and best practices  Conclusion ConnectIndustry and IOT Overview of protocols and best practices  Conclusion Connect
Industry and IOT Overview of protocols and best practices Conclusion Connect
 
IoT practical case using the people counter sensing traffic density build usi...
IoT practical case using the people counter sensing traffic density build usi...IoT practical case using the people counter sensing traffic density build usi...
IoT practical case using the people counter sensing traffic density build usi...
 
R introduction decision_trees
R introduction decision_treesR introduction decision_trees
R introduction decision_trees
 
Introduction overviewmachinelearning sig Door Lucas Jellema
Introduction overviewmachinelearning sig Door Lucas JellemaIntroduction overviewmachinelearning sig Door Lucas Jellema
Introduction overviewmachinelearning sig Door Lucas Jellema
 
IoT and the Future of work
IoT and the Future of work IoT and the Future of work
IoT and the Future of work
 
Oracle OpenWorld 2017 Review (31st October 2017 - 250 slides)
Oracle OpenWorld 2017 Review (31st October 2017 - 250 slides)Oracle OpenWorld 2017 Review (31st October 2017 - 250 slides)
Oracle OpenWorld 2017 Review (31st October 2017 - 250 slides)
 
Ethereum smart contracts - door Peter Reitsma
Ethereum smart contracts - door Peter ReitsmaEthereum smart contracts - door Peter Reitsma
Ethereum smart contracts - door Peter Reitsma
 
Blockchain - Techniek en usecases door Robert van Molken - AMIS - Conclusion
Blockchain - Techniek en usecases door Robert van Molken - AMIS - ConclusionBlockchain - Techniek en usecases door Robert van Molken - AMIS - Conclusion
Blockchain - Techniek en usecases door Robert van Molken - AMIS - Conclusion
 
kennissessie blockchain - Wat is Blockchain en smart contracts @Conclusion
kennissessie blockchain -  Wat is Blockchain en smart contracts @Conclusion kennissessie blockchain -  Wat is Blockchain en smart contracts @Conclusion
kennissessie blockchain - Wat is Blockchain en smart contracts @Conclusion
 
Internet of Things propositie - Enterprise IOT - AMIS - Conclusion
Internet of Things propositie - Enterprise IOT - AMIS - Conclusion Internet of Things propositie - Enterprise IOT - AMIS - Conclusion
Internet of Things propositie - Enterprise IOT - AMIS - Conclusion
 
Omc AMIS evenement 26012017 Dennis van Soest
Omc AMIS evenement 26012017 Dennis van SoestOmc AMIS evenement 26012017 Dennis van Soest
Omc AMIS evenement 26012017 Dennis van Soest
 

Recently uploaded

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 

Recently uploaded (20)

04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

How te bring common UI patterns to ADF

  • 1. ADF How to Bring Common UI Patterns to ADF Luc Bors, AMIS, The Netherlands Wednesday, June 27, 2012 ODTUG KScope 12 San Antonio, Texas, USA
  • 8. CLOSE ALL / CLOSE OTHERS
  • 9. CLOSE ALL / CLOSE OTHERS
  • 10. CLOSE ALL / CLOSE OTHERS • e
  • 11. CAN YOU DO THIS IN ADF ?
  • 12. CREATE THE CONTEXT MENU <af:popup id="contextMenu" contentDelivery="lazyUncached" eventContext="launcher" launcherVar="source"> <af:menu id="men1" text="#{source.attributes.menuInvokedOnTab}"> <af:commandMenuItem id="cmi1" text="close“ actionListener="#{viewScope.jhsDynTabContext.closeThis}"> <af:setPropertyListener from="#{source.attributes.menuInvokedOnTab}" to="#{viewScope.jhsDynTabContext.menuInvokedOnTab}" type="action"/> </af:commandMenuItem> <af:commandMenuItem id="cmi2" text="close others“ actionListener="#{viewScope.jhsDynTabContext.closeOthers}"> ……. </af:commandMenuItem> <af:commandMenuItem id="cmi3" text="close all“ actionListener="#{viewScope.jhsDynTabContext.closeAll}"> …………….. </af:commandMenuItem> </af:menu> </af:popup>
  • 13. INVOKING THE CONTEXT MENU <af:navigationPane ...........> <af:commandNavigationItem ...............> <f:attribute name="tabId" value="#{tab.id}"/> <af:clientListener method="showMenu" type="contextMenu"/> <af:clientAttribute name="menuInvokedOnTab" value="#{tab.id}"/> </af:commandNavigationItem> </af:navigationPane > function showMenu(evt) { var popup = AdfPage.PAGE.findComponent("pt:contextMenu"); …………….. popup.show(hints); evt.cancel(); }
  • 15. CLOSE THIS TAB public void closeThis(ActionEvent action) { String id = getMenuInvokedOnTab(); List<String> tabsToRemove = new ArrayList(); for (DynTab t : getActiveTabList()) { String x = t.getId(); if (id == x) { tabsToRemove.add(x); } } for (String t : tabsToRemove) { removeTab(t); } }
  • 16. CLOSE OTHER TABS public void closeOthers(ActionEvent action) { String id = getMenuInvokedOnTab(); List<String> tabsToRemove = new ArrayList(); for (DynTab t : getActiveTabList()) { String x = t.getId(); if (id != x) { tabsToRemove.add(x); } } for (String t : tabsToRemove) { removeTab(t); } }
  • 17. CLOSE ALL public void closeAll(ActionEvent action) { List<String> tabsToRemove = new ArrayList(); for (DynTab t : getActiveTabList()) { tabsToRemove.add(t.getId()); } for (String t : tabsToRemove) { removeTab(t); } }
  • 18. CLOSE ALL / CLOSE OTHERS
  • 19. MOST RECENTLY USED (..HISTORY)
  • 20. IMPLEMENTATION • Record activities – Use setPropertyListeners • Historybean (session scope) that manages the collection of navigation events – Display Label, Entity Type and Primary Key – bean calls … • BusinessService to record event in database for this user – (Optional) Also remove events for deleted records!
  • 21. CREATE THE BEAN • Create History bean <managed-bean id=“1"> <managed-bean-name id=“2"> recentHistoryBean</managed-bean-name> <managed-bean-class id=“3"> nl.amis.jsf.history.beans.RecentHistoryBean </managed-bean-class> <managed-bean-scope id=“3">session</managed-bean-scope> </managed-bean>
  • 22. INTERCEPT ACTIVITY <af:commandLink id="ot3" text="#{row.LastName}" action="edit" actionListener="#{recentHistoryBean.add}"> <af:setPropertyListener from="#{row.EmployeeId}“ to="#{recentHistoryBean.entityInstanceIdentifier}" type="action"/> <af:setPropertyListener from="#{row.LastName}“ to="#{recentHistoryBean.entityInstanceDisplayLabel}" type="action"/> <af:setPropertyListener from="#{'EMP'}" to="#{recentHistoryBean.entityType}" type="action"/> </af:commandLink>
  • 23. RECORD ACTIVITY public void add(ActionEvent actionEvent) { // Add event code here... recentHistory.add(new HistoryEvent(new oracle.jbo.domain.Date() , entityType , entityInstanceIdentifier , entityInstanceDisplayLabel)); HRServiceImpl hrAppMod = (HRServiceImpl) pageTemplateBc.getDataControl().getApplicationModule(); hrAppMod.recordAndPersistHistoryEntry(recentHistory.get(0));
  • 24. PERSIST ACTIVITY public void recordAndPersistHistoryEntry(HistoryEvent event) { String statement = "RECENT_HISTORY_MANAGER.RECORD_AND_PERSIST_ENTRY(?,?,?,?)"; callStoredProcedure(statement, new Object[] {event.getEntityType() , event.getKey().toString() , event.getDisplayLabel(), null}); }
  • 26. DO YOU RECOGNIZE THIS ??
  • 29. PREPARE THE DATABASE • Make sure that the HR user is allowed to use the ctxsys.ctx_ddl package grant EXECUTE on CTXSYS.CTX_DDL to HR
  • 30. CREATE A SEARCH PACKAGE function get_emp_search_item ( p_rowid in rowid ) return varchar2 as begin for b in (select e.first_name , e.last_name , e.email , e.phone_number , j.job_title from employees e left join jobs j using (job_id) where e.rowid = p_rowid) loop return b.first_name || ' ' || b.last_name || ' (' || b.email || ', ' || b.phone_number || ', ' || b.job_title || ')'; end loop; end get_emp_search_item;
  • 31. CREATE THE ORACLE TEXT INDICES -- Configure preferences... ctx_ddl.create_preference('emp_datastore', 'user_datastore'); ctx_ddl.set_attribute('emp_datastore', 'procedure' , 'ot_search.create_emp_search_item'); -- Create the indices... execute immediate 'create index emp_search_index on employees(last_name) indextype is ctxsys.context parameters (''datastore emp_datastore wordlist wordlist lexer lexer stoplist stoplist sync (on commit)'')';
  • 32. THE BASE CLASSES • OracleTextSearchSupport: • Converts the given user input (the search command): <code>searchValue</code> to an Oracle Text search-string. • BaseViewObjectImpl • overrides getCriteriaItemClause(ViewCriteriaItem vci) • BaseViewDefImpl • implementation to provide the following custom properties on ViewObjects: • ORACLE_TEXT_SEARCH_ATTRIBUTE: To mark the column in which the seach info is queried • ORACLE_TEXT_INDEX_ATTRIBUTE: To mark the database column on which the index was defined in the database.
  • 33. CREATE THE MODEL PROJECT
  • 34. CREATE THE MODEL PROJECT
  • 35. VIEWCONTROLLER : A BEAN <managed-bean-name id="1">departmentsQuickSearch</managed-bean-name> <managed-bean-class id="4"> adfplus.quicksearch.controller.bean.QuickSearchBean </managed-bean-class> <managed-bean-scope id="2">pageFlow</managed-bean-scope> <managed-property id=“8"> <property-name id=“10">iteratorBindingName</property-name> <property-class>java.lang.String</property-class> <value id="9">DepartmentsVO1Iterator</value> </managed-property> <managed-property id="11"> <property-name id="13">searchAttribute</property-name> <property-class>java.lang.String</property-class> <value id="12">DepartmentSearchString</value> </managed-property> <managed-property id="14"> <property-name id="15">searchIteratorBindingName</property-name> <property-class>java.lang.String</property-class> <value id="16">DepartmentsVO1IteratorQuickSearch</value> </managed-property>
  • 36. VIEWCONTROLLER : A SUBFORM <af:subform id="s1" defaultCommand="cb7"> <af:panelGroupLayout id="pgl4" layout="horizontal" inlineStyle="margin:10px;"> <af:inputText label="Search" id="it2“ value="#{pageFlowScope.departmentsQuickSearch.searchValue}"> <af:autoSuggestBehavior suggestItems= "#{pageFlowScope.departmentsQuickSearch.suggestItems}" maxSuggestedItems="10"/> </af:inputText> <af:commandButton text="Search" id="cb7" action="#{pageFlowScope.departmentsQuickSearch.go}" partialSubmit="true"/> </af:panelGroupLayout> </af:subform>
  • 37. VIEWCONTROLLER : SEARCH METHOD private synchronized List<SelectItem> search(String searchValue) { DCIteratorBinding iter = getSearchIteratorBinding(); applySearchCriteria(iter, searchAttribute, searchValue); translations.clear(); lastSuggestList = new ArrayList<SelectItem>(); lastSearchValue = searchValue; Row[] rows = iter.getAllRowsInRange(); for (Row row : rows) { String description = (String)row.getAttribute(searchAttribute); lastSuggestList.add(new SelectItem(description)); translations.put(description, row.getKey()); } return lastSuggestList; }
  • 41. THE IMPLEMENTATION; THE DATABASE grant change notification to <user>;
  • 42. REGISTER FOR DBQRCN (STEP 1) public void startChangeNotification(){ DatabaseChangeRegistration dcr = null; String query = "SELECT * from DEPARTMENTS"; Properties prop = new Properties(); prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS ,"true"); prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION ,"true"); try { dcr = conn.registerDatabaseChangeNotification(prop); RdbmsChangeEventListener listener = new RdbmsChangeEventListener(this); dcr.addListener(listener); ………..
  • 43. REGISTER FOR DBQRCN (STEP 2) // second step: add objects in the registration: Statement stmt = conn.createStatement(); ((OracleStatement)stmt).setDatabaseChangeRegistration(dcr); ResultSet rs = stmt.executeQuery(query); while (rs.next()){} rs.close(); stmt.close();
  • 45. SETUP ACTIVE DATA COMPONENT public void setupActiveData() { ActiveModelContext context = ActiveModelContext.getActiveModelContext(); Object[] keyPath = new String[0]; context.addActiveModelInfo( this , keyPath , "activemessage"); System.out.println("add active bean as listener"); databaseNotificationProcessor.registerAsListener(this); }
  • 46. SETUP THE ACTUAL UPDATE public void triggerDataUpdate(String message) { this.message = message; counter.incrementAndGet(); ActiveDataUpdateEvent event = ActiveDataEventUtil.buildActiveDataUpdateEvent( ActiveDataEntry.ChangeType.UPDATE, counter.get(), new String[0], null, new String[] { "activemessage" }, new Object[] { message }); System.out.println("fireActiveDataUpdate"); fireActiveDataUpdate(event); }
  • 47. IMPLEMENTATION IN THE PAGE <af:activeOutputText value="#{pageFlowScope.trackChangesBean.updates}" id="aot1" visible="false"> <af:clientListener method="activeDataCallback" type="propertyChange"/> </af:activeOutputText> <af:resource type="javascript"> activeDataCallback = function (event) { var button = AdfPage.PAGE.findComponentByAbsoluteId("pt1:r1:0:cb1"); button.setVisible(true); } </af:resource>
  • 49. PATTERNS UNDER INVESTIGATION • Grouping Tabs • Drag and Drop Tabs in UI Shell – dragSource and dropTarget • Duplicating Tabs – Restarting a new instance of a taskflow
  • 50. PATTERNS UNDER INVESTIGATION • Adding Sticky Notes – dragSource and dropTarget – Contextual events – Concept : http://technology.amis.nl • Search for: adf-11g-dragn-drop-and-contextual-events/
  • 54. ADF How to Bring Common UI Patterns to ADF Luc Bors, AMIS, The Netherlands Luc.Bors@amis.nl LucBors@gmail.com Follow me on Twitter : @lucb_ Wednesday, June 27, 2012 ODTUG KScope 12 San Antonio, Texas, USA