Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label valueChangeListener. Show all posts
Showing posts with label valueChangeListener. Show all posts

Friday 20 May 2016

Navigate to another page on value change event of ADF input component

Recently I have seen a thread on OTN forum in that user want to navigate from one page to another on valueChangeListener of input component.

First Method-
This is a simple piece of code to perform navigation to specific page , Use it in ValueChangeListener directly

 FacesContext facesContext = FacesContext.getCurrentInstance();
 facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "controlFlowName");

Second Method-
ValueChangeListener fires when value of input component changes but it is not meant for navigation, For navigation we use buttons and links with Action property
But for this requirement we have to be a bit tricky, We can queue button Action on value change listener of inputText to navigate to another page
Now first value change listener will be executed and then it'll queue button action to execute and as final outcome user will be able to navigate

Tuesday 15 December 2015

Checkbox ValueChangeListener problem in af:table - ADF 12.1.3


Recently i faced a problem while working on one of my application, it has an editable table having one check box column and a valueChangeListener is defined on that check box.

Problem is that whenever user selects any row of table , valueChangeListener of check box is called every time for all editable rows, this is weird because VCL should execute only when user selects or deselects check box

Saturday 5 September 2015

Apply ValueChangeListener to programmatically created ADF Faces components

Again a post in series of  Working with ADF Faces Components programmatically
Previously i have posted about Getting value , Applying Action Listener , Applying Client/Server Listener, Creating and applying client Attributes, Setting value expression , Applying Validation to programmatically created component
Now this post post is about applying Value Change Listener to a component that is created at run time
See how to do this (Jdev 12.1.3)-
  • First created a FusionWebApplication and a page in viewController project
  • Dropped a button on page , on this button action i will create an inputText programmatically and assign Value Change Listener method reference to it
  • To create new inputText i have added following code (described in previous post)

Monday 22 September 2014

Invoke button action (ActionEvent) and value change listener using JavaScript- Oracle ADF

This is another post about using JavaScript in ADF Faces, So again nothing complicated just simple things but needed often
In this post i am covering two simple requirements , using Jdeveloper 11.1.2.4 (11g Release2)

1. How to call button action (ActionEvent) using JavaScript
2. How to call valueChangeListener of a component using JavaScript

 

Call button action using JavaScript-


So for this just drop a commandButton and an inputText on page and create a ActionListener in managed bean for button



Code in managed bean for ActionEvent-




    /**Action Listener for Button
     * @param actionEvent
     */
    public void buttonAction(ActionEvent actionEvent) {
        FacesMessage msg = new FacesMessage("Button Action called");
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, msg);
    }

Now requirement is to call this button action on double click event of mouse in inputText
To handle ActionEvent in JavaScript, framework provides a class AdfActionEvent , it has a method to queue ActionEvent from a component. So here i use same method to call ActionEvent

See JavaScript function-

function callButtonAction() {
                  //Method to get component using id (here button is top container)
                  var button = AdfPage.PAGE.findComponentByAbsoluteId('cb1');
                  //Method to queue ActionEvent from component
                  AdfActionEvent.queue(button, button.getPartialSubmit());
              }

and call it using af:clientListener under af:inputText-



Run page and check on double click of mouse in inputText-




Call ValueChangeListener using JavaScript-


This is also same as pervious one, created a valueChangeListener in managed bean for input text and requirement is to call this listener on mouse hover of button

Code in managed bean for ValueChangeListener-

    /**ValueChangeListener for inputText
     * @param valueChangeEvent
     */
    public void inputTextVCE(ValueChangeEvent valueChangeEvent) {
        FacesMessage msg = new FacesMessage("Value Change Lestener called");
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, msg);
    }

There is a class to handle valueChange event using JavaScript - AdfValueChangeEvent
So this class also has a queue method , the difference is this queue method takes 4 parameters and also requires a value change event on component
So first step is to change (set) value of field using JavaScript and then queue valueChangeEvent

See JavaScript function-


 function callValueChangeEvent(evt) {
                  //Method to get component using id (here inputText is top container)
                  var field = AdfPage.PAGE.findComponentByAbsoluteId('it1');
                  //Change(set) field's value
                  field.setValue('I am JavaScript text');
                  //Get New changed value
                  var newVal = field.getValue();
                  //Queue ValueChangeEvent (component,oldValue,newValue,autoSubmit)
                  AdfValueChangeEvent.queue(field, null, newVal, false);

              }

