Recently I have seen a question on OTN JDeveloper forum and It was about table selection listener
The requirement is like this suppose the user has to check a condition after selecting a row and if that condition is true only then the new row will be selected else selected row should be the previous one
It means undo row selection on validation(condition) failure
So In this post, I am implementing the same scenario and here I am using Departments table of HR Schema to prepare model and condition is that user should be able to select new row only if ManagerId is not null
Drop Departments view object on page as af:table and create a custom selection listener in the managed bean
<af:table value="#{bindings.DepartmentsVO1.collectionModel}" var="row" rows="#{bindings.DepartmentsVO1.rangeSize}" emptyText="#{bindings.DepartmentsVO1.viewable ? 'No data to display.' : 'Access Denied.'}" rowBandingInterval="0" selectedRowKeys="#{bindings.DepartmentsVO1.collectionModel.selectedRow}" rowSelection="single" fetchSize="#{bindings.DepartmentsVO1.rangeSize}" filterModel="#{bindings.DepartmentsVO1Query.queryDescriptor}" queryListener="#{bindings.DepartmentsVO1Query.processQuery}" filterVisible="true" varStatus="vs" id="t1" autoHeightRows="10" styleClass="AFStretchWidth" contentDelivery="immediate" selectionListener="#{viewScope.TableSelectionBean.tableSelectionListener}"> <af:column sortProperty="#{bindings.DepartmentsVO1.hints.DepartmentId.name}" filterable="true" sortable="true" headerText="#{bindings.DepartmentsVO1.hints.DepartmentId.label}" id="c1"> <af:outputText value="#{row.DepartmentId}" shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentId.tooltip}" id="ot1"> <af:convertNumber groupingUsed="false" pattern="#{bindings.DepartmentsVO1.hints.DepartmentId.format}"/> </af:outputText> </af:column> <af:column sortProperty="#{bindings.DepartmentsVO1.hints.DepartmentName.name}" filterable="true" sortable="true" headerText="#{bindings.DepartmentsVO1.hints.DepartmentName.label}" id="c2"> <af:outputText value="#{row.DepartmentName}" shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentName.tooltip}" id="ot2"/> </af:column> <af:column sortProperty="#{bindings.DepartmentsVO1.hints.ManagerId.name}" filterable="true" sortable="true" headerText="#{bindings.DepartmentsVO1.hints.ManagerId.label}" id="c3"> <af:outputText value="#{row.ManagerId}" shortDesc="#{bindings.DepartmentsVO1.hints.ManagerId.tooltip}" id="ot3"> <af:convertNumber groupingUsed="false" pattern="#{bindings.DepartmentsVO1.hints.ManagerId.format}"/> </af:outputText> </af:column> <af:column sortProperty="#{bindings.DepartmentsVO1.hints.LocationId.name}" filterable="true" sortable="true" headerText="#{bindings.DepartmentsVO1.hints.LocationId.label}" id="c4"> <af:outputText value="#{row.LocationId}" shortDesc="#{bindings.DepartmentsVO1.hints.LocationId.tooltip}" id="ot4"> <af:convertNumber groupingUsed="false" pattern="#{bindings.DepartmentsVO1.hints.LocationId.format}"/> </af:outputText> </af:column> </af:table>
Now next step is implementing SelectionListener code so for that logic is simple
- First We need to get currently selected row key (Old Row)
- Set newly selected row as the current row
- Now get current row (new row) and check that ManagerId should not be null
- If it is null then set the previous row as the current row
Packages Used
import javax.el.ELContext; import javax.el.ExpressionFactory; import javax.el.MethodExpression; import javax.el.ValueExpression; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import oracle.adf.view.rich.component.rich.data.RichTable; import oracle.adf.view.rich.context.AdfFacesContext; import oracle.jbo.Row; import org.apache.myfaces.trinidad.event.SelectionEvent; import org.apache.myfaces.trinidad.model.RowKeySet;
Helper Methods
/** * Programmatic invocation of a method that an EL evaluates to. * The method must not take any parameters. * * @param el EL of the method to invoke * @return Object that the method returns */ public static Object invokeEL(String el) { return invokeEL(el, new Class[0], new Object[0]); } /** * Programmatic invocation of a method that an EL evaluates to. * * @param el EL of the method to invoke * @param paramTypes Array of Class defining the types of the parameters * @param params Array of Object defining the values of the parametrs * @return Object that the method returns */ public static Object invokeEL(String el, Class[] paramTypes, Object[] params) { FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory(); MethodExpression exp = expressionFactory.createMethodExpression(elContext, el, Object.class, paramTypes); return exp.invoke(elContext, params); } /** * Programmatic evaluation of EL. * @param el EL to evaluate * @return Result of the evaluation */ public static Object evaluateEL(String el) { FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory(); ValueExpression exp = expressionFactory.createValueExpression(elContext, el, Object.class); return exp.getValue(elContext); }
SelectionListener of af:table
/**Method to invoke custom selection listener * @param selectionEvent */ public void tableSelectionListener(SelectionEvent selectionEvent) { //Get previous selected row key RowKeySet oldRowKey = selectionEvent.getRemovedSet(); //Get Richtable instance fron selectionEvent RichTable table = (RichTable) selectionEvent.getSource(); //Invoke this EL to make selected row as current invokeEL("#{bindings.DepartmentsVO1.collectionModel.makeCurrent}", new Class[] { SelectionEvent.class }, new Object[] { selectionEvent }); // Get the selected row , by this you can get any attribute of that row Row selectedRow = (Row) evaluateEL("#{bindings.DepartmentsVO1Iterator.currentRow}"); System.out.println("Selected Deaprtment is- " + selectedRow.getAttribute("DepartmentName")); //Now check condition that Manager Id should not be null for newly selected row if (selectedRow.getAttribute("ManagerId") == null) { //If Manager Id is null then set focus on previously selected row and show a message to user table.setSelectedRowKeys(oldRowKey); //Refresh table AdfFacesContext.getCurrentInstance().addPartialTarget(table); //Show FacesMessage FacesContext fctx = FacesContext.getCurrentInstance(); fctx.addMessage(null, new FacesMessage("Can't Select new row as Manager Id is null")); //Save and render response fctx.renderResponse(); } }
Now run and check application
Try to select a Department that has no manager
Cheers 🙂 Happy Learning
Working like a charm
Thanks
I Was looking for this
Thanks a lot Ashish
Hello sir, I'm Chandan and I follow your blog and on Quora..The contents you post are very useful.
After around two months of preparation I took 1z0-554 certification but I couldn't clear it.anyhow I'm again taking the exam.
I've some set of questions which I'm trying to find answers that appeared in the exam.
If possible please give me your mail id and I'll send the questions.if you give me the solutions for it, It'll be very useful..My mail id chandanhs77@gmail.com
Nice Blog.Thank you for Sharing. I'm working in erp software solution in chennaiwe are leading cloud erp software solution in chennai
Nice post,thanks for giving this post this is very useful to every one and like this types also good explanation.thank you