A Custom ShowDetailFrame that does not require a WebCenter License

This post demonstrates a custom showDetailFrame that is built using regular ADF Faces components. Hence no additional license is needed to use it. (You need a WebCenter license if you use the new showDetailFrame component. The issue is explained in this OTN thread )

The sample application is built in 10.1.3.2. It does not require a database connection to run. You can download the workspace from here.
Sample Application

The application contains a page built with custom ShowDetailFrame and another page built with the original component.
Custom ShowDetailFrame Original ShowDetailFrame

Below is the JSP and the JavaScript code of the custom showDetailFrame.
<f:view>
<afh:html>
<afh:head title="Show Custom Detail Frame">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<script type="text/javascript" src="customFrame.js"></script>
</afh:head>
<afh:body onload="onLoad();">
<af:form>
<af:inputHidden id="frameStatus" value="#{processScope.frameStatus}"/>
<af:panelForm rows="2" maxColumns="1">
<af:panelBox  width="400">
<af:panelHorizontal halign="left">
<af:commandLink onclick="minimize();" id="minimizer"
partialSubmit="true" immediate="true"
inlineStyle="#{processScope.frameStatus == 'minimized' ? 'display: none;' : ''}">
<af:setActionListener from="#{'minimized'}" to="#{processScope.frameStatus}"/>
<af:objectImage source="/minimize.gif"
id="minimizeObj" />
</af:commandLink>
<af:commandLink onclick="maximize();" id="maximizer"
partialSubmit="true" immediate="true"
inlineStyle="#{processScope.frameStatus == 'minimized' ? '' : 'display: none;'}">
<af:setActionListener from="#{'maximized'}" to="#{processScope.frameStatus}"/>
<af:objectImage source="/expand.gif" id="extendObj"/>
</af:commandLink>           
<af:outputLabel value="Custom showDetailFrame"/>
</af:panelHorizontal>
</af:panelBox>
<afh:tableLayout width="400" id ="frameTableLayout"
inlineStyle="border: 1px solid #D2D8B0; border-top: 0; height:200.0px;"
#{processScope.frameStatus == 'minimized' ? ' display: none;' : ''}">
<afh:rowLayout>
<afh:cellFormat halign="center">
<af:goLink destination="http://www.gergerconsulting.com">
<af:objectImage source="/GC.gif" shortDesc="Gerger Consulting"/>
</af:goLink>
</afh:cellFormat>
</afh:rowLayout>
<afh:rowLayout>
<afh:cellFormat>
<af:inputText label="Required Field" required="true" value="#{processScope.requiredField1}"
columns="10" maximumLength="10"/>
</afh:cellFormat>
</afh:rowLayout>
</afh:tableLayout>
</af:panelForm>
<af:panelForm rows="1" maxColumns="1">
<af:objectSpacer width="10" height="10"/>
<af:commandButton text="Go To The Next Page" action="goPage1"/>
</af:panelForm>
</af:form>
</afh:body>
</afh:html>
</f:view>

function minimize(){
var frameStatus=document.getElementById('frameStatus');
frameStatus.value='minimized';
var minimizer=document.getElementById('minimizer');
minimizer.style.display='none';
var maximizer=document.getElementById('maximizer');
maximizer.style.display='';
var frameTableLayout=document.getElementById('frameTableLayout');
frameTableLayout.style.display='none';
return true;
}

function maximize(){
var frameStatus=document.getElementById('frameStatus');
frameStatus.value='maximized';
var minimizer=document.getElementById('minimizer');
minimizer.style.display='';
var maximizer=document.getElementById('maximizer');
maximizer.style.display='none';
var frameTableLayout=document.getElementById('frameTableLayout');
frameTableLayout.style.display='';  
return true;
}

function onLoad(){
var frameStatus=document.getElementById('frameStatus');
if (frameStatus.value=='maximized' || frameStatus.value=='')
{
maximize();
}
else if (frameStatus.value=='minimized')
{
minimize();
}
return true;
}
The original showDetailFrame component is not Back/Forward Button friendly. The custom showDetailFrame shown in this sample application preserves its state even though the page is viewed using the Back/Forward buttons.

If this behavior is not important or not desired, use the following JSP below;
<f:view>
<afh:html>
<afh:head title="Show Custom Detail Frame">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<script type="text/javascript" src="customFrame.js"></script>
</afh:head>
<afh:body onload="onLoad();">
<af:form>
<af:inputHidden id="frameStatus" value="#{processScope.frameStatus}"/>
<af:panelForm rows="2" maxColumns="1">
<af:panelBox  width="400">
<af:panelHorizontal halign="left">
<af:commandLink onclick="minimize(); return false;" id="minimizer">
<af:objectImage source="/minimize.gif"
id="minimizeObj" />
</af:commandLink>
<af:commandLink onclick="maximize(); return false;" id="maximizer">
<af:objectImage source="/expand.gif" id="extendObj"/>
</af:commandLink>
<af:outputLabel value="Custom showDetailFrame"/>
</af:panelHorizontal>
</af:panelBox>
<afh:tableLayout width="400" id ="frameTableLayout"
inlineStyle="border: 1px solid #D2D8B0; border-top: 0; height:200.0px;">
<afh:rowLayout>
<afh:cellFormat halign="center">
<af:goLink destination="http://www.gergerconsulting.com">
<af:objectImage source="/GC.gif" shortDesc="Gerger Consulting"/>
</af:goLink>
</afh:cellFormat>
</afh:rowLayout>
<afh:rowLayout>
<afh:cellFormat>
<af:inputText label="Required Field" required="true" value="#{processScope.requiredField1}"
columns="10" maximumLength="10"/>
</afh:cellFormat>
</afh:rowLayout>
</afh:tableLayout>
</af:panelForm>
<af:panelForm rows="1" maxColumns="1">
<af:objectSpacer width="10" height="10"/>
<af:commandButton text="Go To The Next Page" action="goPage1"/>
</af:panelForm>
</af:form>
</afh:body>
</afh:html>
</f:view>
The modified custom showDetailFrame will not support the following scenario;

  1. Run the customShowDetailFrame page

  2. Click the “Go To The Next Page” button

  3. Click the Back Button

  4. Minimize the frame

  5. Click Forward Button

  6. Click the “Go To The Previous Page” button
The frame will appear as maximized even though it was minimized in step 4.

Yalım K. Gerger

Comments

zeo said…
Great tutorial. In additino I have a bunch of these on my page so I figured it would be useful to parameterize the js functions see following:

function maximize(frameId,minLink,maxLink){
...
minimizer=document.getElementById(minLink);
...
maximizer=document.getElementById(maxLink);
...
frameTableLayout=document.getElementById(frameId);
...}


within the jsp file, just assign unique ids to the tablelayouts,commandlinks and then pass in the three ids.

Popular posts from this blog

PostgreSQL for Oracle Developers and DBA's