Please disable your adblock and script blockers to view this page

Search this blog

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  ☺

Tuesday 28 April 2015

ADF Skinning : Remove "search" or "more" link from af:inputComboboxListOfValues in ADF Faces (Jdev 12.1.3)

Hello all,

This post is about a small CSS trick that may be useful sometimes

we often use af:inputComboboxListOfValues to show large amount of data as List of Values
From Oracle Docs-
The inputComboboxListOfValues component allows a user to open a choice list and select from a list of values, in order to populate the LOV field (and possibly other fields) on a page.
Users can either select a value from the list in the dropdown panel or click the "Search..." link at the bottom of the panel to launch the "Search and Select" dialog. The dialog enables users to search for specific values and select the desired value that should go into the LOV field on the base page. The choice list when opened could display various items in the following order with separators between each (if applicable).




Have a look at this -
 here you see a link "more" on click this link a search dialog box appears , when you define a search criteria in lov at model level then this link appears as "search"


So to remove this link from combobox use this CSS

af|inputComboboxListOfValues::search{
    display: none;
}

Now look at combo box , we are done



Also Check how to configure ADF Skin in Application - ADF Basics: Using CSS to change appearance of application (Skins and Styles in ADF Faces)

Cheers :)
Happy Learning

Thursday 16 April 2015

Build selectOneChoice to show hierarchical (tree style) data programmatically in ADF

This post is based on an old article from Frank Nimphius How - to build a select one choice displaying hierarchical selection data

This article is about showing tree structure data in af:selectOneChoice component using ADF BC , it makes use of tree binding and af:forEach
Same concept i have used to populate data from managed bean using List data structure

Let's see the implementation part - how to populate tree style selectOneChoice programatically ?

First we have to design a Java Bean class in such a way that it can hold  master -detail type of data

A class that represents a List for Parent Values
                          ======> A list of same type to hold Child Values

See bean class code-

import java.util.ArrayList;
import java.util.List;

public class Seasons {
    public Seasons(String name) {
        this.name = name; // To Store Header Values (Storing Seasons Name :))
    }
    // Season and Charater Name
    private String name;
    // To Store Detail Values (Storing Season's Charatcers)
    private List<Seasons> characters = new <Seasons>ArrayList();

    public void setCharacters(List<Seasons> empDet) {
        this.characters = empDet;
    }

    public List<Seasons> getCharacters() {
        return characters;
    }


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    // This methods directly add characters value in list
    public void addCharaters(Seasons employee) {
        characters.add(employee);
    }
}

Now how to use this bean in managed bean to add records, i have written code in constructor to populate values on class load




    // Master List to populate data in selectOnce choice
    List<Seasons> seasonList = new ArrayList<Seasons>();

    public void setSeasonList(List<Seasons> seasonList) {
        this.seasonList = seasonList;
    }

    public List<Seasons> getSeasonList() {
        return seasonList;
    }
    //Constructor of Managed Bean to populate data on page load (you can move this code )
    public TreeStyleLovBean() {
        super();
        // Creating tree for Seasons and Characters details
        // Adding Master Values (seasons)
        Seasons season1 = new Seasons("Game of Thrones");

        // Adding Detail Values (Child Node-Characters)
        Seasons character = new Seasons("Tywin Lannister");
        season1.addCharaters(character);
        character = new Seasons("Tyrion Lannister");
        season1.addCharaters(character);
        character = new Seasons("Jaime Lannister");
        season1.addCharaters(character);
        character = new Seasons("Cersie Lannister");
        season1.addCharaters(character);
        character = new Seasons("Ned Stark");
        season1.addCharaters(character);

        // Adding Master Values (seasons)
        Seasons season2 = new Seasons("Arrow");

        // Adding Detail Values (Child Node-Characters)
        character = new Seasons("Oliver Queen");
        season2.addCharaters(character);
        character = new Seasons("Moira Queen");
        season2.addCharaters(character);
        character = new Seasons("Laurel Lance");
        season2.addCharaters(character);
        character = new Seasons("Sara Lance");
        season2.addCharaters(character);

        // Adding Master Values (seasons)
        Seasons season3 = new Seasons("Vikings");

        // Adding Detail Values (Child Node-Characters)
        character = new Seasons("Ragnar Lothrak");
        season3.addCharaters(character);

        // Adding Master Values (seasons)
        Seasons season4 = new Seasons("The Flash");

        // Adding Detail Values (Child Node-Characters)
        character = new Seasons("Barry Allen");
        season4.addCharaters(character);
        character = new Seasons("Harisson Wells");
        season4.addCharaters(character);
        character = new Seasons("Iris West");
        season4.addCharaters(character);
        character = new Seasons("Joe");
        season4.addCharaters(character);

        // Adding all list to topList
        seasonList.add(season1);
        seasonList.add(season2);
        seasonList.add(season3);
        seasonList.add(season4);

    }
