Thursday, December 27, 2012

Adding ghost labels/ label in fields using JQuery to WebCenter/ ADF web application


Ghost labels is equivalent to placeholder attribute of input tag. This HTML tag is not supported by ADF. Please visit http://www.w3schools.com/html5/att_input_placeholder.asp for more on placeholder. placeholder attribute is supported in all major browsers, except Internet Explorer

Figure 1

This application covers displaying of label in fields for 3 commonly used controls, viz. Input Text, Input Text with secret="true" i.e. password and Select One Choice. Below is screenshot of ghost label image generated as output of this application
Figure 2
Once you click on any field to type, it becomes blank as shown below
Figure 3
Screen appears as below after making entries in all fields
Figure 4
Below are steps to implement ghost labels/ label in fields 
1.  Create new Web Center Portal - Framework Application
2.  Download jquery-1.7.1.min.js or get it from downloadable application under MyWebApplicationWithJQueryGhostLabels\Portal\public_html\js. Copy it to folder added by you, say C:\JDeveloper\mywork\MyWebApplicationWithJQueryGhostLabels\Portal\public_html\js
3.  Right click folder js > New > Categories > Web tier > HTML > JavaScript File, name it say, label-in-field.js. Your js folder should now be containing 2 files, viz. jquery-1.7.1.min.js, label-in-field.js
4.   Add folder, say C:\JDeveloper\mywork\MyWebApplicationWithJQueryGhostLabels\Portal\public_html\css css, in Web Content folder. Right click folder css > New > Categories > Web tier > HTML > CSS File, say label-in-field.css. Add below code to it and save it
.text-label { color: #cdcdcd; font-weight: bold;}
5.   Add below code to label-in-field.js and save it
function onADFPageLoad() {
    try {
        // Label in field/ ghost label for Select One Choice control
        $('select').each(function () {
            if (this.selectedIndex == 0) {
                $(this).addClass('text-label');
            }

            $(this).focus(function () {
                $(this).removeClass('text-label');
                $(this.options[0]).addClass('text-label');
            });

            $(this).change(function () {
                if (this.selectedIndex == 0) {
                    $(this).addClass('text-label');
                    $(this.options[0]).addClass('text-label');
                    //Use below to lines if you do not want to use CSS
                    //this.style.color = '#cdcdcd';
                    //this.style.fontWeight = 'bold';
                }
                else {
                    $(this).removeClass('text-label');
                    $(this.options[0]).addClass('text-label');
                }
            });
        });

        // Label in field/ ghost label for Input Text control
        $('input[type="text"]').each(function () {
            if (this.value == '') {
                this.value = getLabelForComponentId(this.name);
                $(this).addClass('text-label');
            }

            $(this).focus(function () {
                if (this.value == getLabelForComponentId(this.name)) {
                    this.value = '';
                    $(this).removeClass('text-label');
                }
            });

            $(this).blur(function () {
                if (this.value == '') {
                    this.value = getLabelForComponentId(this.name);
                    $(this).addClass('text-label');
                }
            });
        });

        // Label in field/ ghost label for Input Text control with secret="true" i.e. password
        $('input[type="password"]').each(function () {
            this.value = "";

            if (this.value == '') {
                this.type = "text";
                this.value = getLabelForComponentId(this.name);
                $(this).addClass('text-label');
            }

            $(this).focus(function () {
                if (this.value == getLabelForComponentId(this.name)) {
                    this.type = "password";
                    this.value = '';
                    $(this).removeClass('text-label');
                }
                else {
                    //this.type = "text"; //For testing only. DO NOT uncomment. Uncommenting will show password in plain text
                }
            });

            $(this).blur(function () {
                if (this.value == '') {
                    this.type = "text";
                    this.value = getLabelForComponentId(this.name);
                    $(this).addClass('text-label');
                }
                else {
                    this.type = "password";
                    $(this).removeClass('text-label');
                }
            });
        });
    }
    catch (err) {
        alert(err);
    }
}

function getLabelForComponentId(textId) {
    try {
        var adfComp = AdfPage.PAGE.findComponentByAbsoluteId(textId);
        return adfComp.getLabel();
    }
    catch (err) {
        alert(err);
    }
}
6.   Add say MyRegistrationForm.jspx under Web Content > oracle > webcenter > portalapp > pages, which requires to display input texts, password input texts, dropdowns to display label in field or ghost label functionality
7.   Add below lines to your MyRegistrationForm.jspx

  
  
    
      
        
        
        
      
      
        
          
          
          
            
            
            
          
        
      
      
    
  

8.   Open pages.xml from Web Content > oracle > webcenter > portalapp > pagehierarchy. Select Root. Drag drop MyRegistrationForm under Root in Page Hierarchy’s Hierarchy: section and select MyRegistrationForm. Select Delegate Security radio button under Security section. Ensure anonymous-role has View permission
9.   To run application, download it. Expand Web Content > oracle > webcenter > portalapp > pages, right click MyRegistrationForm.jspx, click run

In case, you do not wish to apply ghosting to certain controls, add below condition
if (getLabelForComponentId(this.name) != "itTelephoneNo") {}

within
$('input[type="text"]').each(function() {});

(where itTelephoneNo is id property of Input Text control on your .jspx form)

Download Application


Monday, December 24, 2012

WebCenter Content Interface Branding for 11g - Part 2


Continuing from part 1 (here) ...

Building the component

Using Component Wizard, we will start a new component.

This component will be named “WCC_Interface_Branding”. The main requirement of a component name is that it be unique to the system. I usually prefix a component with the name of the customer, such that for aurionPro SENA, the component could be named “APS_Interface_Branding”. Using this convention, all custom components created for aurionPro SENA would be prefixed with “APS_” to distinguish them as created for aurionPro SENA.
For this component we will need five resources:
1.       Resource – HTML Include
2.       Resource – Static Table (HTML Format)
3.       Template
4.       Resource – default cs_string include
5.       Resource – Strings – English cs_strings
Using the Component Wizard, create each of these as follows
Type of Resource
File Name
Load Order
HTML Include/String
resources/wcc_interface_branding_resource.htm
10
Static Table (HTML Format)
resources/wcc_interface_branding_static_tables.htm
10
Template
templates/wcc_interface_branding_template.hda
10
HTML Include/String
resources/lang/cs_strings.htm
10
HTML Include/String
resources/lang/en/cs_strings.htm
10

The first string resource is for the default language strings while the second holds the English version of the strings. Since the default is English, the English file is empty. It is needed only to prevent errors.

Strings

The string we want to add is the component description string. In Component Wizard,
1.       Select the resources/lang/cs_strings.htm resource on the left
2.       Select the Launch Editor… button on the left.
If you have not configured and editor you will get an error indicating this. If you get the error then select the Options menu and select Set HTML Editor. In Linux I set this to /usr/bin/gedit.
3.       When you created the resource, a sample string was added. You can delete that.
4.       Add the following within the body tags:
<@string csCompDesc_WCC_Interface_Branding@>
The WCC_Interface_Branding component alters 
the web interface to change the out of the 
box logo to a custom logo.
<@end@>
5.       Save and close the editor
Now edit the English string file to simply state that it is a dummy file.
1.       Select the resources/lang/en/cs_strings.htm resource on the left
2.       Select the Launch Editor… button on the left.
If you have not configured and editor you will get an error indicating this. If you get the error then select the Options menu and select Set HTML Editor. In Linux I set this to /usr/bin/gedit.
3.       When you created the resource, a sample string was added. You can delete that.
4.       Add the following within the body tags:
<@string csCompDesc_WCC_Interface_Branding@>
The WCC_Interface_Branding component alters 
the web interface to change the out of the 
box logo to a custom logo.
<@end@>
5.       Save and close the editor

Templates

Now add the templates. In Component Wizard,
1.       Select the template resource on the left,
2.       Then select the add button on the right to add a new template.
3.       Since the templates we need are out of the box templates that we will modify, we need to select them from the dialog rather than recreate them. So in the AddIntradoc Template dialog, select the Select button.
4.       Check the box to Show All.
5.       Locate and select the TOP_MENUS_LAYOUT_JS template and then select OK
Note that you can sort this list by selecting the column heading.
Repeat the process to select the TRAYS_LAYOUT_JS template
The next step is to edit the templates. Select the TOP_MENUS_LAYOUT_JS template on the right and select the Launch Editor… button on the right.
It is always a good habit to include notes in your work to help others that come after you. At the top of this file I included a comment of
/* ============================================================================
   Name:        top_menus_layout.js
   Description: template is modified to change the value of the logoImage
                to point to the SENA image
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
============================================================================ */

Locate the line with the oracle_logo.png file called out. It looks like this:
/* Header/menu bar image src values */
var logoImage = httpSkinRoot + "oracle_logo.png";
Change it to
/* Header/menu bar image src values */
/* ============================================================================
       logoImage changed to SENA image
       2012-07-05 - Steve Hamilton
============================================================================ */
//var logoImage = httpSkinRoot + "oracle_logo.png";
var logoImage = httpSkinRoot + "sena.gif";

Save and close the editor.
Repeat this for the TRAYS_LAYOUT_JS  template. Add the comment to the top:
/* ============================================================================
   Name:        trays_layout.js
   Description: template is modified to change the value of the logoImage
                to point to the SENA image
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
============================================================================ */
Locate the line with the oracle_logo.png file called out. It looks like this:
/* Header/menu bar image src values */
var logoImage = httpSkinRoot + "oracle_logo.png";
Change it to
/* Header/menu bar image src values */
/* ============================================================================
       logoImage changed to SENA image
       2012-07-05 - Steve Hamilton
============================================================================ */
//var logoImage = httpSkinRoot + "oracle_logo.png";
var logoImage = httpSkinRoot + "sena.gif";

Save and close the editor.

Resources

The next step is the resources. In Component Wizard,
1.       Select the resource file (resources/wcc_interface_branding_resource.htm) on the left,
2.       Then select the add button on the right to add a new resource.
3.       Since the resource we need is out of the box that we will modify, we need to select it from the dialog rather than recreate it. So in the Add HTML Resource Include dialog, select the Select button.
4.       Check the box to Show All.
5.       Locate the home_page_static_content resource, select it and then select OK twice.
6.       Select the Launch Editor button on the left.
7.       Again we add a comment for those that follow. Place it outside the resource so that it will not be in the rendered pages.
locate the line
<@dynamichtml home_page_static_content@>
and replace it with
<!-- ==========================================================================
   Name:        home_page_static_content
   Description: include is modified to change the logo image and add the 
                InstanceDescription variable to the headerDescription
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
=========================================================================== -->
 
<@dynamichtml home_page_static_content@>
8.       Next, locate these lines
<img style="margin-bottom:-5px;" src="<$HttpImagesRoot$>stellent/mailheadinglogo.gif" alt="<$stripXml(lc("wwTopBannerLogo"))$>">&nbsp;
              <$lc("wwWelcomeTo", ProductID)$></h1>
And change them to
<img style="margin-bottom:-5px;" src="<$HttpImagesRoot$>sena/sena.gif" width="72" height="36" alt="<$stripXml(lc("wwTopBannerLogo"))$>">&nbsp;
              <$lc("wwWelcomeTo", ProductID)$> - <$InstanceDescription$></h1>

Using steps 1 – 6 above, add the std_navigation_header_top_row resource to our component.
Add the comment above the resource
<!-- ==========================================================================
   Name:        std_navigation_header_top_row
   Description: include is modified to adjust the height and width 
                of the logo image
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
=========================================================================== -->

Locate the lines
html[html.length] = '<img src="' + logoImage + '" width="119" height="25" border="0" alt="' + lc("wwLogoAltText") + ' ' + lc("wwContentMgmt") + ' ' + lc("wwHome") + '" />';

And change to
html[html.length] = '<img src="' + logoImage + '" width="72" height="36" border="0" alt="' + lc("wwLogoAltText") + ' ' + lc("wwContentMgmt") + ' ' + lc("wwHome") + '" />';

Repeat for the resource std_javascript_header_functions
Add the comment above the resource
<!-- ==========================================================================
   Name:        std_javascript_header_functions
   Description: include is modified to add the InstanceDescription 
                variable to the headerDescription
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
=========================================================================== -->
Locate the lines
var headerDescription = "<$ProductLabel ? js(ProductLabel) : lc('wwHeaderProductName')$>";

And change to
var headerDescription = "<$ProductLabel ? js(ProductLabel) : lc('wwHeaderProductName') $>" + " - <$InstanceDescription$>";

Publish

Now we need to set up the image files to be published. In the Component Wizard,
1.       Select the resources/wcc_interface_branding_static_tables.htm resource
2.       Select the Add button
3.       Ensure that
a.       The resource type selected is Resource – Static Table (HTML Format)
b.      The file name is the resources/wcc_interface_branding_static_tables.htm file
4.       Select Next
5.       Check the Merge To check box
6.       Select to merge to the PublishedStaticFiles
7.       Make sure theTable Name is set to WCC_Interface_Branding_PublishedStaticFiles
8.       Select OK to create it
9.       Select OK to open the editor
10.   Add the comment
<!-- ==========================================================================
   Name:        WCC_Interface_Branding_PublishedStaticFiles
   Description: Merge table to the PublishedStaticFiles table
                to control the publish of the SENA resources
                to the Weblayout static directories
   ----------
   Change History
   Rev  Date        Responsible      Comments
   ---  ----------  ---------------- --------------------------------------
    1   2012-07-05  Steve Hamilton   Original version
=========================================================================== -->
11.   Then change the table be be
<table border=1><caption><strong>
 
<tr>
<td>srcPath</td><td>path</td><td>class</td><td>loadOrder</td><td>doPublishScript</td><td>canDeleteDir</td>
</tr>
 
<tr>
       <td>publish/images/sena</td>
       <td>images/sena</td>
       <td>images:logo</td>
       <td>50</td>
       <td><$doPublish = 1$></td>
       <td>0</td>
</tr><tr>
       <td>publish/resources/layouts/Trays/Oracle</td>
       <td>resources/layouts/Trays/Oracle</td>
       <td>resources:layout:Trays</td>
       <td>50</td>
       <td><$doPublish = 1$></td>
       <td>0</td>
</tr>
<tr>
       <td>publish/resources/layouts/Trays/Oracle 2</td>
       <td>resources/layouts/Trays/Oracle 2</td>
       <td>resources:layout:Trays</td>
       <td>50</td>
       <td><$doPublish = 1$></td>
       <td>0</td>
</tr>
<tr>
       <td>publish/resources/layouts/Top Menus/Oracle</td>
       <td>resources/layouts/Top Menus/Oracle</td>
       <td>resources:layout:TopMenus</td>
       <td>50</td>
       <td><$doPublish = 1$></td>
       <td>0</td>
</tr>
<tr>
       <td>publish/resources/layouts/Top Menus/Oracle 2</td>
       <td>resources/layouts/Top Menus/Oracle 2</td>
       <td>resources:layout:TopMenus</td>
       <td>50</td>
       <td><$doPublish = 1$></td>
       <td>0</td>
</tr>
</table>
12.   Save and close the editor
Next we have to set up the publish source for the component. This involves file system work as well as component wizard work. First the file system: open your file browser or terminal. Browse to the custom directory of your instance. For me, that is
/u01/app/oracle/Middleware/user_projects/domains/dev_domain/ucm/cs/custom
Here you will find the directory for your component - WCC_Interface_Branding
Change into this directory.
Now create a directory structure that mimics the srcPath of the WCC_Interface_Branding_PublishedWeblayoutFiles table we created above. Into each bottom level directory, place our sena.gif file. When you are done it should look like the following

Next, in the Component Wizard,
1.       Select the Build, Build Settings menu
2.       Here, select Add
3.       For Entry Type, select Component Extra
4.       For the Sub Directory or File, enter “WCC_Interface_Branding/publish/”
5.       Select OK
6.       Enter a version if not already there: such as “2012_10_12-dev(build 1)”
7.       Select Advanced
a.       Enter Interface, Branding as the component tags
b.      Enter WCC_Interface_Branding as the Feature Extension.
c.       Select OK
8.       Select OK again

Enable

In Component Wizard, select Options, Enable to make the component available to the content server

Restart and Test

Restart your instance.
Once restarted log out so that you can get to the static home page and log in page for verify them

Static Home Page


This looks ok

Login page


This looks ok

Dynamic Pages


This looks ok

Conclusion

You have successfully created a component to rebrand your instance of WebCenter Content.
By the way, it also works on WebCenter Content: Records.

Thursday, December 20, 2012

Does Archiver Do Dynamic Value Mapping? <$if isTrue(IsSkeptical)$>I Don’t Think It Can.<$else$>Absolutely!<$endif$>


A user in the Oracle forums recently made a rather blanket statement that “dynamic changes are not possible with Archiver”. 

Never being one to shy away from a challenge, this post shows that import maps in Archiver can indeed be designed to be dynamic. 

It’s not readily apparent, but the admin applets are largely capable of utilizing Idoc Script, which in itself is very dynamic.  Coupling script with components is a very powerful way to build very complex logic to compute values in a mapping operation.  You don’t necessarily need a component, as you can simply key all the script logic directly into the value map box, but it’s easier to edit and compose the code logic outside of the applet.

To demonstrate this, first create an archive, and select a document to export, and export it. 

Looking at the item’s document information page, the document’s info looks like this.  Note that the expiration date is blank.
 


As an initial example, let’s set the expiration date to 7 days from the current date.
 
Open the archive’s “Import Maps” tab.  Select the “Edit” button located beside the “Value Maps” section.


Select “Expiration Date” from the field list.  In the “Output Value” box, enter “<$dateCurrent(7)$>” as shown in the next screen print, and click “Add”.  The value map is added as shown in the second screen print.   Click “Ok” to exit.


 
Now import the document exported earlier.  The expiration date is now set for 7 days from the date/time the import was executed.

 
Let’s do something a bit more complex by building some logic into a component to build a value for assigning to a document.  This example will be used to add comments to the document from the first example.  Again, note that the comments are blank for the document.



Start with creating a component with a resource file.  In the resource file, let’s create a dynamichtml include called “myExternalLogic”.



Let’s discuss a couple of things about the include that was created. 

First, note the “trimtext” directive added to the include definition.  This tells the system “whatever the result of the include is, trim the leading and trailing white space”.  This is good, since eventually the computed value will be put into a metadata field, and the extra whitespace may be an issue.  Secondly, note the trailing <$strResult$>.  Think of this like an ECHO statement – we’re just printing out the result for the import process, and it is necessary to actually get the value passed.

In the import map section, now add “Comments” as the field, and enter the text “<$include myExternalLogic$>” in the “Output Value” box as shown.  Click “Ok”.



Importing the document again populates the comments section with “some random text” as shown.


The logic can easily be more complex.  Let’s add another variable to the calculation.  Add <$myTemp=1$> to the import map as shown.



Now in the component resource, edit the resource to use this new value in the calculation.




Now the comments are populated based on the value of the variable “myTemp”.


The possible variables could also include environment variables, local variables, or other active values in the current row of the result set, which makes this VERY powerful.  Any constructs used in a dynamichtml statement are valid.  

For example, to put the current document type into the comments field use <$strResults=#active.dDocType$>.  It’s also possible to execute services in this manner to retrieve other data, although if field names are identical in the executed service, there is a risk of data pollution.


This is a really simple example of how Archiver is definitely “not static”, and can easily handle complex calculations.



 


Wednesday, December 19, 2012

Resolving Exception Code “Please create at least one open period for this operating unit” in Invoice Processing


Steps to resolve Exception Code “Please create at least one open period for this operating unit” in Invoice Processing

What are accounting periods?
Accounting period in bookkeeping is the period with reference to which accounting books of any entity are prepared. Period for which a firm prepares its internal or external accounts; the period covered by the financial statements. For internal accounts, it may be a month or a quarter; for external accounts it is normally a period of 12 months

It is the period for which books are balanced and the financial statements are prepared. Generally, the accounting period consists of 12 months. However the beginning of the accounting period differs according to the jurisdiction. For example one entity may follow the regular calendar year, i.e. January to December as the accounting year, while another entity may follow April to March as the accounting period

In some of the ERP tools there are more than 12 accounting periods in a financial year

Accounting periods can have one of the following statuses:
Open: Journal entry and posting allowed
While executing any transaction, the transaction date must fall in an open period. If that period is not open then the system prevents us from proceeding any further

Closed: Journal entry and posting not allowed until accounting period is reopened. Reporting and inquiry allowed

Permanently Closed: Journal entry and posting not allowed. You cannot change this period status. Reporting and inquiry allowed

Never Opened: Journal entry and posting are not allowed. General Ledger assigns this status to any period preceding the first period ever opened in your calendar, or to any period that has been defined, but is not yet future-enterable. You cannot change this period status

Future: Journal entry is allowed, but posting is not. Your period is not yet open, but falls within the range of future-enterable periods you designated in the Set of Books window. You cannot change this period status without using the concurrent process to open the period

How to resolve Exception Code “Please create at least one open period for this operating unit” in Invoice Processing?
In case the Exception Code is displayed as below while Invoice Processing i.e. “Please create at least one open period for this operating unit”, in Invoice Processing, follow below steps
 Figure 1


1)      Logon to Oracle E-Business Suite

2)      Locate Payables, Vision Operations (USA) under Main Menu
 Figure 2


3)      Select Accounting Periods
 Figure 3


4)      Click … button next to Never Opened. Select Open from Control Statuses
 Figure 4