This post talks about how to display hierarchical dropdown in selectOneChoice.
There is one method explained by Frank here. Well this method show two levels in hierarchical dropdown using two af:ForEach iteration.
What if we have multiple level, and don't know how many af:forEach would be required. Other approach is to achieve required spaces through query to show dropdown structure. Thanks to my friend Prahlad for sharing this.
In below query, emp_disp will have appropriate spaces based on the level of the employee in the employee hierarchy.
select LEVEL,FIRST_NAME,LAST_NAME,
LPAD(FIRST_NAME ||' '|| LAST_NAME,length(FIRST_NAME ||' '|| LAST_NAME)+(LEVEL-1)*4,unistr('\00A0\00A0\00A0\00A0')) emp_disp
from EMPLOYEES
start with MANAGER_ID is null
connect by prior EMPLOYEE_ID = MANAGER_ID;
All you need to do is create a VO with above sample query and use this for dropdown.
Sample is uploaded here..
Enjoy.
Showing posts with label ADF. Show all posts
Showing posts with label ADF. Show all posts
Friday, March 13, 2015
Thursday, December 18, 2014
Handling Ok Cancel action on Uncommited warning popup
Handling Ok Cancel action on Uncommited warning popup
There are couple of post which covers how to show uncommitted data warning popup. So I will not go in details for that, rather we will cover how to handle ok cancel action on uncommited data warning popup.
Few references for, how to show uncommitted data warning popup :
http://www.oracle.com/technetwork/testcontent/unsaveddatawarning-096556.html
http://www.awasthiashish.com/2012/10/uncommitedunsaved-data-warnig-on-page.html
Select af:document from page structure and go to property inspector, now set UncommitedDataWarning to on.
Before starting with implementation, I would like to refer the information found on OTN forum :
https://community.oracle.com/message/10982006#10982006
From looking at the design specs, uncommitted data warning is a combination of ADF view and ADFc functionality. Good news is that - at least by the specs - a dirty transaction in a region should be automatically detected. The class that handles the uncommitted data warning is AdfcDirtyPageHandler. This class is registered in a text file "oracle.adf.view.rich.context.DirtyPageHandler". So if this works as with how you change the ADFc exception handler, then its by a file with this name in the application META-INF/service folder (the latter doesn't exist by default). Note that "AdfcDirtyPageHandler" is in an internal package, which means its not supported to extend it. However, the default abstract class is DirtyPageHandler and this is in a public package.
From the Java docs:
META_INF/services-based application-scoped object for tracking whether navigation will result in data loss. Only a single implementation may be registered per application. Registering multiple implementations will result in an IllegalStateException at applciation initialization. If no implementation is registered, a default implementation will be used. That implementation will always return false from isDataDirty and will do nothing in response to a trackNavigation call.
Maybe worth filing an ER to get a public listener / hook into this instead of dealing with your own implementation. Will file one
Before starting with implementation, I would like to refer the information found on OTN forum :
https://community.oracle.com/message/10982006#10982006
From looking at the design specs, uncommitted data warning is a combination of ADF view and ADFc functionality. Good news is that - at least by the specs - a dirty transaction in a region should be automatically detected. The class that handles the uncommitted data warning is AdfcDirtyPageHandler. This class is registered in a text file "oracle.adf.view.rich.context.DirtyPageHandler". So if this works as with how you change the ADFc exception handler, then its by a file with this name in the application META-INF/service folder (the latter doesn't exist by default). Note that "AdfcDirtyPageHandler" is in an internal package, which means its not supported to extend it. However, the default abstract class is DirtyPageHandler and this is in a public package.
From the Java docs:
META_INF/services-based application-scoped object for tracking whether navigation will result in data loss. Only a single implementation may be registered per application. Registering multiple implementations will result in an IllegalStateException at applciation initialization. If no implementation is registered, a default implementation will be used. That implementation will always return false from isDataDirty and will do nothing in response to a trackNavigation call.
Maybe worth filing an ER to get a public listener / hook into this instead of dealing with your own implementation. Will file one
To handle ok cancel action on uncommitted data warning popup :
1. Create a text file with name "oracle.adf.view.rich.context.DirtyPageHandler" under folder structure :
TestApp/.adf/META-INF/services/
2. Create a java class CustomDirtyPageHandler which extends "AdfcDirtyPageHandler".
public class CustomDirtyPageHandler extends AdfcDirtyPageHandler
3. Update the file "oracle.adf.view.rich.context.DirtyPageHandler" created in step1 with the name of custom handler ( full package path ).
4. Now you are good to write your logic in CustomDirtyPageHandler java class. In sample code below, Rollback is executed on OK action. Make sure that Rollback binding is available in pageDef of jspx.
Enjoy!!!
Wednesday, December 17, 2014
Scroll to top on Commit or Rollback
Scroll to top on Commit or Rollback
This post is about scrolling to some component on user action. Mostly when user click save or cancel, a message is displayed on top of the page. At the same time, it is required to scroll the page to top and show message to the user... rather user scrolling up to see what happened.
Implementation is simple :
1. Need a javascript method to scroll.
2. Next step is just to invoke this javascript method at the end of your commit call.
Enjoy!!
Enjoy!!
Labels:
ADF,
ADF Faces,
JavaScript
Calling JavaScript from ManagedBean
Calling JavaScript from ManagedBean
Often there are requirements to call the invoke javascript from actionListener to set focus or scroll etc. Here goes the code to invoke javascript :
Enjoy !!!
Labels:
ADF,
ADF Faces,
JavaScript,
ManagedBean
Monday, November 24, 2014
Invoke Bindings from PageTemplate PageDef
Invoke Bindings from PageTemplate PageDef
There are scenarios when certain method binding in pageTemplate's pageDef needs to be invoked from some button Action in page. Here are the details :1. For page based on the pageTemplate, there will be reference of pageTemplate's PageDef created in page's pageDef.
2. Now in order to access bindings in pageTemplate's pageDef, refer below code. Enjoy!!!
Labels:
ADF,
ADF Faces,
Bindings,
PageTemplate
Thursday, November 20, 2014
Show exceptions caught in Managed Beans
There are couple of scenarios when some exception is caught while executing some logic in managed bean. The post is about how to show those exceptions to user and when it is required to do it explicitly.
For most of the scenarios, ADFm Error Handlers shows the message. But in case when some exception occurs in managedBean, it can be caught and reported to ADFm Error Handler using below code.
Note : Using the ADF model error handling for displaying exceptions thrown in managed beans require the current ADF Faces page to have an associated PageDef file (which is the case if the page or view contains ADF bound components).
Sample App is uploaded here. Following scenarios are covered :
Enjoy !!!
For most of the scenarios, ADFm Error Handlers shows the message. But in case when some exception occurs in managedBean, it can be caught and reported to ADFm Error Handler using below code.
BindingContext bctx = BindingContext.getCurrent(); ((DCBindingContainer)bctx.getCurrentBindingsEntry()).reportException(ex);
Note : Using the ADF model error handling for displaying exceptions thrown in managed beans require the current ADF Faces page to have an associated PageDef file (which is the case if the page or view contains ADF bound components).
Sample App is uploaded here. Following scenarios are covered :
Scenario Description | Button Text in Sample App | Requires Explicit Handling to show messaage to User | |
1 | Drag and Drop AM Method on Page as command Button | throwJboExceptionFromAM | No |
2 | Call AM method in Bean method through bindings | Call throwJboExceptionFromAM in Bean through Bindings | No. By default, all exception are handled by ADFm Error Handler when calling AMMethod through bindings. When you check for exception in operationBinding and report it expliclity .. It is basically duplicating the message |
3 | throw an exception in ActionListener | ThrowingExceptionInActionListener | Yes. See the button in section Handled and it's actionListener. How the exception is reported . |
Enjoy !!!
Friday, November 14, 2014
Setting Button Action from ActionListener
Control the button Action based on the logic inside ActionListener
This post talks about how to control the button Action based on the logic inside ActionListener. Lets say there is a commandButton "Go to View2" on pageFragment "View1" . On Click of this button conditionally a navigation is required. Here goes the code :That's all ..enjoy.
Labels:
Action,
ActionListener,
ADF,
ADF Faces,
CommandButton
Tuesday, November 11, 2014
SelectBooleanCheckbox with [Y, N] values using a custom converter
How to show selectBooleanCheckbox with [Y,N} values using a custom converter.
So first we need a converter which converts [Y,N] to [true, false] and viceversa. Here goes the converter code :-
Next goes the code snippet showing usage of our converter in selectBooleanCheckbox.
So first we need a converter which converts [Y,N] to [true, false] and viceversa. Here goes the converter code :-
Converter needs to be declared in faces-config.xml ..
Next goes the code snippet showing usage of our converter in selectBooleanCheckbox.
Enjoy!!
Wednesday, October 15, 2014
Retain current row after Rollback or refresh
It is very common requirement to retain the current row on rollback or after executing VO. To retain the current Row, first get the current Row key and then call rollback. Now you have the rowKey to set the currentRow again.
Tuesday, September 30, 2014
Show Faces Message using JavaScript in ADF Faces
How to show faces Message using javaScript in ADF Faces
I have read this on Ashish Awasthi's blog. So if you want to read full detail sample refer to his blog.
For reference purpose, I am putting two lines of code here :
// Clear all validation message
AdfPage.PAGE.clearAllMessages();
//Invoke FacesMessage AdfPage.PAGE.addMessage('it1', new AdfFacesMessage(AdfFacesMessage.TYPE_ERROR, "Invalid Value", "Enter Characters Only"));
Other valid types are : TYPE_ERROR, TYPE_INFO, TYPE_WARNING, TYPE_FATAL .
Enjoy !!
Labels:
ADF,
ADF Faces,
Faces Message
Friday, September 26, 2014
WebProxy - Log Request and Response xml to console
How to view the request and response xml for a webservice call made using webProxy.
To see the soap request and response we can set a JAX-WS parameter.
"-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true" ,this will dump the data in your console output.
Edit the Run/Debug Profile for the project and then run it . See the screenshot for more details :
You can also write a SOAP logging handler ....will be covered in future posts.
Enjoy...
Labels:
ADF,
Logging,
WebProxy,
WebService
Tuesday, August 5, 2014
Uploading Large Files to UCM - af:inputFile Component
This post covers uploading large files to UCM using inputFile Component.
JDeveloper Version : Studio Edition Version 11.1.1.7.0
Recently I was working with af:inputFile Component trying to upload files to UCM. I hit an issue when trying to upload files larger than 2MB. I am going to share my findings :
1. InputFile component gets stuck if trying to upload large file... and it doesn't even allow to select other small file once it is stuck. I searched google and found this :
Andrejusb Blog - Oracle UCM 11g uploading large files
Set this parameter "org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE" = 20971520 in web.xml for upload up to 20 MB.{ maximum file upload size to 20971520 bytes, or divided by 1024 and one more time by 1024 - 20 MB }
2. Now again question is - what happens after that 20MB file ... inputFile Component gets stuck. Further digging found that it is component bug and patch is available.
Dowload and apply Patch : 15931140
Enjoy !!
JDeveloper Version : Studio Edition Version 11.1.1.7.0
Recently I was working with af:inputFile Component trying to upload files to UCM. I hit an issue when trying to upload files larger than 2MB. I am going to share my findings :
1. InputFile component gets stuck if trying to upload large file... and it doesn't even allow to select other small file once it is stuck. I searched google and found this :
Andrejusb Blog - Oracle UCM 11g uploading large files
Set this parameter "org.apache.myfaces.trinidad.UPLOAD_MAX_DISK_SPACE" = 20971520 in web.xml for upload up to 20 MB.{ maximum file upload size to 20971520 bytes, or divided by 1024 and one more time by 1024 - 20 MB }
2. Now again question is - what happens after that 20MB file ... inputFile Component gets stuck. Further digging found that it is component bug and patch is available.
Dowload and apply Patch : 15931140
Enjoy !!
Wednesday, May 28, 2014
Error Message html formatting
How to apply HTML formatting to error message
In my earlier post, I explained how to show error messages programmatically. This post covers how to apply HTML formatting to error messages. Credits to Ashish Awasthi's blog for this one.
Enjoy...
Monday, March 31, 2014
Showing Error Message programmatically
How to show error message programmatically
ADF Faces uses the standard JSF messaging API. JSF supports a built-in framework for messaging by allowing FacesMessage instances to be added to the FacesContext object using the addMessage(java.lang.String clientId, FacesMessage message) method.
Error Message can be shown inline using af:messages and setting inline property to false.
Code to show error Message :
Following types of error messages can be shown :
Component-Level Message :
These messages are associated to a specific component based on the clientID parameter passed to addMessage method.
Global-Level Message :
These messages are not associated to any component and null is passed for clientID parameter to addMessage method.
Sample app can be download from here. Enjoy !!!
Tuesday, March 18, 2014
ADF Logging Explained Chapter 4
ADF Logging Explained Chapter 4
In this post, we tried to cover the commonly used methods of ADFLogger class.
Now I create ADFLogger instance and try to log a message using belowCode :
private static ADFLogger logger = ADFLogger.createADFLogger(TestLoggerTFBean.class);
logger.log("Logging Message1");
After running the application, I set the LogLevel of my custom ADFLogger to Warning. Now lets see the logged message ...it's not there. Why ? We created ADFLogger instance... logged the message ... set the LogLevel ... and no message Logged.
Almost all logging methods internally does a check isLoggable before logging. The above logger.log method checks isLoggable(ADFLoggerLevel.TRACE) and which return false because our custom ADFLogger's LogLevel is Warning.
Lesson Learnt : Information about internal LogLevel check is required before using any log method.
Well not to worry... other log methods are straight forward. Here are some examples :
logger.severe(String msg) - This checks isLoggable against Level.Severe.
logger.fine(String msg) - This checks isLoggable against Level.Fine.
logger.log(Level level, String msg) - This check isLoggable against inputParameter level before logging.
That's it. Enjoy logging.
If you want more than this, please go Adventures in Logging index by Duncan Mills.
Monday, March 10, 2014
ADF Logging Explained Chapter 3
ADF Logging Explained Chapter 3
This post illustrates ADFLogger initialization concepts.First thing you create the ADF Logger instance using below code :
private static ADFLogger logger = ADFLogger.createADFLogger(TestLoggerTFBean.class);
Log Level for newly Created Instance
I ask you a very simple question : Say you have not done any additional change to Oracle Diagnostic Logging. That is it looks like this :Now What is the logLevel for the above ADFLogger instance "logger" ?
Answer is LogLevel is null.
How isLoggable(Level level) check works on logger instance with LogLevel null ?
Ahh...Now we know that LogLevel is null for a newly created ADFLogger instance when it is not configured in OracleDiagnostic Logging. Wondering what will happen to code comparing LogLevel before logging any info ? Like :
if(logger.isLoggable(ADFLogger.INTERNAL_ERROR)){
logger.log("loggingBtnAction logger.isLoggable(ADFLogger.INTERNAL_ERROR) -> logger.log ");
}
Well ADFLogger is based on java.util.logging.Logger and isLoggable method works on class variable levelValue [ private volatile int levelValue ] defined in java.util.logging.Logger . When a new ADFLogger instance is created, levelValue variable is update using the below logic :
So if LogLevel for logger is null it means that logLevel is inherited from the parent. As the logger build a tree, it picks the logLevel of parent till it reaches the logger which returns a level not null.
From java.util.logging.Logger
private volatile int levelValue; // current effective level value
Thanks to Timo Hahn for clarifying this on https://community.oracle.com/thread/3524267
Thursday, March 6, 2014
ADF Logging Explained Chapter 2
Logging in ADF Application
For ADF Logging Explained Chapter 1, click here. This post describes Logging Levels.
Why there is need to learn Logging levels ?
When adding logger to Oracle Diagnostic Logging, there is option to define the loggingLevel for that Logger. Switching the logging Level in Oracle Diagnostic Logging for our custom Logger, you can control the level of details logged. Too much of logging can also cause performance issue. Decision of logging an information is taken based on the intValue comparision ( more details explained in later section ).
A logging Level is defined using name,intValue and resourceBundleName. The resource bundle name to be used in localizing the level name so for now we will focus on name and intValue. There are some predefined Levels mentioned in java.util.logging.Level class.
LOG LEVEL | NAME | INT VALUE |
OFF | OFF | INTEGER.MAX_VALUE |
SEVERE | SEVERE | 1000 |
WARNING | WARNING | 900 |
INFO | INFO | 800 |
CONFIG | CONFIG | 700 |
FINE | FINE | 500 |
FINER | FINER | 400 |
FINEST | FINEST | 300 |
ALL | ALL | Integer.MIN_VALUE |
Other logging Level types are custom levels defined using java.util.logging.Level with new name and API.
Logging Levels defined in ADFLogger :
LOG LEVEL | NAME | INT VALUE |
INTERNAL_ERROR | INTERNAL_ERROR | 1100 |
ERROR | SEVERE | 1000 |
WARNING | WARNING | 900 |
NOTIFICATION | INFO | 800 |
TRACE | FINE | 500 |
Other Logging Levels :
A) ODL Log Level
B) JAVA Log Level
C) Weblogic Server
Here is detailed list of different logging levels and there comparision :
ODL | WebLogic Server | Java |
OFF | OFF | 2147483647 - OFF |
INCIDENT_ERROR:1 | (EMERGENCY) | 1100 |
INCIDENT_ERROR:4 | EMERGENCY | 1090 |
INCIDENT_ERROR:14 | ALERT | 1060 |
INCIDENT_ERROR:24 | CRITICAL | 1030 |
ERROR:1 | (ERROR) | 1000 - SEVERE |
ERROR:7 | ERROR | 980 |
WARNING:1 | WARNING | 900 - WARNING |
WARNING:7 | NOTICE | 880 |
NOTIFICATION:1 | INFO | 800 - INFO |
NOTIFICATION:16 | (DEBUG) | 700 - CONFIG |
TRACE:1 | (DEBUG) | 500 - FINE |
TRACE:1 | DEBUG | 495 |
TRACE:16 | (TRACE) | 400 - FINER |
TRACE:32 | (TRACE) | 300 - FINEST |
TRACE:32 | TRACE | 295 |
Now you know about different available logging Level Types and their values. It is very much clear from the level names ALL and OFF that more and more detailed logging will happen with decrease in logging level int Value.
ADF Logging Explained Chapter 1
Logging in ADF Application
This post talks about using ADFLogger in adf application. The ADFLogger is a logging mechanism which is built into the ADF framework. It is built on top of java.util.logging API.
Using ADFLogger :
To start with you need to define the ADFLogger instance in your class ... something like below code :public class TestLoggerTFBean {
public TestLoggerTFBean() {
super();
}
private static ADFLogger logger = ADFLogger.createADFLogger(TestLoggerTFBean.class);
There are additional methods available in ADFLogger API to create ADFLogger instance. For other methods please refer to ADFLogger JAVA API.
Where to View Available Loggers :
Run your integratedWeblogic server and choose "Configure Oracle Diagnostic Loggin" from Actions. You will able to see all available loggers in the logging.xml file.Registering your ADFLogger :
You can register your logger by clicking green plus "+" icon in right on logging.xml. You can choose to add transient (discarded at the end of session ) logger or persistent (stored in logging.xml) logger.
When you run your application, you might notice that logger gets registered as when it is initialised.
OR
When you run your application, you might notice that logger gets registered as when it is initialised.
In the sample app provided, there are two taskflows : 1) noLogger-tf 2)testLogger-tf . An ADFLogger instance in created in pageFlowScope managed bean for testLogger-tf. Running the TestLoggerPage.jspx loads the noLogger-tf ( Not ADFLogger instance created yet ). If you notice registered loggers, our custom logger "TestLoggerBean " is still not registered.
Click the button to navigate to testLogger-tf taskflow. Click button "Do Some Logging" to log something. Now again check available loggers and our custom logger is available.
Tuesday, February 18, 2014
Hide move all/remove all buttons from SelectManyShuttle component
In this post, I will share how to hide move_all / remove_all buttons using skinning. With no additional skinning SelectManyShuttle component looks like this :
Now to hide move_all / remove_all buttons, define a style class on shuttle component like this
Now add the below code to your skin file and you are done.
New look for Shuttle component after skinning change :
Enjoy :)
Accessing Messages From Resource Bundle
Accessing Messages from Resource Bundle
1. Passing Parameters to Messaages from Resource Bundle in PageFragment
At times there are requirements to show messages like : 'Entered email Address "xyz@gmail.com" is not valid' .
There are different ways to achieve this:
a. Construct a Java message dynamically - not scalable
b. Return a Bean message - makes a trip to the bean everytime
c. Break the string to different strings and join them dynamically - Doesn't support internationalization
Correct way for implementing above would be :
1. Create an entry in resourceBundle of your application like this
EMAIL_ADDRESS_INVALID=Entered email Address {EMAIL_ADDRESS_TOKEN} is not valid.
2. Now use below tag to show message :
requiredMessageDetail="#{af:formatNamed(viewcontrollerBundle.EMAIL_ADDRESS_INVALID,'EMAIL_ADDRESS_TOKEN', pageFlowScope.EmployeeBean.emailAddress)}"
where emailAddress is a property in pageFlowScope EmployeeBean holding the value of EmailAddress.
EMAIL_ADDRESS_TOKEN is the parameter for which value is passed.
Note:
a. af:format, af:format1, af:format2, af:format3, af:format4 can be used to send parameters to the messages. The number in the af:format denotes the number of tokens it accepts
b. af:format can accept 1 parameter
2. Passing Parameters to Messages in Resource Bundle and accessing from Managed Bean
At times you write custom Validator method for input fields or do some other kind of validations in actionListener before calling service or calling commit. In case of some validation failure, it is common tendency to add error messages or return validation message from bean as a hardcoded String. For example see below code in custom Validator :
if (!matcher.matches()) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Entered email Address "+getEmailAddress()+" is not valid",null );
It is not good practice to use hardcoding for errorMessaage as String. Rather one should create entry in Resource Bundle and then fetch it in Bean for adding any validation message.
Steps to implement in correctly :
1. Create an entry in resourceBundle of your application like this
EMAIL_ADDRESS_INVALID=Entered email Address {EMAIL_ADDRESS_TOKEN} is not valid.
2. Create below methods in your utility class ( ADFUtils.java )
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import oracle.javatools.resourcebundle.BundleFactory;
import oracle.javatools.resourcebundle.NamedMessageFormat;
import javax.faces.context.FacesContext;
public static final String Missing_Resource_Msg = "No Message Found";
/**
* @param bundlePath
* @return
*/
private static ResourceBundle getBundle(String bundlePath) {
Locale locale =
FacesContext.getCurrentInstance().getViewRoot().getLocale();
return BundleFactory.getBundle(bundlePath, locale);
}
/**
* @param bundlePath
* @param messageKey
* @return
*/
public static String getStringFromBundle(String bundlePath,
String messageKey) {
ResourceBundle rsBundle = getBundle(bundlePath);
String bundleKeyValue;
try {
bundleKeyValue = rsBundle.getString(messageKey);
} catch (MissingResourceException mrExp) {
bundleKeyValue = Missing_Resource_Msg;
}
return bundleKeyValue;
}
/**
* @param bundlePath
* @param messageKey
* @param tokenMap
* @return
*/
public static String getStringFromBundle(String bundlePath,
String messageKey,
Map<String, Object> tokenMap) {
ResourceBundle rsBundle = getBundle(bundlePath);
String message;
try {
message = rsBundle.getString(messageKey);
} catch (MissingResourceException mrExp) {
message = Missing_Resource_Msg;
}
if (tokenMap != null && !tokenMap.isEmpty() &&
!Missing_Resource_Msg.equalsIgnoreCase(message))
message = NamedMessageFormat.formatMsg(message, tokenMap);
return message;
}
3. Now in you managedBean you can change your validation exception code like this :
private static final String bundlePath =
"test.rc.com.ViewControllerBundle";
Map tokenMap = new HashMap();
// Add a token with Key as token or parameter Name and value is the parameter Value
tokenMap.put("EMAIL_ADDRESS_TOKEN",getEmailAddress());
String errorMessage = ADFUtils.getStringFromBundle(bundlePath,
"EMAIL_ADDRESS_INVALID", tokenMap);
// errorMessage String is retrieved from Resource Bundle and passing parameter in Message
if (!matcher.matches()) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
errorMessage ,null );
That's it.. We are done ....Enjoy
Subscribe to:
Posts (Atom)