Thursday, May 19, 2016

Oracle JET Master-Detail with ADF BC REST

One of the most typical use cases in enterprise applications - Master-Detail relationship implementation. I have decided to implement it in JET and to share this practical implementation with you. Hopefully it will be useful, when you will be learning and building JET applications.

Sample application - JETCRUDApp_v8.zip implements a table with row selection in JET (you must run ADF BC REST application in JDEV 12.2.1 and JET in NetBeans 8). On row selection, Job ID is retrieved from selected row and based on this - Job data is fetched. Minimum and Maximum salary values are fetched from Job data and displayed in the chart, along with selected employee salary. I'm executing separate REST call for each new selection in the master and detail data change, see how fast data is being changed in the chart:


Detail data displayed in the chart is fetched based on Job ID selected in the master table:


Each time when new row is selected in the table, chart is changed (REST call to ADF BC is executed in the background, using Job ID for selected employee as a key):


Great thing about JET - it is responsive out of the box. On narrow screen, UI components are re-arranged into single column layout. Editable form is displayed below table:


Chart is displayed below editable form:


Let's take a look, how detail data displayed in the chart is fetched. First of all chart UI component is defined in HTML, it points to series value observable variable:


This observable variable is defined as array in JavaScript. Observable variable allows to push value changes to UI automatically, without additional intervention:


I have defined data structure for Job response, this includes JobId key, Minimum/Maximum values. REST URL will be assigned later, in the table selection listener. This URL will change for each selected row, to retrieve different REST resource. We leave model definition without REST URL here:


Table selection listener creates new model and executes fetch operation for the job. REST URL with Job key is constructed to fetch required detail data. In the success callback returned data is accessed and pushed into observable collection, which is displayed in the chart:

Tuesday, May 17, 2016

We are Hiring - Red Samurai ADF and JET Team

Do you want to join Red Samurai force and become one of our technical experts? The moment is now - we are looking for additional team player.

You should be strong in ADF, highly preferable to be confident with JavaScript and Oracle JET. It never hurts to be fluent in PL/SQL and understand Oracle Forms. You will work in Red Samurai projects focused on ADF and JET.

What would be your position? You name it - you will get a chance to wear multiple hats - expert ADF or JET developer, performance tuning specialist or the guy who solves unsolvable.

Don't wait - drop me email: abaranovskis at redsamuraiconsulting dot com

Monday, May 16, 2016

ADF Hidden Gem - Export Collection Listener

How many times you complained about ADF export collection listener generated output? There are two options for the output - CSV and excelHTML. Both of them are not really Excel friendly (Excel complains, each time when such file is opened) and produced output lacks formatting. Luckily there is a way to specify custom formatter for ADF export collection listener and set your own output type. In this way we can produce better and customized output file for Excel, you can construct Excel document with different formatting and layout.

Demo application with custom formatter for ADF export collection listener is available on GitHub repository - rs-export-xls. This was implemented by Red Samurai Consulting colleague - Fedor Zymarev. You are free to check-out the source code - use it in your projects and add new formatting features.  It would be great, if you could contribute to the community and commit any improvements - simply request merge approval into master on GitHub repository.

Demo runs with the entry page, which contains ADF UI table with Export all/selected rows options:


This is how Excel output looks like. There is a placeholder for worksheet title, header is highlighted and format is recognized by Excel:


You only need to set custom type (RSExcelExport) for ADF export collection listener, instead selecting excelHTML available by default:


Custom type is not available in the list of options, you should type it:


Format type is defined with Java class registered in oracle.adf.view.rich.export.FormatHandler text file, located in ADF META-INF/services folder:


Formatting implementation logic take place in RSExcelFormatHandle class. We are using Apache POI, Java API for Microsoft documents, to prepare native format for Excel:

Saturday, May 14, 2016

Oracle JET Input Search with ADF BC REST

LOV is popular component in ADF, it allows to seach for data entry in the list, select it and assign to the attribute. I was researching, how similar concept can be implemented in Oracle JET, based on data from ADF BC REST service. JET Input Search component seems to be useful for LOV like behavior implementation.

Job ID field is implemented with Input Search. It is based on value/label pair, user enters label and in the background selected value is returned and assigned to the attribute:


Watch this recording, to see how was it is. Search is performed on client side and value selection is instant:


List is being filter when user types value (you can configure it, to start filtering after user enters certain number of charachters):


Try to select a value from the list and update record:


In the background it is using key value SA_REP for update, we can track it in ADF BC log, where actual DB update takes place (through REST PATCH):


Let's take a look into implementation. In HTML I'm using ojInputSearch component with value and options properties. Property options provides list entries and property value holds selected value key:


Options are defined in JavaScript as observableArray, this allows to synch collection data to the UI. There is collection for options and REST service URL (pointing to Jobs ADF BC REST resource):


Data structure is defined by parseJob function, it contains JobId and JobTitle attributes - this will help to map REST response into JET collection:


