Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label af:button. Show all posts
Showing posts with label af:button. Show all posts

Friday, 30 November 2018

Switching ADF Skin at run time using trinidad-config.xml

 This post talks about switching ADF skin at runtime and uses a managed bean variable to change skin name at runtime. Sometimes we want to use multiple themes for our application and in that case, we need this.

Created an ADF application, 2 different skins and a page in view controller project


Learn more about creating ADF skin in JDeveloper 

This page has a button to switch between skins and an outputText. Create a variable in the managed bean to hold skin name and button action listener to change skin variable value.

Here goes the managed bean code

  1. package switchadfskin.view.bean;
  2. import javax.faces.application.ViewHandler;
  3. import javax.faces.component.UIViewRoot;
  4. import javax.faces.context.FacesContext;
  5. import javax.faces.event.ActionEvent;
  6. public class SwitchADFSkinBean {
  7. public SwitchADFSkinBean() {
  8. }
  9. //Set default skin name
  10. private String skinName = "RedButton";
  11. public void setSkinName(String skinName) {
  12. this.skinName = skinName;
  13. }
  14. public String getSkinName() {
  15. return skinName;
  16. }
  17. /**Method to change skin at runtime
  18. * @param actionEvent
  19. */
  20. public void switchSkinAction(ActionEvent actionEvent) {
  21. //Change skin name
  22. if (skinName.equalsIgnoreCase("RedButton")) {
  23. this.setSkinName("GreenButton");
  24. } else {
  25. this.setSkinName("RedButton");
  26. }
  27. //Reload page
  28. refreshPage();
  29. }
  30. /**Method to refresh/reload page
  31. */
  32. protected void refreshPage() {
  33. FacesContext fctx = FacesContext.getCurrentInstance();
  34. String page = fctx.getViewRoot().getViewId();
  35. ViewHandler ViewH = fctx.getApplication().getViewHandler();
  36. UIViewRoot UIV = ViewH.createView(fctx, page);
  37. UIV.setViewId(page);
  38. fctx.setViewRoot(UIV);
  39. }
  40. }

The next step is to change the trinidad-config.xml file, set skin-family variable to refer to its value from managed bean so that when the user changes the bean variable then skin (CSS) is updated in the application.

  1. <?xml version="1.0" encoding="windows-1252"?>
  2. <trinidad-config xmlns="http://myfaces.apache.org/trinidad/config">
  3. <skin-family>#{SwitchADFSkinBean.skinName}</skin-family>
  4. </trinidad-config>

Now run and check application

The default skin is "RedButton" so it looks like this


and on click of the button

Sample ADF Application (JDeveloper 12.1.3) - Download

Cheers 🙂 Happy Learning

Monday, 15 February 2016

Show live progress of a long running task using af:progressIndicator in Oracle ADF

This post is about using af:progressIndicator to show live status of a particular task
af:progressIndicator state is tracked and maintained by it's value property that supports org.apache.myfaces.trinidad.model.BoundedRangeModel
This class has two methods

public abstract long getMaximum() { }
returns Maximum value for Model

public abstract long getValue() { }
returns value for Model (current state)

Now to see live progress on page we have to refresh progressIndicator component periodically and this can be achieved using af:poll component , poll component delivers poll events to server periodically and we can ppr (refresh) progress indicator after a particular interval

Friday, 28 August 2015

ADF Basics: Using setPropertyListener to set value in memory scope variables

Soemtimes we need to set a value in memory scope variable on some event
In ADF af:setPropertyListener does this for you declaratively

The setPropertyListener tag provides a declarative syntax for assigning values when an event fires. The setPropertyListener implements the listener interface for a variety of events, to indicate which event type it should listen for set the 'type' attribute.

Read more about <af:setPropertyListener>

Saturday, 16 May 2015

Apply ActionListener to programmatically created buttons/link in ADF


This post is next in series of "Working with ADF Faces Components programmatically"
Previous posts are-
Creating dynamic layout (form and UI Component) using ADF Faces
Get Value from programmatically created components , Iterate over parent component to get child values in ADF Faces

