Sunday, 3 December 2017

Oracle ADF SelectOne Choice Values Refresh and Display View Objects rows.

Oracle ADF SelectOne Choice Values Refresh and Display View Objects rows


public void printCoutries(){
        ViewObjectImpl vo = getCountryEOView1();
        RowSetIterator iter =  vo.createRowSetIterator(null);
        while(iter.hasNext()){
            Row r = iter.next();
            System.out.println(r.getAttribute("CountryName"));
        }
        iter.closeRowSetIterator();
    }


BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding iter= (DCIteratorBinding) bindings.get("EmployeeIterator");
iter.executeQuery();


How to get ViewObject and RowImpl class in Backing bean using DCIteratorBindings in ADF ?

Below blog explains about how to get View Object and Row Impl class in backing bean using DCIteratorBindings

import oracle.adf.model.binding.DCIteratorBinding;

    /**
     * Find an iterator binding in the current binding container by name.
     *
     * @param name iterator binding name
     * @return iterator binding
     */
    public static DCIteratorBinding findIterator(String name) {
        DCIteratorBinding iter = getBindingContainer().findIteratorBinding(name);
           return iter;
    }


    public static BindingContainer getBindingContainer() {
        return (BindingContainer)JSFUtils.resolveExpression("#{bindings}");
    }
Example how to use

Get the Row Impl class in Backing bean, Ensure 'EmployeeViewIterator' must be available in page definition bindings.

        EmployeeViewRowImpl empRow =
            (EmployeeViewRowImpl )findIterator("EmployeeViewIterator").getCurrentRow();


Below code sample shows how to get View Object instance in backing bean using DIteratorBindings, Ensure 'EmployeeViewIterator' must be available in corresponding page definition bindings
        ViewObject agreementLocationViewObject =
            findIterator("EmployeeViewIterator").getViewObject();
public String executeWithParam() {
        String name = null;
        
        name = it1.getValue().toString();
        
        BindingContainer bindings = getBindings();
        OperationBinding operationBinding = bindings.getOperationBinding("ExecuteWithParams");
        operationBinding.getParamsMap().put("studentName", name);
        
        Object result = operationBinding.execute();
        if (!operationBinding.getErrors().isEmpty()) {
            return null;
        }
        return null;
    }






Assume we have a Model-Driven List for Deptno attribute with the display value of Dname and selectOneChoice bound to Deptno attribute in jspx page
<af:selectOneChoice value="#{bindings.Deptno.inputValue}" label="Select Department"
                            required="true" shortDesc="#{bindings.Deptno.hints.tooltip}"
                            id="soc1" autoSubmit="true">
          <f:selectItems value="#{bindings.Deptno.items}" id="si1"/>
</af:selectOneChoice>
When we want the selected value, the common mistake we do is to use the same EL bound to the value property of SelectOneChoice component, but using this we get the index of the selected item instead rather than the value. This is because when we drag and drop attribute as SelectOneChoice on to the page, SelectItems gets generated with indexes as values.
Displaying selected value on to the jspx page
In this section, we see how to get selected value without writing single line of java code. Create an outputText component with its value property bound to #{bindings.Deptno.attributeValue} instead of #{bindings.Deptno.inputValue} and make it refreshable based on list selection by adding partialTriggers property.
<af:outputText value = "Selected Value: #{bindings.Deptno.attributeValue}" id="ot1" partialTriggers="soc1"/>
The above code gives the Deptno value of the selected item. If the Deptno of 'SALES' is 30, 30 will get displayed on outputText on selecting 'SALES' from the list.
If we want 'SALES' itself to be displayed then the following EL should be used assuming Dname is the second attribute DeptView
<af:outputText value = "Display Value: #{bindings.Deptno.selectedValue ne ' ' ? bindings.Deptno.selectedValue.attributeValues[1] : ''}" id="ot2" partialTriggers="soc1"/>
Inside value change listener
Evaluating above EL expressions inside ValueChangeListener doesn't give the current selected value instead gives the previously selected value as the selected value doesn't get updated to the model by the time ValueChangeListener gets invoked.
In this case, before accessing the selected value, we need to update the model first.
Here is the sample code:
public void valueChanged(ValueChangeEvent valueChangeEvent) {
    this.setValueToEL("#{bindings.Deptno.inputValue}", valueChangeEvent.getNewValue()); //Updates the model
    System.out.println("\n******** Selected Value: "+resolveExpression("#{bindings.Deptno.attributeValue}"));
    System.out.println("\n******** Display Value: "+resolveExpression("#{bindings.Deptno.selectedValue ne ' ' ? bindings.Deptno.selectedValue.attributeValues[1] : ''}"));
}
 
public Object resolveExpression(String el) {      
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    ExpressionFactory expressionFactory =  facesContext.getApplication().getExpressionFactory();        
    ValueExpression valueExp = expressionFactory.createValueExpression(elContext,el,Object.class);
    return valueExp.getValue(elContext);
}
 
public void setValueToEL(String el, Object val) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    ExpressionFactory expressionFactory =   facesContext.getApplication().getExpressionFactory();
    ValueExpression exp = expressionFactory.createValueExpression(elContext, el, Object.class);
    exp.setValue(elContext, val);
}



