Recently I have seen a question on OTN Jdeveloper forum and It was about table selection listener
Requirement is like this suppose user has to check a condition after selecting a row and if that condition is true only then new row will be selected else selected row should be previous one
It means undo row selection on validation(condition) failure
So In this post I am implementing 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 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 current row
- Now get current row (new row) and check that ManagerId should not be null
- If it is null then set prevous row as 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 Departmentthat has no manager
Cheers :) Happy Learning
Working like a charm
ReplyDeleteThanks
I Was looking for this
ReplyDeleteThanks a lot Ashish
Hello sir, I'm Chandan and I follow your blog and on Quora..The contents you post are very useful.
ReplyDeleteAfter 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