Now this post is about applying ActionListener to a programmatically created button or link
Let's start (Jdev 12.13) -

  • First created a FusionWebApplication and a page in viewController project
  • Dropped a button on page , on this button action i will create a link programmatically and assign actionListener to it
  • To create new link i have added following code (described in previous posts)



  •     /**Method to add dynamically created component to a parent layout
         * @param parentUIComponent
         * @param childUIComponent
         */
        public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
            parentUIComponent.getChildren().add(childUIComponent);
            AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
        }
    

           //Creating Link programmatically on button click     
            RichLink ui = new RichLink();
            ui.setId("li1");
            ui.setText("Programmatically Created Link");
            ui.setInlineStyle("font-weight:bold;");
            //Add this link to parent form layout
     //ParentGroupLayoutBind is the component binding of panelGroupLayout
            addComponent(getParentGroupLayoutBind(), ui);
    

  • After this we are able to create a new Link on click of button, now next is to assign ActionListener to this Link
    For this first i have to define an ActionListener method in bean. So i have added this 

  •     /**Action Listener to be applied on dynamically created button
         * @param actionEvent
         */
        public void actionForProgLink(ActionEvent actionEvent) {
            FacesMessage infoMsg = new FacesMessage("Action Listener Invoked");
            infoMsg.setSeverity(FacesMessage.SEVERITY_INFO);
            FacesContext.getCurrentInstance().addMessage(null, infoMsg);
        }
    

  • Now how to assign this ActionListener to that dynamically created Link?
    See the Code-

  •     /**Method to to resolve actionListener
         * @param actionName
         */
        private ActionListener getActionListener(String actionName) {
            //here Testbean is the name of ManagedBean
            MethodExpression methodExp = getMethodExpressionForAction("#{viewScope.Testbean." + actionName + "}");
            return new MethodExpressionActionListener(methodExp);
        }
    

    Helper method to resolve ActionListener-

        private MethodExpression getMethodExpressionForAction(String actionName) {
            Class[] argtypes = new Class[1];
            argtypes[0] = ActionEvent.class;
    
            FacesContext facesCtx = FacesContext.getCurrentInstance();
            Application app = facesCtx.getApplication();
            ExpressionFactory elFactory = app.getExpressionFactory();
            ELContext elContext = facesCtx.getELContext();
            return elFactory.createMethodExpression(elContext, actionName, null, argtypes);
        }
    

    Just pass the name of method to resolve it

       //Apply ActionListener on this dynamically created link 
        ui.addActionListener(getActionListener("actionForProgLink")); 
     
Now time to check , run application :)
First a button appears-


On click of this button a link is created -

Click on this link- programmatically assigned Action Listener is called

Cheers , Happy Learning :)

Monday, 4 May 2015

ADF Skinning : Change color and style of af:query buttons in ADF Faces (Jdev 12.1.3)

Hello All,

This is another post about ADF Skinning , in this post i am going to show you that how can we change button's style in af:query component
Actually this is very easy , if we define some styles for af:button component in our css file then it will be applicable on af:query's buttons (Search, Reset, Advanced, Save etc) too

Suppose i have defined this in css file

af|button{
    color:navy;
    font-weight:bold;
}
 

Now it will change color of all buttons of application including af:query
See this snap after applying this skin




But if you have a requirement to use different style in af:query buttons or you don't want to change color of all buttons
Then it is not that much easy as it seems

There is a selector to style buttons of af:query - af|query::button 
But this works only if buttons are af:commandButton not af:button
See from docs-

af|query::button Styles the buttons of the query component. Note that this skin selector is only present when the skin selector -tr-button-type is set to 'old', and the query buttons are rendered as af:commandButtons. When the -tr-button-type is set to 'unified', the query buttons are rendered as af:buttons and have the default stylings for af:button applied, so that query buttons have the same look and feel as all other buttons. Tip: If you skin this selector's background-image, you may also want to skin it for :hover, :active, :focus. The :disabled state is currently not supported. Please note that for buttons :active and :focus pseudo-classes do not work in IE7. IE7 also does not allow disabled buttons to be styled. It is recommended that you use the .AFButton*:alias selectors as a shortcut to skin all button components the same.