ADF LOV reset the values.
ADF Lov valu can be reset as below (Lov default value set to null) .

UI component


<af:selectOneChoice value="#{bindings.BILLING_CITY.inputValue}"
                              label="#{bindings.BILLING_CITY.label}"
                              shortDesc="#{bindings.BILLING_CITY.hints.tooltip}"
                              id="BILLING_CITY1Id" autoSubmit="true"
                              binding="#{pageFlowScope.xxxBean.billingPostalCode}"
                              showRequired="true">
            <f:selectItems value="#{bindings.BILLING_CITY.items}"
                           id="selectItems1"/>
</af:selectOneChoice>

Bean

setEL("#{bindings.BILLING_CITY.inputValue}",null);


public static void setEL(String el, Object val) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory =
            facesContext.getApplication().getExpressionFactory();
        ValueExpression exp =
            expressionFactory.createValueExpression(elContext, el,
                                                    Object.class);

        exp.setValue(elContext, val);
    }





public Integer getLoc(Integer EmpId){
        Integer sal = null;
        Row[] row_2 = this.getEmployee1().getFilteredRows("EmployeeId", EmpId);
        if(row_2.length>0){
            sal = Integer.parseInt(row_2[0].getAttribute("Salary").toString());
        }
        return sal;
    }
    public void fetchSalary(ActionEvent actionEvent) {
        OperationBinding binding = getBindings().getOperationBinding("getLoc");
        // to put parameters value in the method
        binding.getParamsMap().put("EmpId", empId);
        Object execute = binding.execute();
        salary  = (Integer) execute;
    }
===========

public void onValueChanged(ValueChangeEvent ev){
  BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
  DCIteratorBinding iterBind = (DCIteratorBinding)bindings.get("MpStavkeulazaView5Iterator");
  System.out.println("Vrijednost je" + ev.getNewValue());
  ev.processUpdates(FacesContext.getCurrentInstance());
  Row row = iterBind.getCurrentRow();
  System.out.println("Proizvod: " + row.getAttribute("Proizvod"));
  System.out.println("Jmjere: " + row.getAttribute("Jmjere"));
}

====================

get selected row attributes from listofvaluesmodel inputComboboxListOfValues

Consider a case where you have configured an LOV for a VO attribute and you want to access all attributes of the LOV selected row say to display additional information about the selected LOV row. The problem here is that the list returned by the LOV binding in the bean code does not provide the selected row, returns null. Here is how you can access the row.

I have a CountryId in LocationVO that is configured as LOV using CountryVO.

1. I drag and drop LocationVO.CountryId as LOV on my jspx. The following code is added into my jspx
<af:inputComboboxListOfValues id="countryId"
popupTitle="Search and Select: #{bindings.CountryId.hints.label}"
value="#{bindings.CountryId.inputValue}"
label="#{bindings.CountryId.hints.label}"
model="#{bindings.CountryId.listOfValuesModel}"
required="#{bindings.CountryId.hints.mandatory}"
columns="#{bindings.CountryId.hints.displayWidth}"
shortDesc="#{bindings.CountryId.hints.tooltip}">
<f:validator binding="#{bindings.CountryId.validator}"/>
</af:inputComboboxListOfValues>


2. The page definition for this LOV looks like this

<list IterBinding="LocationsView1Iterator" StaticList="false" Uses="LOV_CountryId" id="CountryId"
DTSupportsMRU="true" SelectItemValueMode="ListObject"/>


3. Set autoSubmit to true for the component.

4. Set a value change listener as valueChangeListener="#{viewScope.MyBean.valueChanged}" where MyBean is your bean name.

5. Code your valueChanged() method as below.
public void valueChanged(ValueChangeEvent valueChangeEvent)
{
    BindingContext bctx = BindingContext.getCurrent();
    BindingContainer bindings = bctx.getCurrentBindingsEntry();
    JUCtrlListBinding list = (JUCtrlListBinding) bindings.get("CountryId");       
    String selectedValue = (String)list.getAttributeValue();   
    list.getListIterBinding().setCurrentRowWithKeyValue(selectedValue);
    Row currRow = list.getListIterBinding().getCurrentRow(); // THIS IS WHAT WE WANTED, the CountryVORow.
}

How to use findByKey() in ADF

Subject : 

   To find a specific row from a Row Set Iterator using findByKey() and setting the row as a current Row to a specific view object

Solution#1 - To get a specific row in Application Module Impl class


//Primary key value , Specify the data type accordingly
    String empID= "EMP001";
 
    // 1. Get the View Object instance
       EmployeeVO empVO = getEmployeeVO();

    // 2. Create a Key object
    Key key = new Key(new Object[] { empID });
 
    //3. Get the RowSetIterator Object
    RowSetIterator rsi = empVO.createRowSetIterator(null);
 
    //4. Find the row in the Iterator using findByKey funtion by passing Key object
    Row row = rsi.findByKey(key, 1)[0];
 
   // 6. Set the Current row in Iterator (findByKey does not Navigate to current row)
    rsi.setCurrentRow(row);


Solution#2 - To get a specific row in Managed Bean


