Welcome to the OPA Hub!


Tag Archives: Custom Label

Detail Pop-up in Oracle Policy Automation

Detail Pop-up in Oracle Policy Automation

The other day someone came to me with a curious and interesting problem. They had a number of entity instances, inferred in an Excel spreadsheet. These had to be displayed in the usual way with an Entity Container in a Screen of Oracle Policy Modeller. So far so good, I hear you say.

Detail Pop-up in Oracle Policy Automation 1

The inferred attributes (which in the end would probably be coming from a data source, but for now come from Excel as inferred instances) included a Text attribute that was frankly far too large to display correctly in the Screen, given that there might be a few rows of instances in the final result.

We experimented with lots of different layouts, dynamically hiding and showing items based on various criteria in order to make room, but in the end we came to the conclusion that we needed some sort of Detail Pop-up in Oracle Policy Automation – something that could be called upon by the user as and when they needed it, but ignored (and invisible) when not needed.

Here is the starting point for our adventure.

The Screen above is populated with all the instances of the student’s scholarship. On the left is a set of information that we need to display on request. Normally we will only display the name of the Scholarship. You will see in the list of attributes there is an overview ( a text attribute), a deduction ( a currency attribute) and a renewable status (a boolean attribute). There are a few others, including the contact details (a text attribute, which is a URL).

So we are going to customise the label control I have just described. It is “inside” the Entity instance loop : so in reality there will be one per instance. We need our label to contain, as you would expect, the correct information. We wish to avoid pop-ups (nasty!) and dialogs (too complex for a simple window) and tool-tips are too small and simple for the data we have. The label shown will have a custom property called “name” and will be used as a hook for our JavaScript Extension.

We experimented with all sort of things before we went for this option : JavaScript is a last resort. We were frustrated by the behaviour of hidden items that appeared slowly (we could see “uncertain” appearing before the out of the box JavaScript populated the bound controls). So it was going to be JavaScript.

So,  our Detail Pop-up in Oracle Policy Automation needs to meet these challenges. We are going, as a simple demonstration, to use a CSS toggle to show or hide the relevant data for our instances. We can set the scene as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.area {
position:relative;
color:#0645AD;
font-weight:400;
}
 
.area:hover {
text-decoration:underline;
text-decoration-color:blue;
cursor: pointer;
}
 
.fixed {
position:absolute;
top:190px;
left:465px;
border:0;
z-index:9999;
background-color:#FFF;
display:none;
height:300px;
width:420px;
float:right;
text-decoration:none;
text-decoration-color:#000;
text-color:#000;
padding:5px;
}

The above CSS file sets up two main classes and a pseudo-class for a mouse hovering over our row. The area is the area we will normally show – with just the name – and the fixed area is a fixed DIV which will display (or not) when we decide we want to visualise the information. Now for the main content of our customLabel extension. Here is the mount key with as usual, my simplistic attempts at coding : for the umpteenth time I’m not a professional – but my job is to show something can be done, and let other’s get on with making it happen.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
 