So for this first i have to change -tr-button-type selector to old so that i can use af|query::button
Now see the css


af|query {
    -tr-button-type: old;
}
 af|query::button {
    color: red;
    font-weight:bold;
}

 af|query::button:hover {
    color: Orange;
    font-weight:bold;
}

 af|query::button:focus {
    color: maroon;
    font-weight:bold;
}

af|button{
    color:navy;
    font-weight:bold;
}

Check the output-

To use specific style for af:query you can create styleClass in css file and put this in styleClass property of af:query
Suppose i have two af:query components on page and i want to use different style for both
For this i have define two different styleClass in css file like this-


af|query {
    -tr-button-type: old;
}
 .mystyle1 af|query::button {
    color: red;
    font-weight:bold;
}

.mystyle2 af|query::button {
    color: darkgreen;
    font-weight:bold;
}

and on page put myStyle1 in styleClass property of first af:query component and myStyle2 in second af:query
See how it looks now -


Cheers, Happy Learning  ☺

Wednesday, 24 December 2014

Update page component in between of event processing in ADF Faces using JavaScript

This post is not about any specific topic of framework, recently i was working in an application, requirement was like this
There is a button on page that uploads a large file to server and it takes some time . So as soon as user press this button it's text should be changed to 'Processing..' and after upload is complete it should be 'Done'




In this post i am sharing same - How to update page component while an event is processing ?
First i have tried it using java means in same button action listener but in this case button text was changed only after event processing is complete
So for this purpose i have used some javascript function, this is quite simple (see the implementation)

  • Drop a button on page and create a ActionListener , it will change button text to 'Done' after event processing (used Thread.sleep() for some long processing)

  •     private RichButton buttonBind;
    
        /**Method to process Action Event
         * @param actionEvent
         */
        public void processValueAction(ActionEvent actionEvent) {
            // Sleep for some time (Event Processing time)
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //After processing set button text to 'Done'
            buttonBind.setText("Done");
            AdfFacesContext.getCurrentInstance().addPartialTarget(buttonBind);
        }
    
        public void setButtonBind(RichButton buttonBind) {
            this.buttonBind = buttonBind;
        }
    
        public RichButton getButtonBind() {
            return buttonBind;
        }
    

  • Now question is how to change button text to 'Processing..' immediately after clicking button. So for this purpose i am using javascript

  • function changeButtonText(event) {
                      var comp = event.getSource();
                      comp.setText('Processing..');
                  }
    

  • Calling this javascript function using af:clientListener in button like this (See XML source of page)

  •  <af:document title="UpdatePageComponent.jspx" id="d1">
                <af:resource type="javascript">
                  function changeButtonText(event) {
                      var comp = event.getSource();
                      comp.setText('Processing..');
                  }
                </af:resource>
                <af:form id="f1">
                    <af:spacer width="10" height="10" id="s1"/>
                    <af:panelGroupLayout id="pgl1" layout="horizontal" halign="center">
                        <af:panelBox id="pb1" showDisclosure="false">
                            <f:facet name="toolbar"/>
                            <af:button text="Click to process" id="b1"
                                       actionListener="#{viewScope.UpdatePageComponent.processValueAction}"
                                       clientComponent="true" binding="#{viewScope.UpdatePageComponent.buttonBind}"
                                       inlineStyle="width:250px;text-align:center;padding:5px;font-weight:bold;">
                                <af:clientListener method="changeButtonText" type="action"/>
                            </af:button>
                        </af:panelBox>
                    </af:panelGroupLayout>
                </af:form>
            </af:document>
    

  • As soon as button is clicked this javascript function will be invoked and set new text in button and after event processing button text is again set by managed bean actionListener.


  • After Clicking button (Event is processing)-

    Processing complete-

Thanks, Happy Learning :)