how to bind this managed bean to selectOneChoice ? i have used same concept as described in Frank's article using af:forEach


<af:selectOneChoice id="selectBox" label="Choose Character" valuePassThru="true"
                                        styleClass="employeeSelectBox" contentStyle="width:150px;"
                                        binding="#{viewScope.TreeStyleLovBean.selectOneValueBind}">
                        <af:forEach items="#{viewScope.TreeStyleLovBean.seasonList}" var="seasonNm">
                            <af:selectItem label="#{seasonNm.name}" disabled="true" id="si1"/>
                            <af:forEach items="#{seasonNm.characters}" var="characterNm">
                                <af:selectItem label="#{characterNm.name}" value="#{characterNm.name}" id="si2"/>
                            </af:forEach>
                        </af:forEach>
                    </af:selectOneChoice>

you can see here that first forEach is populated from master list and iterates over list of seasons and first selectItem show season's name
the inner forEach makes used of character list that is defined in Java Bean class and stores season wise character's name
Rest is same - a CSS is used to differentiate color and alignment of parent and child records (same as Frank's article)


<f:facet name="metaContainer">
                <af:group>
                    <![CDATA[
<style>
.employeeSelectBox option{text-indent:15px;color:darkgreen;}
.employeeSelectBox option[disabled]{color:red; background-color:#dddddd; 
font-weight: bold; text-indent:0px}
</style>
]]>
                </af:group>
            </f:facet>

Now run this application - see how it appears on page



It looks quite good :) to get selected value in bean just use componentBinding.getValue();

Sample ADF Application-Download (Jdev 12.1.3)
Cheers , Happy Learning 

Tuesday 7 April 2015

Better UI -Show jQuery notification message (for error, warning, info) in Oracle ADF

Hello all,
Another post about using jQuery with ADF Faces , this post is about showing a notification message using jQuery in your ADF Application
Normally we use default FacesMesage to show error, warning and info messages in ADF

here i am using jQuery growl library , you can download files from Growl : jQuery Informative Messages Plugin

Let's see how to integrate this library with ADF Faces, you will get two files from above link
one is JavaScript file (jQuery script) and other one is CSS file (style-sheet for notification UI)



Add both files to viewController project under Web Content

now add reference of both files (JS and CSS) in page and also jQuery library to execute growl script


 <af:resource source="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js" type="javascript"/>
            <af:resource source="js/jquery.growl.js" type="javascript"/>
            <af:resource source="style/jquery.growl.css" type="css"/>

Now i have added 3 buttons on page to show different messages on button click and created a managed bean to define action for each button
On button click i have called jQuery script to invoke notification message
see managed bean code-


import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

public class ShowJqNotification {
    public ShowJqNotification() {
    }

    /**Helper method to execute javascript
     * @param script
     */
    public void calljqHelper(String script) {
        FacesContext context = FacesContext.getCurrentInstance();
        ExtendedRenderKitService erks = Service.getService(context.getRenderKit(), ExtendedRenderKitService.class);
        erks.addScript(context, script);
    }
    //Change your message as per requirement 
    /**Method to invoke Error Message
     * @param actionEvent
     */
    public void showErrMessageAction(ActionEvent actionEvent) {
        calljqHelper("$.growl.error({ message: \"Hi this is error message!\" });");

    }

    /**Method to invoke Warnign Message
     * @param actionEvent
     */
    public void showWarningMessageAction(ActionEvent actionEvent) {
        calljqHelper("$.growl.warning({ message: \"Hi this is Warning!\" });");
    }