make sure that clientComponent and autoSubmit property of inputText set to true
call this javascript fucntion from button using af:clientListener


Run page and check it-
Thanks, Happy Learning


Monday 15 September 2014

Showing all values instead of 'All' text in selectManyChoice using JavaScript -Oracle ADF

Happy Engineer's Day :)
This post is about overriding default text for select all feature in af:selectManyChoice
af:selectManyChoice supports multiple selection in ADF Faces and framework provides a default feature to select all values of list but after selecting all value it doesn't show values ,only show a String 'All'.
Like this-
but sometimes it is not clear that what are the values by just seeing this 'All' text or it is a requirement to show all values (if there is not much data) instead of this default text



So in this post i am going to override this default text using JavaScript and this is a quick overview that how we can play with JavaScript and try it in ADF Faces
see previous posts on JavaScript in Oracle ADF-

Show message (Invoke FacesMessage) using JavaScript in ADF Faces
Launching browser print dialog using simple javascript function in ADF
Using JQuery in Oracle ADF

So in this implementation i am using Departments table (HR Schema -Oracle) and Jdeveloper 12C (12.1.3)
  • Prepare model using Departments table and drop viewObject on page as af:selectManyChoice


  • Now  see when we select one -two values , it appears on component but in case of all only that 'All' string appears


  • Here i am changing this text on valueChange event of selectManyChoice , so created a valueChangeListener in managed bean. 

  • See what i am going to do in this listener is -
    1. Get all selected values means DepartmentId
    2. Next is to get corresponding DepartmentName for DepartmentId 
    3. Add all DepartmentName into an String
    4. Call JavaScript method to set this String as value of selectManyChoice instead of 'All'

  • See code written in valueChangeListener , i have used enough comments to understand each line

  •     /**ValueChangeListener for SelectManyChoice (Executes Javascript to replace 'All' text)
         * @param vce
         */
        public void selectManyVCE(ValueChangeEvent vce) {
            //String to store all selected Departments Name
            String displayVal = "";
            //Get BindingContainer of current page
            BindingContext bctx = BindingContext.getCurrent();
            BindingContainer bindings = bctx.getCurrentBindingsEntry();
            //Get Iterator of SelectManyChoice
            DCIteratorBinding iter = (DCIteratorBinding) bindings.get("Departments1Iterator");
    
            if (vce.getNewValue() != null) {
                //Get all selected values in an Object array
                Object[] selectedVals = (Object[]) vce.getNewValue();
                //Iterate over array to get all selected DepartmentId
                for (int i = 0; i < selectedVals.length; i++) {
                    Integer val = (Integer) selectedVals[i];
                    //Create Key using DepartmentId to use furhter
                    Key key = new Key(new Object[] { val });
                    //Get ViewObject row using Key vlaue
                    Row row = iter.getViewObject().getRow(key);
                    // Get DepartmentName from row and add it to String
                    if (displayVal != "") {
                        displayVal = displayVal.concat(", ").concat(row.getAttribute("DepartmentName").toString());
                    } else {
                        displayVal = displayVal.concat(row.getAttribute("DepartmentName").toString());
                    }
                }
                //Write JavaScript code to change text of selectManyChoice as a StingBuilder Object
                StringBuilder jsString = new StringBuilder();
                //First Step-get clientID of component
                jsString.append("var elementId = '" + vce.getComponent().getClientId());
                //Second- add ::content to access it's value
                jsString.append("::content';");
                //Third- Check that current value is 'All' or not
                jsString.append("\n if (document.getElementById(elementId).value == 'All') {");
                //Forth- if yes then assign Department Name's string as value of selectManyChoice
                jsString.append("\n document.getElementById(elementId).value ='" + displayVal + "' \n};");
                System.out.println("JS File-" + jsString);
                //Call this JavaScript code using this Helper method
                writeJavaScriptToClient(jsString.toString());
    
            }
        }
    

    Method to call JavaScript from managed bean-

        /**Helper Method to call Javascript
         * @param javascriptCode
         */
        public static void writeJavaScriptToClient(String javascriptCode) {
            FacesContext facesCtx = FacesContext.getCurrentInstance();
            ExtendedRenderKitService service = Service.getRenderKitService(facesCtx, ExtendedRenderKitService.class);
            service.addScript(facesCtx, javascriptCode);
        }
    

    Import packages-

    import javax.faces.context.FacesContext;
    import javax.faces.event.ValueChangeEvent;
    
    import oracle.adf.model.BindingContext;
    import oracle.adf.model.binding.DCIteratorBinding;
    
    import oracle.binding.BindingContainer;
    
    import oracle.jbo.Key;
    import oracle.jbo.Row;
    
    import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
    import org.apache.myfaces.trinidad.util.Service;
    

  • Run application and check, on selecting all values it shows -


  • but this will happen only on value change event of selectManyChoice , you can call this JavaScript any time as per your requirement like on page load
