Welcome to the OPA Hub!


Tag Archives: Control Extensions

Back to Basics – What are Extensions?

Back to Basics – What are Extensions?

Styling Extensions

Introduced in Oracle Policy Automation November 2016 release, a styling extension allows a designer to create styling rules and logic using JavaScript and Cascading Style Sheets. These files are contained within the deployed Oracle Policy Automation project, and should be used only if you have exhausted all of the built in Styling possibilities offered as standard in the Interview tab, Styles dialog.

Control Extensions

A Control represents a single item placed on a Screen during the design of an Interview. Typically these controls might be used by the user to enter data (for example, a Control with a Calendar attached to enter the date of birth of the applicant) or to organize data on the Screen (for example, a Container that allows for a better layout of several other items). At run-time, each Control is translated into HTML and associated JavaScript code. Introduced initially at the same time as the styling extensions mentioned in the previous paragraph, although they have grown more numerous over time.

Control Extensions Example

They are generally referred to by a name such as customLabel or customContainer which identifies the type. In a later post you will learn the origin of these names.

Evolution

Interview behavior Extensions have gradually gained in functionality, and also in terms of which Control types are available for customization. There are different kinds of extension for different needs.

Scope

If Controls represent items grouped on a Screen (and therefore on a page, as far as most Interview users are concerned), with Extensions you can also customize the real estate around the pages – whether it be the navigation styling, of a custom footer or header, or even a completely new navigation system. So extensions can be for a single Control, or for a complete Navigation system.

Naming Convention

Technically speaking, all of the examples mentioned above are called Interview Extensions in the official documentation, and they are divided into styling extensions and control extensions as you will discover. You can find the reference material at the following URL at the time of writing .

Architecture

Before looking at the different types available to us, it pays to review the architecture of the Interview and gain understanding as to how they function within it. Coming next…

Template Generator Update – JavaScript for Control Extensions

Template Generator – JavaScript for Control Extensions

Another update, quite a big one, for the template generator. We’ve added lots more information to explain how to use the generator, and hopefully how to work on the template once you have created it. In addition, we have added the Entity Container as a new extension type, so you can create scrollbar-friendly lists of instances for your Entities. Read on for more information. If you just want to download the new version leave a comment and I will send it to you. In the not too distant future we will be releasing it to the OPA Hub Shop, but for now just ask and we can pass it to you.

Control Extension Template Generator : New Form Available

If you don’t intend to use the template code straight away, you can now just print the Form and keep it for later. At the moment the form just dumps the code in plain text, it does not pretty-print it like the screen output, but the code is still ready to copy-and-paste.

Control Extension Template Generator : Information Added

In the Form, we have included some hopefully useful background information about using the code, what to look out for and what to know in terms of where you might want to customize the code. We’ll keep adding to this Form as time goes on, with anything we think might be useful.

Control Extension Template Generator : New Extension

You can now generate Entity Container Extensions. This template requires an extra Property and uses jsGrid to provide a scrolling layout. Again, more information is given in your Form about how to use it and how to customize it to go even further. As always, the official documentation is your friend.

Control Extension Template Generator : Example Container

New Video

And so, to close, you will find below a short video explaining the new Extension Template for Entity Containers, and giving you a bit more background about the different aspects of this Extension type. Nothing beats having a go yourself. Of course, as we always say, the code is entirely for entertainment purposes, never for production, and it’s your own fault if you don’t get a professional to rewrite it. But at least you will know that it can be done, and as a consultant that is often one of the most important things to know.

The video can be viewed here:

What’s New in Oracle Policy Automation 18B #2 Relationship Control Extensions

What’s New in Oracle Policy Automation 18B #2

The main thrust of this post first came into my head when I was writing one of the recent Back to Basics posts about Relationships. And as if by magic, Oracle Policy Automation went ahead and improved the product with something I felt was lacking. I should ruminate more often, perhaps they have telepathic powers over there. So in this post, What’s New in Oracle Policy Automation 18B #2, we are going to look at the new feature of the Control Extensions : the ability to customise the Relationship experience.

What’s New in Oracle Policy Automation 18B #2

The relationship above is a good example. In the course of a prototype, I designed the car and the passenger entities for a car-sharing enterprise. A car can have many potential passengers. For each journey, however, your passenger can only be in one car at a time. And yes, I understand that I could build a many-to-many and intersection the car and passengers or infer the current passengers or what have you, but this is just an example.

What’s New in Oracle Policy Automation 18B #2

So in the above example, you can see that I am in the process of selecting the passengers for each car. Putting aside the discussion about how best to model the data, there is a challenge here. The checkbox (which is the only display offered) is fine, but due to the lack of dynamism (?) in the display, the choices remain static. I mean by that you are able to choose an incoherent selection, with the same passenger being in multiple cars.

Of course, when you do so, the engine (correctly) gives you an error and you must correct your data entry. But what if we did it another way?

The core of this is the fact that now, in Oracle Policy Automation 18B, you can use the following in your Extensions:

control.getControlType() – which now will return “OneToMany” or “ManyToMany” and so forth for relationship controls. So your code could adapt the User Experience based on the cardinality.