    /**Method to invoke Info Message
     * @param actionEvent
     */
    public void showNoticeMessageAction(ActionEvent actionEvent) {
        calljqHelper("$.growl.notice({ message: \"Hi this is Notice!\" });");
    }

}

All done, now run application and check - how it looks :)


this is default look of script , you can customize it , just change some parameters in both JS and CSS files
I have changed some parameters in both files and see how it looks now

Cheers, Happy Learning :)
Sample ADF Application- Download

Read more about - Jquery and ADF Working together

Image zoom (power zoomer) effect using Jquery in ADF Faces
Show animated Image Caption using jQuery in ADF Faces
Using JQuery in Oracle ADF

Friday 3 April 2015

Stretch ADF Faces Components to fit browser width (Show as row-column layout- inline block )

Recently i have seen a thread in OTN about layout of components (How to use components to show a particular layout)
ADF layout for showing email recipients

Requirement was simple, user want to show components up to maximum available width (browser window width) first and then move to next line and show other components
So i thought to document it here :)

Suppose i have to show 6 images on page (horizontally) , so for that i have used 6 group layout
one for each image and button



See xml source-

<af:panelGroupLayout id="pgl1" layout="horizontal">
                    <af:panelGroupLayout id="pgl2" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:a_hobbit_house-wallpaper-1280x800.jpg']}"
                                  shortDesc="Hobbit House" id="i1" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b1"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl3" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:beach_at_sunset_3-wallpaper-1440x900.jpg']}"
                                  shortDesc="Sunset at Beach" id="i2" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b2"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl4" layout="vertical" halign="center" inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:icelands_ring_road-wide.jpg']}" shortDesc="Ring Road"
                                  id="i3" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b3"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl5" layout="vertical" halign="center" inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:road_to_mount_cook-wallpaper-1280x800.jpg']}"
                                  shortDesc="Road To Mount Cook" id="i4" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b4"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl6" layout="vertical" halign="center" inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:skyscrapers_reflections-wallpaper-1280x800.jpg']}"
                                  shortDesc="Skycrappers " id="i5" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b5"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl7" layout="vertical" halign="center" inlineStyle="padding:2px;">
                        <af:image source="#{resource['images:tufandisli_1387241118_57.jpg']}" shortDesc="Tufan"
                                  id="i6" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b6"/>
                    </af:panelGroupLayout>
                </af:panelGroupLayout>

 and how it looks on page-


You can see here last image is not appearing properly because total width of all images has crossed maximum available width of browser window
Now i want to show last image on next line
So to do this set parent panel group layout to default layout and set display:inline-block for all child panel group layout


<af:panelGroupLayout id="pgl1">
                    <af:panelGroupLayout id="pgl2" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:a_hobbit_house-wallpaper-1280x800.jpg']}"
                                  shortDesc="Hobbit House" id="i1" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b1"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl3" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:beach_at_sunset_3-wallpaper-1440x900.jpg']}"
                                  shortDesc="Sunset at Beach" id="i2" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b2"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl4" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:icelands_ring_road-wide.jpg']}" shortDesc="Ring Road"
                                  id="i3" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b3"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl5" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:road_to_mount_cook-wallpaper-1280x800.jpg']}"
                                  shortDesc="Road To Mount Cook" id="i4" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b4"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl6" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:skyscrapers_reflections-wallpaper-1280x800.jpg']}"
                                  shortDesc="Skycrappers " id="i5" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b5"/>
                    </af:panelGroupLayout>
                    <af:panelGroupLayout id="pgl7" layout="vertical" halign="center"
                                         inlineStyle="padding:2px;display:inline-block;">
                        <af:image source="#{resource['images:tufandisli_1387241118_57.jpg']}" shortDesc="Tufan"
                                  id="i6" inlineStyle="width:250px;height:200px; "/>
                        <af:button text="View" id="b6"/>
                    </af:panelGroupLayout>
                </af:panelGroupLayout>

Now it appears like this -

now again test it by increasing and decreasing browser window width , images and group layout are adjusted as per screen size automatically like a grid view (row and columns)

Thanks , Happy Learning :)
Sample ADF Application- Download