Thanks , Happy Learning :-)

Monday 12 May 2014

Getting selected value (not index) & display value of select one choice programmatically in ADF

Hello All,
This post is about a common requirement of getting selected value & display value of af:selectOneChoice in managed bean
normally when we try to get selected value of  selectOneChoice in managed bean (in ValueChange/ Validator or using binding) it returns index of that row
so there is a little piece of code using that we can get selected value of choice component

  • I have used Departments table of HR Schema in sample and created a lov on a transient field


  • Now dropped that ViewObject on page as a table 


  • Created a value change listener in managed bean fro DeptIdTrans but it return index of selected value





  • Then i googled about it and used this method to solve my headache, try to get attributeValue instead of inputValue, see the code written in valueChaneListener in managed bean

  •     /**Value Change Listener of DeptIdTrans (to get selected and display value)
         * @param vce
         */
        public void deptIdVCE(ValueChangeEvent vce) {
            System.out.println("New Value is-" + vce.getNewValue());
            if (vce.getNewValue() != null) {
                this.setvalueToExpression("#{row.bindings.DeptIdTrans.inputValue}",
                                          vce.getNewValue()); //Updating Model Values
                Integer selectedCode =
                    Integer.parseInt(this.getValueFrmExpression("#{row.bindings.DeptIdTrans.attributeValue}").toString());
    
                System.out.println("******** Selected Value in List***** " + selectedCode);
                System.out.println("*******Display Value in List ****" +
                                   getValueFrmExpression("#{row.bindings.DeptIdTrans.selectedValue.attributeValues[1]}"));
    
            }
        }
    

  • There is two methods to set and get value in expression (EL)

  •     /**Method to set value in Expression (EL)
         * @param el
         * @param val
         */
        public void setvalueToExpression(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);
        }
    
        /**Method to get value from Expression (EL)
         * @param data
         * @return
         */
        public String getValueFrmExpression(String data) {
            FacesContext fc = FacesContext.getCurrentInstance();
            Application app = fc.getApplication();
            ExpressionFactory elFactory = app.getExpressionFactory();
            ELContext elContext = fc.getELContext();
            ValueExpression valueExp = elFactory.createValueExpression(elContext, data, Object.class);
            String Message = null;
            Object obj = valueExp.getValue(elContext);
            if (obj != null) {
                Message = obj.toString();
            }
            return Message;
        }
    

  • Again run page and select any value in selectOneChoice (lov) and see the result

Cheers :-) Happy Learning

Monday 7 April 2014

Get updated model values in value change listener instantly, ProcessUpdates in ADF (a beauty)

Hello All,

