Set Tab layout order defect 8.1.1.2

Last year i looked at a Siebel feature that prevented tab orders from being adhered to on Popup Form applets.

This was tested in 8.1.1.1, but under 8.1.1.2, this solution dosnt work anymore. The background on this can be found here.

[Problem]

The root cause this time around, is just as obscure but with our background on this problem in 8.1.1.1, the reason why it is broken in 8.1.1.2, is more easily identified.

If you recall from last time, Siebel generated the HTML Tab index in the browser source code, but failed to provide it with an identifier.

In 8.1.1.2, Siebel dosnt generate the tabIndex property or its value at all, so the solution i'm about to provide is a going to be another UI hack.

Although it is not as elegant as the last solution, it has the advantage of being backwards compatible and should be quite future proof.

[Solution]

Since Siebel dosnt generate the HTML Tab index anymore, we need to find a way to make this information available to the browser. To be thorough, you should turn on all the hidden properties in Tools, by setting this option in your tools configuration.

ClientConfigurationMode = All

After that exercise, i've found that only the Height/Width properties work. So we are going to pick one, and for this example i'm going to use the control height property and ask that developers populate that with the desired HTML sequence.

When Siebel renders the controls on this applet, it will be stretched out of proportion, because we used the control height property as our HTML Sequence indicator.

To get around this problem, we will manipulate the DOM on applet load and inject the tabIndex property, with the height value that we have configured above, and at the same time restore the height to the standard 24 pixel, for all the field controls on the applet, before the user has a chance to see it.

Heres how its done, copy the following code and put it into your browser applet load.

fixTabOrder8112(this,"any valid control name");

function fixTabOrder8112(that,ctrlName)
{
try {
var oControl = that.FindActiveXControl(ctrlName);
oControl.document.body.style.display="none";
var oObject = oControl.document.body.getElementsByTagName("object");
for (var i=0; i < oObject.length; i++){
oObject[i].tabIndex = oObject[i]["height"];
oObject[i].height = "24";
}
   oControl.document.body.style.display="block";
} catch(e){
} finally {
}
}

If you look carefully, you'll notice that i hide the entire contents of the applet, ensuring that all the controls are invisible while the code re-draws all the controls, and re-displays the content when the routine is finished.

You may or may not notice a small moment of flicker as the applet is being worked on, but it should be un-noticable. To get a second opinion, I asked a BA to watch it in action and watch out for the flicker, and when it was over, she stated "I didnt see any flicker!" If you are testing this, try it out on both thin and thick client to see the behaviour.

This will work for the majority of cases, but if you have a Popup form applet with varying control heights such as text areas, then you have to work a bit harder to get this solution to work.

The basic idea, is to append the HTML sequence to the end of the height property, split the values to get your separate properties values and use the above method to alter your HTML source.

The original defect was discovered in 8.1.1.1, and i was told a fix was pushed for 8.1.1.2. We have discovered that it is still outstanding, and 8.1.1.2 has also broken our fix for 8.1.1.1, but customers who are still suffering from this defect, now have a new solution.

Trap submit button in TBUI

In my last article, we encountered a new behaviour in Siebel that allows TBUI to re-use its buttons and dynamically generate different button labels depending on what view the user is on.

For example, you have 5 views in your TBUI task, on the first 4 views, this button would read "Next", but as you navigate to the final view, this button dynamically changes to "Submit", click "Previous" and it turns to "Next" again.

Image of TBUI Playbar


This behaviour is activated by the following control user property.

DynamicLabel Y

If you are curious enough to look at the web template to see how this works, here is the corresponding section with some cues on how to configure it.

<swe:control id="152">
<!-- Next Button -->
<!-- If of "DynamicLabel" is "Y", it shows "Next"/"Submit"/"Finish" based on -->
<!-- <forward button type> in task step -->
<td class="AppletButtons" nowrap>
<swe:this property="FormattedHtml" hintText="Next" hintMapType="Control"/>//Our magic button
</td>
</swe:control>

