Canceling an edit form with ADF requires more than just setting the immediate property to true on the command button. It requires some cleaning up of the changes performed on the ADF binding layer.
After navigating to the edit form, the user starts modifying the form data and then decides to forget about
the changes. So he presses the cancel button of the edit form in which case the ADF Faces RC response
might be as shown below
There are two issues here:
i) The user didn't provided all the required field values before pressing "cancel"
and
ii) a new record has been created in the ADF iterator binding, which awaits clean up
Since the edit form is used for new records and existing records, we need to know about the row state. If
the edited row is new then the clean-up process needs to remove it from the ADF binding and if it is an
existing row, we want to refresh it to its old state.
First, create the RowImpl and Impl classes of your view object like shown below:
Open the ViewImpl class in the Java code editor and add the following code:
The longer part of the code is to translate the row state, which is read from the entity, from byte to String.
The getRowStatus method is defined as public so it can be exposed on the ViewObject as a client method.
This step makes the method available in the ADF binding layer so it can be added as a method binding to
the pageDef file of the edit form.
Add a method binding to to the page definition of your page that contains the form and make it point to getRowStatus method.
On the view layer there are three things to do:
i) set immediate=true on the cancel button so client validation is bypassed,
ii)add and reference an action listener in a managed bean to clean up the
modifications,
iii) and navigate back to the browse page.
The managed bean code access the getRowStatus method that is exposed on the binding to determine
whether or not the row is new or an existing row. Based on the returned information, the row then is
either refreshed or removed before navigation continues to the browse page
You can download this sample from the link below: (it uses the HR demo schema which you can find an sql file here)
The problem is based on a simple usecase: A user enters a page to either create a new record or update an
existing record.
After navigating to the edit form, the user starts modifying the form data and then decides to forget about
the changes. So he presses the cancel button of the edit form in which case the ADF Faces RC response
might be as shown below
There are two issues here:
i) The user didn't provided all the required field values before pressing "cancel"
and
ii) a new record has been created in the ADF iterator binding, which awaits clean up
Since the edit form is used for new records and existing records, we need to know about the row state. If
the edited row is new then the clean-up process needs to remove it from the ADF binding and if it is an
existing row, we want to refresh it to its old state.
First, create the RowImpl and Impl classes of your view object like shown below:
Open the ViewImpl class in the Java code editor and add the following code:
public String getRowStatus(Row row){
DepartmentsViewRowImpl rwImpl = (DepartmentsViewRowImpl)row;
String rwStatus = translateStatusToString(rwImpl.getEntity(0).getEntityState());
return rwStatus;
}
private String translateStatusToString(byte b) {
String ret = null;
switch (b) {
case Entity.STATUS_INITIALIZED: {
ret = "Initialized";
break;
}
case Entity.STATUS_MODIFIED: {
ret = "Modified";
break;
}
case Entity.STATUS_UNMODIFIED: {
ret = "Unmodified";
break;
}
case Entity.STATUS_NEW: {
ret = "New";
break;
}
}
return ret;
}
The longer part of the code is to translate the row state, which is read from the entity, from byte to String.
The getRowStatus method is defined as public so it can be exposed on the ViewObject as a client method.
This step makes the method available in the ADF binding layer so it can be added as a method binding to
the pageDef file of the edit form.
Add a method binding to to the page definition of your page that contains the form and make it point to getRowStatus method.
On the view layer there are three things to do:
i) set immediate=true on the cancel button so client validation is bypassed,
ii)add and reference an action listener in a managed bean to clean up the
modifications,
iii) and navigate back to the browse page.
The managed bean code access the getRowStatus method that is exposed on the binding to determine
whether or not the row is new or an existing row. Based on the returned information, the row then is
either refreshed or removed before navigation continues to the browse page
public void onCancel(ActionEvent actionEvent) {And this is it. Don't forget to set "immediate=true" on the cancel button.
FacesContext fctx = FacesContext.getCurrentInstance();
ELContext elctx = fctx.getELContext();
ExpressionFactory fact = fctx.getApplication().getExpressionFactory();
ValueExpression ve = fact.createValueExpression(elctx,"#{bindings}",Object.class);
DCBindingContainer bindings = (DCBindingContainer) ve.getValue(elctx);
DCIteratorBinding iter = bindings.findIteratorBinding("DepartmentsView1Iterator");
Row rw = iter.getCurrentRow();
OperationBinding getRowStatusBinding = bindings.getOperationBinding("getRowStatus");
String rwStatus = (String)getRowStatusBinding.execute();
if ("NEW".equalsIgnoreCase(rwStatus)){
iter.removeCurrentRow();
iter.refreshIfNeeded();
}
else{
rw.refresh(Row.REFRESH_UNDO_CHANGES);
}
fctx.renderResponse();
}
You can download this sample from the link below: (it uses the HR demo schema which you can find an sql file here)





