Table Headers : Tabular Layout Trick

Table Headers : Tabular Layout Trick

Updated 18th March 2020

[Update Start

Thanks to assiduous reader Steven Robert (see the comments) who reached out and pointed out some annoying side effects and  a requirement, now I get to revisit this topic after a while away. As luck would have it, I was working on a similar situation to the one Steven describes, and I had not been timely in updating this post. Thanks to him and here is the updated version of the concept, with explanations.

  1. As the original post mentioned, and Steven pointed out, the selector used in the example is unreliable
  2. Steven proposed a new selector and solved that issue, making it multi-column as well

But the downside is the lack of display when the table is first instantiated. We need something capable of reacting before the think cycle kicks in.

In order to  achieve something like this, our “payload” needs to be part of the table that is displayed automatically. So the obvious candidate in this case is the label extension, since the first column is actually a label anyway. You could extend this concept to include other controls, but  it would require more heavy lifting as you would probably end up, if you were unlucky, building an entire Entity Container. We covered that in the JavaScript Extensions book and it isn’t usually a short effort. Anyway, we have a label so we are cool.

Our label extension has a mount key which fires when the label is displayed. So if the table is displayed, the label code will kick in. So we can be ready as soon as the table is ready. Secondly, we could in theory add several label columns and have custom headers for each of them (you could of course achieve that using non-JavaScript techniques).

Here is the walkthrough based on the previous Project (with the credit cards and visa cards which are derived as a subset of the credit cards).

  1. Add a label in the row in the table and add custom properties. It should display whatever attribute is appropriate.
  2. Generate a standard label extension and edit it a bit.
  3. Add the custom properties to trigger the code when the label is displayed.
  4. Add another label if you want (I ran out of originality but added a second one for demonstration purposes).
  5. Fire it up in the Debugger, and then in the Browser.

I didn’t go all the way to deployment but it looks like it could be elevated into a viable concept. Also, I wasn’t a very good citizen as I didn’t do any checking to avoid my code running every time the label is instantiated – I would most likely check to see if the header already had the text I wanted to avoid setting it again.

And finally, of course if you want the Project Zip just leave a note in the comments!

Here is a walkthrough video. Hope it makes sense!

Update End]

Original Post :

There is always much discussion when users first discover the Interview tab. Let’s be honest – not all of the comments are exactly positive. It all feels a bit, well, basic.

There are a number of things that catch you out at first (and indeed, later). So let’s take a moment to study tabular layouts and a common issue.

For this example I’m going to use the same project (Credit and Visa Cards) as the previous post, since that gives us two entities to work with.

Tabular Layout

Let’s consider that you want to display both entities using tabular layout. You create a Screen and set them both to tabular display. But let’s assume that you want to display the Visa Card with a couple of specifics. You want to include the provider of the credit card. So let’s set that up as a Value List and use an attribute on the Credit Card, and infer it on the Visa Card:

Table Headers Tabular Layout Trick 1So, with that now done, we want to display the Visa Card provider in the Entity Collect (as it is an inferred entity, we cannot use an Entity Collect). But we want to display it as a label as you can see in this screenshot (we added a name to the attribute as you saw in step one so we can reference it in our Screen:

Table Headers Tabular Layout Trick 2Notice how we added a label and used that to display the text of the provider? Using a label ensures three things

  1. It is read-only
  2. If the user is tabbing from input to input, the cursor will not get stuck in that field
  3. It doesn’t look like a read-only input, just a label (which is what we want).

But the downside is that the label does not have a table header in that column, since the Interview designer only adds those for Inputs:

Table Headers Tabular Layout Trick 4

I find it a shame that we cannot put table headers in this “tabular” column, since in HTML a table should have column headers. In fact if we take a moment to inspect this table in the browser, we note that annoying, there is a table header in the table:

Table Headers Tabular Layout Trick 5

So, we need to get that table header populated with our chosen text. But how shall we do it? We don’t want to create an Entity Container extension, since that would mean we have to do the whole thing from top to bottom. So we only want a little tiny change. We have a couple of choices.

  1. Create a Style Extension for the Entity Collect
  2. Create a Label Extension for stealth modification

Let’s try the first option, since it reveals some interesting facts about Styling Extensions. Firstly, get ready by doing the following; change the text associated with your entity in the Interview by double-clicking where the rectangle is, and entering whatever text you would like to display in the missing header.

Then add a compound Styling Extension to your Project. Tabular Containers allow for nested styling, like this:

OraclePolicyAutomation.AddExtension({
style: {
tabularContainer: function (control) {
if (control.getProperty("name") === "xContainer") {
style: {
headerRow:
YOUR STUFF GOES HERE

}
}
}

}
});

Notice the “headerRow” is a child of “tabularContainer”. And notice the line that says YOUR STUFF GOES HERE. Now for an interesting fact about Styling Extensions. They behave, to a reasonable degree, just like Control Extensions. They are really one and the same thing – the main difference of course is the handlers that are exposed in Control and Interview Extensions.

Drop jQuery into your resources folder, and then replace YOUR STUFF GOES HERE with the following line:

$("#opaCtl4th0").text(control.getCaption());

Of course, the jQuery selector may be different for you but it is easy to find the “header” I illustrated in the previous screenshots. Open your Project in a real Browser (Ctrl+F5) for debugging and take a look at the results:

Final Header Result

Our Styling Extension has added the text to the header, drawing it from the Interview Screen Entity Container definition, and we have it where we want it. Of course, you could style it as well.

But it goes to show that Styling Extensions are really not very different to Control Extensions!