As magical as it may be, it causes a problem for anyone who wants to trap the event of a click on the "Submit" button, since the "Next", "Submit" buttons are the same physical button, on the same applet, and fire the same methods, so it makes it quite tricky to detect which "buttons" have been clicked.

The key to this problem is reading the button text when the user clicks on the button and then determine the next course of action. This can be done by trapping the PreInvokemethod, and using browser script to read the button label.

The following code shows how this can be done:


function Applet_PreInvokeMethod (name, inputPropSet)
{
if(name=="NavigateNext"){
sCurrentControlName=getControlLabel(this,"ButtonNext");
}
return ("ContinueOperation");
}

function getControlLabel(that, ControlName)
{
var objControl;
var sControlLabel = "";
try{
objControl = that.FindActiveXControl(ControlName);
sControlLabel = objControl.getElementsByTagName("A")[0].innerHTML;
} catch(e){
alert(e.toString());
}
return sControlLabel;

}


To make things a little more interesting, the final button can have other labels such as "Complete", "Done", "Finalize" and other custom values, and you'll also need to consider what happens when the user cancels or Pauses, in your design.

If you need to trap the "Submit" in TBUI for purposes other than this hack, keep in mind the alternative solution of cloning the applets, as mentioned in the previous article, which will allow you to stay away from the dark side.

Close Task Pane Automatically [ID 781860.1]


[Problem]

In Siebel 8, when a Task Based UI (TBUI) session is completed the task pane remains open, displaying the default task (which could be totally unrelated to the current view), even after the user clicks Submit.

This problem has been raised by the customer of Support Document [ID 781860.1] on Metalink. The customer was told that this behaviour is hard coded and to contact Expert Services.

I dont know if there was a solution provided to the customer, because the document was never updated, but this defect would have problems passing User Acceptance Testing (UAT)

[Toggle Solution]

At first glance, an easy solution would be to hijack the method behind the X button, and invoke it from browser script, but since it is not a documented API, it should be a last resort.

TBUI can be invoked by Ctrl+Shift+Y , which fires a menu command and invokes a Business service to toggle the task pane.
function closeTBUIPane()
{
var BS = theApplication().GetService("Task UI Service (SWE)");
var inputs = theApplication().NewPropertySet();
var outputs = theApplication().NewPropertySet();
outputs = BS.InvokeMethod("ToggleTaskPane", inputs);
}

This would be the ideal solution.

The business service that we are interested in is "Task UI Service (SWE)", it has the following methods

Open,Close and Toggle

The Open,Toggle methods work fine, but the Close methods seems to be disabled. It seems like when Siebel first designed TBUI, they used seperate methods to open and close the task pane, but in the end Siebel replaced it with the Toggle method.

Although we can use Toggle to close the TBUI after the user clicks Submit, but if, on the chance that the user clicks the X button on the task pane in the middle of the task (therefore closing the pane) when the user reaches the end of the task, clicking the submit button to finish would activate the Toggle method and re-open the pane.

Unless we have someway of detecting if the task pane has been already closed and not perform the toggle, this method may not be acceptable. The only way i know of detecting the state of a pane is to check the existence of the frame by using unsupported browser methods, which takes us back to our first solution.

[X Button Solution]

The following line of browser allows us to tap into the method behind the X button, and invoke it from our TBUI applet.
top.SWEFindFrame(top,"SS_TaskUIPane").TaskObj().HandleClose();


Another problem that we'll face is the Next, and Submit buttons are actually the same physical button that call the same method, TBUI will dynamically change the label of the button depending on what view the task is on, which makes this a little trickier.

There are two solutions to this,

1. Make a clone the TBUI applet and use this clone exclusively for the Submit button and put it in the final view

2. Reuse the vanilla TBUI applet and use browser script to read the button text and decide wether or not to close the task pane

The use of undocumented browser methods is not something i would normally recommend, but until Siebel provides a proper fix, this workaround provides customers with a solution that would not cripple the system if the method becomes deprecated.

The worse that can happen is you revert back to the product defect, the upside is that your application dosnt confuse your users and passes UAT.