This posts talks about updating model instantly when a attribute is changed on page level.
In ValueChangeListener of component if we try to get new value from Model layer, it always returns old value, then we have only one option to get new value, use event object (evt.getNewValue();)
but sometimes we need to update model same time
So how to do this-

  • Created a Fusion Web Application using Departments table of HR Schema (Oracle)


  • Dropped Departments Vo on page as a form, and created ValueChangeListener on DepartmnetName field to get new value 





  • Now i have written a code to get DepartmentName from current row of Departments VO (ViewObject) and to get from ValueChangeEvent

  • Method in AMImpl- Called in ValueChangeListener through binding Layer

    /**Method to print Department Name */
        public void getDeptNameAction() {
            ViewObject depart = this.getDepartments1();
            Row curRow = depart.getCurrentRow();
            if (curRow != null) {
                System.out.println("Current Department from model is-" + curRow.getAttribute("DepartmentName"));
            }
        }
    


    Code in ValueChangeListener - AM Method Called and Code to get new value from event itself

        /**Value change listener for Department Name
         * @param vce
         */
        public void deptNmVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                System.out.println("New Value in VCE-" + vce.getNewValue());
                BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry();
                OperationBinding ob = bc.getOperationBinding("getDeptNameAction");
                ob.execute();
            }
        }
    

  • In this case when i have changed value on page 



  • see the result -output from valuechangelistener- Model layer returns old value :-(


  • Now to update value in Model layer , i have just called processUpdates in ValueChangeListener- See the code

  •     /**Value change listener for Department Name
         * @param vce
         */
        public void deptNmVCE(ValueChangeEvent vce) {
            if (vce.getNewValue() != null) {
                //Method to update Model in VCE
                vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
                System.out.println("New Value in VCE-" + vce.getNewValue());
                BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry();
                OperationBinding ob = bc.getOperationBinding("getDeptNameAction");
                ob.execute();
            }
        }
    

  • see the result -Value is updated in model instantly (in VCE)

so this is how processUpdates works, Cheers :-)
See one more post on this concept with different usecase- Update Model Values while Validation (Exception) occurs on page on Value Change event
Happy Learning

Monday 1 July 2013

Update Model Values while Validation (Exception) occurs on page on Value Change event- Oracle ADF (processUpdates)

In ADF when we have some validation on page and we try to submit any value, but normally after validation (Exception) values are not updated in Model until exception is handled.
This tutorial is about how to update values in Model while exception on page.
For a scenario, i have used department (default HR Schema) table and form in a JSP XML fragment inside bounded taskflow.
In form Department Id and Department Name is mandatory field, ManagerId and Location Id has auto submit true.
  • I have dropped createInsert,Execute,Commit and Rollback as buttons on page




  • Click on create button and first enter manager id, as this field has autosubmit true so on submission of value page is validated and then Required Fields throw exception, and after exception you can see that manager id & location id is not updated in Model, and not reflected in af:table also.


  •  Normally what we do, set immediate true to skip validations, but in this case i have witten ValueChangeListener on manager Id and Location Id to process values in Model.- see code

  •     public void mangrIdVCE(ValueChangeEvent vce) {
            vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
        }
    

  • processUpdates() method of UIComponent class perform the coponent tree processing for all facet of this component by Update Model Values phase of request processing, and pushes data to Model

  • Now after calling this method, run application- Now values are populated in af:table and validation is still there on page


  • this approach can be used while using validators on page and want to process some values after validation (as conditional validation of some fields etc)
  • Download sample application -Sample App

Thursday 11 April 2013

Invoking Button Action Programmatically,Queuing ActionEvent

Sometimes we need to invoke any button's action in bean without pressing that button,
as you have to call button action on any component's value change Listener- So how to do this in ADF managed bean.
ADF provides facility to queue action one after another, means you can perform multiple action by queuing 

I am using bounded task flow with page fragments(.jsff)-

  • Create a button in page fragment and define ActionListener in managed bean
  • Now I have created a input text and its valueChangeListener in managed bean
  • I wish to call button' ActionListener in my input text valueChangeListener .




  • we can do this by writing this code snippet on valueChangeListener 

  • public void callAceVCE(ValueChangeEvent vce) {
    if (vce.getNewValue() != null) {
    //Code to call ActionEvent
    FacesContext facesContext = FacesContext.getCurrentInstance();
    UIViewRoot root = facesContext.getViewRoot();
    /**Pass cb1(buttonId) if page is not in taskflow, else if page is inside region then pass rgionid:buttonId*/
    RichCommandButton button = (RichCommandButton)root.findComponent("r1:cb1");
    ActionEvent actionEvent = new ActionEvent(button);
    actionEvent.queue();
    }
    }

  •  Now run your page and when you will change input text value - button actionListener will be called