control.getOptions() – returns an array of the different choices for the user ( the passengers in my case above). So you can retrieve the list of choices.

To help manage this kind of extension, control.getValue() returns an array of the selected values for your relationship (the instances that have been selected). So you can examine the selected values.

Let’s look at this code. It is, as always provided for educational and entertainment purposes (indeed, many will find my stream of consciousness code amusing). It is also available on the OPA Hub Website Shop page as a free PDF download. So let’s see What’s New in Oracle Policy Automation 18B #2 : Relationship Controls with an example.

 

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
(c) 2018 Richard Napier The OPA Hub Website May 2018
Educational Example of Relationship Input Controls
I will remember this is for demonstration and educational purposes only
 */
 
OraclePolicyAutomation.AddExtension({
	customInput: function (control, interview) {
		if (control.getProperty("name") == "xPassengerSelect") {
			return {
				mount: function (el) {
					//console.log("Control " + control.getProperty("name") + " is a " + control.getDataType() + ", originally a " + control.getControlType());
					var myValues = [];
					//Previous values
					myValues = control.getValue();
					var myOptions = control.getOptions();
					//console.log("Obtained list of instances for control " + control.id);
					var myDropDown = document.createElement('select');
					myDropDown.setAttribute('id', control.instance.toString());
					myDropDown.setAttribute('data-instance', control.instance.toString());
					myDropDown.setAttribute('data-entity', control.entity.toString());
					myDropDown.setAttribute('multiple', 'true');
					for (j = 0; j < myOptions.length; j++) {
						var myoption = new Option(myOptions[j].text, myOptions[j].value)
							myoption.setAttribute("data-instance", control.instance.toString());
						myoption.setAttribute("data-entity", control.entity.toString());
						myDropDown.options.add(myoption)
						//console.log("Added list option " + myOptions[j].text);
					}
					for (i = 0; i < myDropDown.length; i++) {
						currentOption = myDropDown[i];
 
						if (myValues.indexOf(currentOption.value) != -1) {
							$("select [data-instance='" + myDropDown.getAttribute('data-instance') + "']").filter("option[value='" + currentOption.value + "']").attr("selected", "selected");
						}
 
					}
					$(myDropDown).change(function () {
 
						//New Values Selected
 
						for (i = 0; i < myDropDown.length; i++) {
							currentOption = myDropDown[i];
 
							if (currentOption.selected == true) {
								myValues.push(currentOption.value);
 
								//Disable All Values Matching Selected in other instances
								$("select [data-instance!='" + myDropDown.getAttribute('data-instance') + "']").filter("option[value='" + currentOption.value + "']").attr("disabled", "true")
 
							} 
 
						}
					});
					var deselectbutton = document.createElement("button");
					deselectbutton.setAttribute("type", "button");
					deselectbutton.setAttribute('data-instance', control.instance.toString());
					var deselectbuttontext = document.createTextNode("Deselect All");
					deselectbutton.appendChild(deselectbuttontext);
 
					el.appendChild(myDropDown);
					$(myDropDown).after(deselectbutton);
 
					$(deselectbutton).click(
 
						function () {
						$("select [data-instance='" + this.getAttribute('data-instance') + "']").filter(":selected").prop("selected", false);
						control.setValue("");
							$("select [data-instance!='" + this.getAttribute('data-instance') + "']").attr("disabled", false);
					});
 
					for (i = 0; i < myDropDown.length; i++) {
						currentOption = myDropDown[i];
 
						if (myValues.indexOf(currentOption.value) != -1) {
							$("select [data-instance='" + myDropDown.getAttribute('data-instance') + "']").filter("option[value='" + currentOption.value + "']").attr("selected", "selected")
 
						}
 
					}
				},
				update: function (el) {},
				unmount: function (el) {}
			}
		}
	}
});

So what are we looking at. There are probably four key areas in this rough prototype.

Lines 18 to 27 build a multiple-select drop-down instead of the check-boxes. Using HTML 5 data attributes, each option and each drop-down (there will be  drop-downs, one for each of the car ) is tagged with the instance name and the entity name. This is useful if you intend to have a page with lots of entity-related things on it , and it was useful in the Entity Collect example from a few weeks ago as well.

Lines  29 to 33 look through the existing values of the Control (maybe the user has already been working on this page, and has now come back to it for further editing) and selects programatically all those values that were chosen previously. Otherwise when you click the Next button and then the Previous button, you will no longer “see” your selections even though they actually have been selected.

Lines 38 to 58 handle the Change event if the user selects other items in the multi-select, and ensures that the corresponding items are deactivated in the other drop-downs.

Lines 58 to 78 create the Deselect All button for each drop-down, which removes all the selected items both from the drop-down and from the underlying control values, and re-enables the values in the other drop-downs.

Once again, I state for the record that this was just a “stream of consciousness” which became a bare-bones prototype. There are lots of holes in the code, and lots of repetition because I just wrote it in a single shot. So you have been warned.

It does, however, demonstrate the new functionality, so our post title What’s New in Oracle Policy Automation 18B #2 is fulfilled. This is something you could not really do in previous versions.


Have fun!