if (control.getProperty("name") == "xLabel") {
return {
mount: function (el) {
var maindiv = document.createElement("div");
maindiv.style.visibility = 'visible';
maindiv.innerHTML = interview.getValue("scholarship_award", "scholarship", control.instance);
maindiv.classList.add("area");
maindiv.setAttribute("id", interview.getValue("scholarship_award", "scholarship", control.instance));
el.appendChild(maindiv);
 
var tooltipdiv = document.createElement("div");
tooltipdiv.style.visibility = 'visible';
tooltipdiv.classList.add("fixed");
tooltipdiv.innerHTML = control.getCaption();
tooltipdiv.setAttribute("id", interview.getValue("scholarship_award", "scholarship", control.instance));
el.appendChild(tooltipdiv);
 
$("div [id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").click(function () {
$(".fixed").hide();
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").html("<h6>Name : " + interview.getValue("scholarship_award", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6>Overview : " + interview.getValue("scholarship_overview", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6><b>Renewable</b>: " + interview.getValue("scholarship_renewable", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6><b>Maximum Value</b>: " + interview.getValue("scholarship_deduction", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6><b>Eligibility</b>: " + interview.getValue("scholarship_eligibility", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6><b>Minimum Grade</b>: " + interview.getValue("scholarship_min_grade", "scholarship", control.instance) + "</h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").append("<h6><b>Contact</b>: <a href='" + interview.getValue("scholarship_contact", "scholarship", control.instance) + "' target='_blank'>SFAS Office</a></h6>");
$(".fixed[id='" + interview.getValue("scholarship_award", "scholarship", control.instance) + "']").toggle();
});
 
}

Here is the review of the Detail Pop-up in Oracle Policy Automation code shown above, starting with the usual check to make sure we are only working with our label and not any other label on the Screen. In lines 6 to 11 we add a new DIV (to replace the one that contained all those %substitution%s , and we populate it with only one attribute. Since that attribute is also unique, we use it as a handy way to populate the HTML id attribute.

In lines 13 to 18 we create a second, hidden DIV that uses the fixed class shown above.

In lines 20 to 29 we set up the click event so that the user can click on the label and the hidden text will be revealed. The code preview (I notice) has eaten the ending part of the line, so use the PDF version instead. Notice the use of getValue, with the entity name and the instance, to ensure that we create a DIV with a unique name and unique content. The content will be toggled (hidden or shown) when you click on it.

Finally the unmount is very standard, cleaning up our various pieces by removing them.

1
2
3
4
if (control.getProperty("name") == "xLabel") {
$(".area").remove();
$(".fixed").remove();
}

The end result looks like this, before the click:

Detail Pop-up in Oracle Policy Automation 3And after the click:

Detail Pop-up in Oracle Policy Automation 4

Our Detail Pop-up in Oracle Policy Automation prototype gives the user the information they need when they need it. Of course it can be extended and transformed into something much less ugly, but this is a good start. You can find the PDF in the Shop, it’s free!

JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling

JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling

Sometimes I get distracted. I was supposed to be preparing for a workshop last night on an unrelated, Siebel-centric topic. I happened to be reading (again) through some material on our sister site, https://siebelhub.com, and I came across an example – which I have always been impressed by – from Duncan Ford, one of the Siebel Open UI and JavaScript gurus who contributes to the Siebel content on our blog. And it got me thinking about and Oracle Policy Automation JavaScript Extension Custom Header as a Timer.

The basic tenet of the script was building a set of statistics for timing performance : how long did such and such a page take to load and be ready, in a sense. In Siebel-world, this is a constant worry and ongoing process. So I got distracted by this and thought about Oracle Policy Automation and how we might use some of the ideas in our own script. I settled on the basic principle that I would want to know about how long it took people to finish a given Screen (ultimately you could extend it to the Stage concept as well). So not directly about performance, more about user time.

To do this, I figure we already have a bucket-load of exciting charts from the Hub :

JavaScript Extension Custom Header as a Timer

You know the sort of things I mean, available for each project : you can grab a set of information about a Project, change the type of chart, decide how to split the axes, decide which version to look at, filter on Service Cloud criteria and number of days and so forth.

These are great  tools. Of course, you also might have the mindbogglingly powerful In-Memory Policy Analysis with TimesTen and so on.

But you might not have any of that to hand, and you might want to work out how much time, each person spends on each Screen. Of course the navigation paradigm in Oracle Policy Automation is different to a Customer Relationship Management application like Siebel – you can go back and forth between the Screens quite a lot. All I really want to do in this case – because it was useful to me – was to identify the cumulative time spent on each Screen, and display it in the Browser at the end of the Interview:

JavaScript Extension Custom Header as a Timer

It sounds really easy but there are a couple of things that will be interesting to talk about along the way.

JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling  – Data

I decided to choose the customHeader as my starting point. The documentation states that this renders the header for an interview. So by logical extension it probably has the things we might need :

  • Access to the Interview Object
  • Access to the Stages and Screens in the Stage
  • Adding code that does not implement any UI probably won’t cause a problem, since the UI does not have to display a Header (it’s an option in the Styles dialog)

For the second part of the requirement, the display of the results, I decided to use the customLabel approach with jsGrid, similar to the example back in December of last year.

So I knew I would need 2 files, one for the custom Header and one for the custom Label. Since the results would only display on the last page (“Interview Complete”), I wanted to be able to pass the results from the Header to the Label easily. So how did the JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling work out? Well, as usual I was just experimenting so it is rough, ready and not very robust. But it is interesting enough to provide some talking points. Let’s look at the code for the Header first.

First the opening salvo of the customHeader:

JavaScript Extension Custom Header as a Timer

  1. We are going to store results in an array of JavaScript objects. This is similar to how the actual Screens are accessed in the Interview, and also it allows us to plug the data straight into the jsGrid component.
  2. So here is the Array
  3. I’m loading the set of Screens here. Be aware, that the Screens you load will only be those in the current Stage. So our myScreens array will be used to store (as you navigate) all the screens in all the stages, to have only one big array when you have finished.
  4. I’m checking in my Array of Objects to see if the Screen we are on has ever been visited : is it in my Screens array?
  5. If it is in my Array, this is not the first time you have been on the Screen in question. We update the information about the Screen in the Object, calculating the elapsed time using a very rough and ready technique.

JavaScript Extension Custom Header as a Timer

Here is the rest of the script, which I have split out into a second part for readability.

  1. If the Screen is not in myScreens, then it is a new Screen. We add it and set up the basic information.
  2. We hook our myScreens array to the Interview object.

JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling – Label

Over in the Label code, the process is very familiar:

JavaScript Extension Custom Header as a Timer 5

  1. Create a custom DIV on the final Screen using the Custom Property “name” to make sure we only execute on the label we are interested in. Get a reference to our myScreens array.
  2. Spawn a jsGrid from the DIV (which implies of course that jQuery and jsGrid files are in the /resources folder of your Project).
  3. Build the field object, noting that you can format the fields, or add / remove fields as you see fit from your array of Objects.

So if all goes according to plan you might get something like this. Note that the whole thing only works if you navigate normally – that is to say you navigate using the navigation Buttons or stage Buttons. Using the Debugger tree on the left does not have the same effect at the array will be empty. The array will also be empty if you do not reset between each debugging session. Once deployed, there should be none of those issues of course, or you could Ctrl+F5 to debug in Chrome or your favorite browser.

OPA 12 - JavaScript Extension Custom Header as a Timer in Oracle Policy Modelling 6

This being a bit of an experiment, I didn’t go much beyond 5 screens in 4 different stages, nor did I add any events to time the Stages, or to time Controls  – such as “on Focus” and “on Blur” which I thought about doing to be able to get the times in and out of individual controls and which I might do at some point.

JavaScript Extension Custom Header as a Timer – Conclusion

Anyway I hope the ideas, if not the implementation, have given you some pause for thought – namely how to get the Screens and Stages and load them into your own Array, and pass them to other Controls. The experimental code is on the OPA Hub Shop, search for customHeader.

Have a nice day!