//Primary key value , Specify the data type accordingly
    String empID= "EMP001";
 
    // 1. Access the binding container
    DCBindingContainer bc = (DCBindingContainer)getBindings();

   // 2. Find a named iterator binding
    DCIteratorBinding iter =
      (DCIteratorBinding)bc.findIteratorBinding("EmployeeVOIterator");

    // 3. Create a Key object
    Key key = new Key(new Object[] { empID});
 
    //4. Get the RowSetIterator Object
    RowSetIterator rsi = iter.getRowSetIterator();
 
    //5. Find the row in the Iterator using findByKey funtion by passing Key object
    Row row = rsi.findByKey(key, 1)[0];
 
   // 6. Set the Current row in Iterator (findByKey does not Navigate to current row)
    rsi.setCurrentRow(row); 
How To Get Application Module From Your BackingBean

There are two ways to generate application module from your backnigbean:

1- Get application module from iterator:
BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding dciter = (DCIteratorBinding)bindings.get("YourView1Iterator");
ApplicationModule am=dciter.getViewObject().getApplicationModule();
--------------------------------------------------------------
2- ApplicationModule am = this.getAm();
private ApplicationModule getAm() {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = fc.getELContext();
ValueExpression valueExp =
elFactory.createValueExpression(elContext, "#{data.AppModuleDataControl.dataProvider}",
Object.class);
return (ApplicationModule )valueExp.getValue(elContext);
}



Different ways of getting Handle to AM from Backing Bean
Method 1 : (Note : ValueBinding is deprecated in 11g)
// 1. Create a value binding
// 2. Access the binding container
// 3. Find the data control using #data binding.
// 4. Access the data control's application module data provider

ValueBinding vb=fctx.getApplication().createValueBinding(); 

BindingContext bc = (BindingContext)vb.getValue(fctx); 
DCDataControl dc =  bc.findDataControl("#{data}"); 
ApplicationModule am =(ApplicationModule)dc.getDataProvider(); 

Method 2 : (Typically used in a managed bean)

Configuration.createRootApplicationModule(MyAMDefn,AMConfig);
Configuration.releaseRootApplicationModule(,..);

Method 3 : (Typically used in a backing bean based on page iterators)

// 1. Access the binding container
// 2. Find a named iterator binding
// 3. Get the data control from the iterator binding
// 4. Access the data control's application module data provider


DCBindingContainer bc = (DCBindingContainer)getBindings();
DCIteratorBinding iter = bc.findIteratorBinding("MyVOIterator");
DCDataControl dc  = iter.getDataControl();
ApplicationModule am = (ApplicationModule)dc.getDataProvider();

Method 4 : (Typically used in a backing bean based on action binding)
// 1. Access the binding container
// 2. Find a named action binding
// 3. Get the data control from the iterator binding (or method binding)
// 4. Access the data control's application module data provider

DCBindingContainer bc = (DCBindingContainer)getBindings();

JUCtrlActionBinding action = (JUCtrlActionBinding)bc.findCtrlBinding("MyActionMethod");
DCDataControl dc = action.getDataControl();
ApplicationModule am = (ApplicationModule)dc.getDataProvider();

Method 5 : 
// 1. Access the binding context
// 2. Find data control by name
// 3. Access the data control's application module data provider
FacesContext fctx = FacesContext.getCurrentInstance();
BindingContext bindingContext = BindingContext.getCurrent();
DCDataControl dc = bindingContext.findDataControl("MyModuleDataControl");
MyAMImpl am = (MyAMImpl)dc.getDataProvider();

Method 6 :
//Using Value Expression.
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = fc.getELContext();
ValueExpression valueExp =elFactory.createValueExpression(elContext, "#{data.MyDataControl.dataProvider}",Object.class);
MyAMImpl am = (AmImpl)valueExp.getValue(elContext);

SelectOneChoice ValueChangeListener ProcessUpdates
When value is changed in selectonechoice and you have valuechangelistener associated with it, which has iterator and a variable which captures particular attribute but the problem is in valuechangelistener if you dont specify below line of code you will see that the values are not right (some old selection is captured) hence give this code in valuechangelistener.

valueChangeEvent.getComponent().processUpdates(FacesContext.getCurrentInstance());
e.g of complete method
public void PersonSelected(ValueChangeEvent valueChangeEvent) {

valueChangeEvent.getComponent().processUpdates(FacesContext.getCurrentInstance());
BindingContext bctx = BindingContext.getCurrent();
DCBindingContainer bindings = (DCBindingContainer)bctx.getCurrentBindingsEntry();
OperationBinding opr = (OperationBinding)bindings.getOperationBinding("AllFruitsEP");
Object result = opr.execute();
DCIteratorBinding allFruitsItr = bindings.findIteratorBinding("AllFruits1Iterator");
AttributeBinding personId = (AttributeBinding)bindings.getControlBinding("Personid");
System.out.println("Person ID:"+personId);
System.out.println("Iter size:"+ allFruitsItr.getViewObject().getRowCount());
if (!opr.getErrors().isEmpty()) {
System.out.println("ERROR");
}
}


No comments:

Post a Comment