JET collection is configured with REST URL for Jobs, unlimited fetch size (to fetch list of all jobs) and data structure mapping for REST resource:


Main part - we need to populate JET collection with data, this can be done by executing fetch method (see JET API documentation). In the success callback (executed asynchronously), we can access returned collection and push all entries into observableArray variable, attached to Input Search UI component:


Make sure to set RangeSize = -1 in ADF BC REST service resource definition for Jobs. This will enforce ADF BC to return all rows:


Download sample application (archive contains ADF BC REST sample and JET implementation with NetBeans, you must add JET runtime distribution to run JET sample) - JETCRUDApp_v7.zip.

Tuesday, May 10, 2016

Oracle JET 2.0.1 - Upgrade for CRUD Sample

Oracle JET 2.0.1 was released in April and I decided to upgrade my CRUD sample (based on ADF BC REST services) implemented with previous JET version. There is migration guide, describing main points to consider, while moving to the next JET version. I'm going to add few more points. Hopefully you will find it useful.

Here is CRUD sample UI running with Oracle JET 2.0.1 and interacting with ADF BC REST:


This sample comes with advanced validation rule integration, which is being enforced in ADF BC and propagated to JET UI (read my previous posts about this):


As per migration guide, you must update reference for Alta CSS (2.0.1):


Next update module names in main.js:


CRUD app is rendering paged table out of collection table datasource. Somehow it worked previously, without specifying ojs/ojcollectiontabledatasource module, now it must be specified, otherwise there is error about constructor:


There are changes on UI side. I have wrapped table/form into div with oj-flex-items-pad (includes padding). Table and form and places into separate div's, with oj-flex-item class:


To enable table pagination, I moved it out of div, in previous version it worked inside separate div:


Form group elements are wrapped into oj-flex/oj-flex-item class, this creates better layout for form items:


Update method was changed to handle ADF BC validation error in slightly different way. I'm showing error first and next resetting collection data - to return original value into the table.

Download sample application - JETCRUDApp_v6.zip.

Tuesday, May 3, 2016

Red Samurai ADF Performance Audit Tool Major Update v 5.0

Our ADF performance audit tool is growing and getting more advanced with each release. Current major update v 5.0 brings ADF Click History integration and allows to track ADF UI client request time. This allows to understand, how long it takes to execute action from user perspective. Combined with ADF BC performance monitoring, we could give precise answer about performance bottlenecks from top to bottom.

New features in v 5.0:

1. Redesigned UI with ADF 12.2.1 Responsive template. UI is aligned with Alta UI best practices

2. Group by ECID functionality. We can track request action from top to bottom. This includes client request time (time needed to complete action on UI, including network traffic time). Executed SQL queries and any issues in ADF BC performance for the given request

3. ADF Click history logging. Click history data about UI performance is being intercepted and logged into Red Samurai DB, for analysis. This gives a database of all user requests and time for each request

4. User request statistics visualization dashboard

Here you can see sample data from ADF demo application. User request statistics are presented to help in understanding system performance. Time for each user request is visualized, along with detail information about request (component ID, name, type, etc.). Average times are presented, along with user statistics and top actions. We display total requests count vs. recent requests, to visualize the load on the system:


Each of the logged requests can be tracked down by ECID. Here we can see a list of VO's invoked during UI request and any slow performance behavior happening in ADF BC:


In the next updated v 6.0, we are going to implement UI behavior analysis, to extract most common UI usage patterns in ADF application.

Tuesday, April 26, 2016

Optimize ADF HTTP Response Size with ChangeEventPolicy

You should read this post, if you are looking how to reduce ADF HTTP response size. This can be important for ADF application performance tuning, to improve PPR request response time. By default in ADF 12.2.1, iterator is assigned with ChangeEventPolicy = ppr. This works great for UI component bindings refresh, no need to set individual partial triggers. On other side, this generates extra content in ADF HTTP response and eventually increases response size. I would recommend to use ChangeEventPolicy = ppr, only when its really needed - dynamic forms, with unknown refresh dependencies. Otherwise set ChangeEventPolicy = none, to generate smaller response.

I will demonstrate below the difference for ADF HTTP response with ChangeEventPolicy=ppr/none. First let's take a look into page load response size:


Page contains list component and form. Both are based on two different iterators, set with ChangeEventPolicy = ppr. This generates AdfPage.PAGE.updateAutoPPRComponents calls for each UI item, referencing attributes from the iterator. In complex screens, this adds significant amount of extra text to the response, could increase size even by half:


Partial response also contains same calls added to the response. Select list item:


Each item from the form will be referenced by JavaScript call, to register it for refresh:


Let's change it to ChangeEventPolicy = none. Set it for both iterators:


We should set refresh dependencies manually. Form block must be set with PartialTrigger, referencing list component - to refresh, when list selection changes:


Next/Previous buttons dependency also must be set, to change form row:


With manual refresh dependency changes, there are no extra calls added to ADF HTTP response, reducing overall response size:


Same applies for PPR response:


Download sample application - ChangeEventPolicyPPRApp.zip.