Passing parameters with method call

Viewed 58

I'm trying to pass a parameter by method cal in a bounded task between two pages: departments and employees, and I'm trying to make employees filter by departmentId. I have a criteria view on employees doing this filter with a Bind Variable vcDeptId and in java:

public void applyViewCriteria(int id)
{
  ViewCriteria vc = getViewCriteria("EmployeesViewFilterByDeptCriteria");
  setvcDepartmentId(id);
  applyViewCriteria(vc);
  executeQuery();
}

On the Departments page I have a table with a button that redirects to the method call:

public void filter()
{
  BindingContext bindingContext = BindingContext.getCurrent();
  DCDataControl dc = bindingContext.findDataControl("AppModuleDataControl");
  AppModuleImpl appM = (AppModuleImpl )dc.getDataProvider();
  Object id =appM.getDepartmentsView1().getCurrentRow().getAttribute("DepartmentId");
  appM.getEmployeesView2().applyViewCriteria(Integer.parseInt(id.toString()));
  System.err.println(id);
}

It turns out that when you go to the employees page, the table doesn't filter, it shows all employees from all departments. I can see in the console that I get the id but I can't do the filter. I don't understand what's missing.. Can someone help me, please??

2 Answers

Actually, you do the filter. However, you do it on a different instance of the view object (VO). When you get the VO from the application module, as you do, you get another fresh instance, not the one used for the table. The table shows data based on an interator binding from the pages pagedef file pageDef.xml the table on the page shows employees via the EmployeesView binding. Ths binding is based on the iterator binding EmployeesViewIterator in the executable section. the view object behind the iterator is the EmployeesView in the data control (or AM). To manipulate the data on the page, you need to get to the vo behind the iterator binding. For this, you can use code like

    BindingContainer lBindingContainer = BindingContext.getCurrent().getCurrentBindingsEntry();
    DCIteratorBinding iterBind= (DCIteratorBinding)lBindingContainer.get("EmployeesViewIterator");
    ViewObject empview = iterBind.getViewObject();

Now you have access to the right VO and can add the view criteria.

Here is a function to apply a viewCriteria using your generated iterator name ("EmployeesViewIterator") :

(https://cedricleruth.com/how-to-apply-a-viewcriteria-programmatically-in-adf/)

/**
 * Apply view criteria named MyViewCriteria to it's ViewObject
 * by getting it through the binding iterator MyViewObjectIterator
 */
public void applyViewCriteriaOnViewObjectByIteratorName(String MyViewCriteriaName, String MyViewObjectIteratorName) {
    try {
        //Get The viewObject from the iterator define in the current binding context
        ViewObject vo = this.getViewObjectFromIteratorName(MyViewObjectIteratorName)
        //Get all it's ViewCriteria using the ViewCriteriaManager of the ViewObject
        ViewCriteriaManager vcm = vo.getViewCriteriaManager();
        //Get the specified View Criteria
        ViewCriteria vc = vcm.getViewCriteria(MyViewCriteriaName);
        //Apply the ViewCriteria to the ViewObject
        vo.applyViewCriteria(vc);
        //Note: If you need to apply this view criteria on top of already applied view criteria
        //without removing them you can add the following boolean parameter : 
        //vo.applyViewCriteria(vc,true);
        
        //That's all you need if the iterator is set to be refresh after this
        //If not you can force the ViewObject to execute by uncommenting the following :
        //vo.executeQuery(); 
    } catch (NullPointerException e) {
        //Log and warn for null
        //Often occur when there is an error in the provided attributes 
        //(MyViewCriteriaName, MyViewObjectIteratorName)
    } catch (Exception e) {
        //Log and warn for other exceptions - Should never be needed
}
    
/**
 * Useful function to get ViewObject from IteratorName
 * The iterator need to have a least one binding define in the current page
 * In this gist it's a private but i advice setting it as a public static in an utility class available for the whole Controller
 */
 private ViewObject getViewObjectFromIteratorName(String MyViewObjectIteratorName) {
    ViewObject vo = null;
    try {
        DCBindingContainer bindings = (DCBindingContainer) BindingContext.getCurrent().getCurrentBindingsEntry();
        DCIteratorBinding iterator = bindings.findIteratorBinding(MyViewObjectIteratorName);
        vo = iterator.getViewObject();      
    } catch (NullPointerException e) {
        //Log and warn for null
        //Often occur when there is an error in the provided attributes 
        //or if the iterator doesn't have a least one binding define in the current page
    }
    return vo;
 }

If you need to set a bind variable before applying your view criteria use :

vcm.getVariableManager().setVariableValue("arg0", arg1);

Here is also an easier way to get your iterator value : (https://cedricleruth.com/how-to-retreive-the-value-of-an-iterator-binding-variable-programmatically-in-adf/)

//Here is how to simply retreive the value of and ADF Binding from the view El Expression :

//Below is a view example with values taken from an ADF View Object
<af:inputText id="it1" autoSubmit="true" value="#{bindings.YOUR_VO.YOUR_VO_ATTRIBUTE.inputValue}" />
<af:table value="#{bindings.YOUR_VO.collectionModel}" var="row">
   <af:column sortProperty="#{bindings.YOUR_VO.hints.YOUR_VO_ATTRIBUTE.name}"
               id="c1">
        <af:outputText value="#{row.YOUR_VO_ATTRIBUTE}" id="ot1"/>
    </af:column>
</af:table>

//Using below function you can easily get any of those value in your ADF Bean as follow : 
//Note: replace String by the correct type
String inputTextValue= (String)resolveExpression("#{bindings.YOUR_VO.YOUR_VO_ATTRIBUTE.inputValue}");
String currentRowValue= (String)resolveExpression("#{row.YOUR_VO_ATTRIBUTE}");

/**
 * Method for taking a reference to a JSF binding expression and returning
 * the matching object (or creating it).
 * @param expression EL expression
 * @return Managed object
 * @author : Duncan Mills, Steve Muench and Ric Smith's JSFUtils class
 */
public static Object resolveExpression(String expression) {
    FacesContext facesContext = getFacesContext();
    Application app = facesContext.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    ELContext elContext = facesContext.getELContext();
    ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
    return valueExp.getValue(elContext);
}
Related