JDeveloper 11.1.1.2: Carousel component as Master and Detail

6

In this post I introduce to you one of the new ADF Rich Client components and one way to use it: The Carousel. You can display a set of images through a carousel, an animation effect that switches the emphasis successively between images as the user moves the mouse across them.

You can also have the carousel invoke and respond to partial triggers and display data in master detail relationships.

I first create a new application based on the Fusion Webapp technology. Then, in order to create master detail forms and tables create need an appropriate datamodel.

The Datamodel:

I created new ADF-BC based on the Countries, Locations and Departments tables from the HR schema. In the application module I deleted the default created datamodel and created a new Region/Country/Location hierarchy.

For this blog I wanted to create the following scenario:  I have a form containing the Region data and I have the carousel containing the Countries respond to this Region form. When in the form a new Region is selected, the carousel needs to display the corresponding Country: the flag of the country.

Here's what I did.

Respond to a PPR event:

First I created a new page without any template and dropped the regions collection as read only form with navigation controls. Next I dropped the countries collection.  You can actually drop a collection as a carousel component.

After some slight modifications (add carouselItem and the image) the carousel code looks like this:

<af:carousel currentItemKey="#{bindings.CountriesView.treeModel.rootCurrencyRowKey}"
             value="#{bindings.CountriesView.treeModel}" var="item"
             id="c1" >
          <f:facet name="nodeStamp">
          <af:carouselItem id="ci1"  >
            <af:image id="img" source="/images/flags_png/#{item.CountryName}.png" shortDesc="#{item.title}"/>
          </af:carouselItem>
          </f:facet>
        </af:carousel>

I read the images for the flags from the filesystem where I have an image for each country. In order to see the effect of the Region change in the carousel I add a partialtrigger to the carousel, referencing the Id of the Region Form. When you now run the page you would expect the carousel to be refreshed when a new Region is selected.

However, this is not the case. It is probably an issue in the Carousel component.

There is a workaround:
Create a binding for the carousel, and create a mehod that you invoke when pressing next and/or previous.

  public String refreshCarousel() {
    AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();
    adfFacesContext.addPartialTarget(this.carousel);

    return null;
  }

This method adds the carousel as a partial target and whe you now run the application it works.

 

Invoke a PPR event:

The carousel should also be able to initiate a PPR event. In order to do this let's create a detail table, containing the Locations, under the carousel. What we want is when you pick a different flag, the Locations table below the carousel is refreshed, and displays the data of all Locations in the selected country.

Drop the Locations collection as a table, add a partialtrigger to the to the Table, referencing the Id of the carousel.Run the page, and it should work………. Woops ! A change in the carousel doesn't invoke a refresh of the table. What's happening here ?

Looks like we have an issue here. The carousel does not make the selected row current. Here is the workaround for this one:

First add a spinListener to the carousel;

	<af:carousel ..............
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>carouselSpinListener=&quot;#{carouselBean.spinning}&quot;</strong>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binding=&quot;#{carouselBean.carousel}&quot;...........&gt;

In this spinListener make sure that the current row is set in the collection.

	&nbsp; public void spinning(CarouselSpinEvent carouselSpinEvent) {

	&nbsp;&nbsp;&nbsp; RichCarousel carousel = getCarousel();
	&nbsp;&nbsp;&nbsp; carousel.setRowKey(carouselSpinEvent.getNewItemKey());
	&nbsp;&nbsp;&nbsp; detailNodeItem = (JUCtrlHierNodeBinding)carousel.getRowData();

	&nbsp;&nbsp;&nbsp; String countryIdValue = (String)detailNodeItem.getAttribute(&quot;CountryId&quot;);
	&nbsp;&nbsp;&nbsp; DCIteratorBinding countryIt =
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getBindingContainer().findIteratorBinding(&quot;CountriesViewIterator&quot;);
	&nbsp;&nbsp;&nbsp; countryIt.setCurrentRowWithKeyValue(countryIdValue);
	&nbsp; }

&nbsp;

And now it works.

When you spin the carousel, the corresponding Locations are shown, and when you select a different region, the Carousel and the Locations table are refreshed.

Resources:

There is a thread on the JDeveloper forum concerning the issues mentioned in this post: http://forums.oracle.com/forums/thread.jspa?threadID=991030&tstart=0

Share.

About Author

Luc Bors is Expertise Lead ADF and technical specialist/architect at AMIS, Nieuwegein (The Netherlands). He developed several Workshops and training on ADF and also is an ADF and JHeadstart instructor. Luc is a member of the ADF Methodology group and publishes articles on ADF in oracle technology related magazines, on the AMIS technology blog, (http://technology.amis.nl/blog).

6 Comments

  1. Hi!! I think it’s great your example, but the carousel support the images from the Data Base?? If it does, can you tell me  how is it?? Thanks

  2. Hi Ewan,

    Do you have an example of using an Active Image? I tried to get it to work but so far was not able to. Thanks for any help/suggestions.

    Lucas

  3. Iwan Hendrickx on

    You can use an Active Image component to refresh the flags. Then the PPR code is obsolete.
    Otherwise a nice example of the interesting component carousel.
    Iwan

  4. Very nice! (by the way: the line countryIt.getCurrentRow().getAttribute(“CountryId”);
    in your code snippet – should it be there?)