Reader Challenge - Display a popup applet from inside a Shuttle Applet

This article is a break from the usual style of where i state the problem and provide the solution.

You are encouraged to try and work out this problem for yourself, it will take < 5 minutes to prototype. This gives the reader an opportunity to solve a tricky problem, and learn a few things along the way.

To start with, this challenge is almost impossible (this adds to the fun), there is a Siebel product defect on this issue. You can view the details of this on Metalink (Bug ID 12-KIGMEO).


This is a horrible defect, basically the behaviour is that you can use ShowPoup to display an applet anywhere in the Application, except inside Shuttle applets.


If you try to use Showpop inside a Shuttle, the popup appear appears in base mode and all the buttons are greyed out.


and when you close it, the shuttle applet re-appears but gets re-arranged like a picasso painting.

There are actually other ways of achieving the same behaviour, for example, you can close the shuttle and open up another applet from the base applet or you can open up a custom IE window that looks like an applet.

But this is a purely technical challenge, and the requirement here is to display a Siebel popup applet from inside a Shuttle Applet, it sounds simple enough.

As always there is more than one solution, so its not entirely impossible, we'll revisit this article again in a several weeks.

Selectively enable/disable multiple buttons based on ShowPopup

Second place in our Impossible Siebel Poll results was a requirement to have two buttons on an applet, that call two different popup applets.

The challenge was to selectively enable/disable these buttons, this is not possible using orthordox config methods, because the buttons are based on the same method.

In this article i'll go through 3 solutions that enables us to control these buttons individually.

Solution 1 - Browser Script hack

The basis around this solution is really a DOM hack, and is implemented as follows.

We take a handle on the control, and change the class from minibuttonOn to minibuttonOf, this causes the button to be styled as an disabled button.

This allows us to control multiple showpopup buttons based on the control name.

The disadvantage of this trick, is that you cannot do complex PreCanInvoke logic, outside of the current UI active fields, without doing a round server trip.

function Applet_Load ()
{
if (theApplication().GetProfileAttr("InvButton1") == "Y" )
{
var btn1 = this.FindActiveXControl("Button1");
btn1.innerHTML = "Button1";
}

if (theApplication().GetProfileAttr("InvButton2") == "Y" )
{
var btn2 = this.FindActiveXControl("Button2");
btn2.innerHTML = "Button2";
}
}


Solution 2 - Server Script + Browser Script

This solution puts our PreCanInvoke logic in server script which offers more flexibility, and should be used over the DOM hack when possible.


  1. Configure your button as follows



    You will notice that instead of using the method ShowPopup, we are using custom methods for our buttons.



    But we still configure the user properties as normal, remember to replace the applet and desired mode with your own.



  2. Put the following code in the Applet_PreInvokeMethod section under browser scripts

    function Applet_PreInvokeMethod (name, inputPropSet)
    {
    var iOperation = "ContinueOperation";
    try
    {
    switch(name)
    {
    case "EventMethodButton1":
    case "EventMethodButton2":
    iOperation = "CancelOperation";
    inputPropSet.SetProperty("SWEMethod","ShowPopup");
    this.InvokeMethod("ShowPopup",inputPropSet);
    break;
    }
    }
    catch(e)
    {
    theApplication().SWEAlert(e.toString());
    }
    finally
    {
    }
    return (iOperation);
    }

    What this does is redirect our custom methods to a generic ShowPoup method, that is interpreted by the class code to display our popup applets, that we configured in the control user properties.

  3. Because we have configured our buttons to invoke different custom methods, we can use normal PreCanInvokeMethod logic to selectively enable/disable our controls.

    function WebApplet_PreCanInvokeMethod (MethodName, &CanInvoke)
    {
    var iOperation = ContinueOperation;

    try
    {
    switch (MethodName)
    {
    case "EventMethodButton1":
    case "EventMethodButton2":
    if (TheApplication().GetProfileAttr("InvButton1") == "Y" )
    {
    CanInvoke = "FALSE";
    iOperation = CancelOperation;
    }
    else
    {
    CanInvoke = "TRUE";
    iOperation = CancelOperation;
    }
    break;

    }
    }
    catch(e)
    {
    //error handling goes here
    }
    finally
    {
    return (iOperation);
    }
    }

  4. If you have already attempted the above instructions and have found that it doesnt work, there is a very obscure trick that enables the entire solution to work.

    You need to enable the ShowPopup property for the control

    How this works is not clear, because if you look at the help files, this is the description of this property

    • This property should not be set to TRUE on a button if there is underlying script that uses the application object method, GotoView.

      If this property is set to TRUE and TheApplication.GotoView is used, this causes the view to be opened in a new browser window. The Siebel client UI does not support a Multiple Document Interface (MDI) architecture, so this combination is not supported


    This has vague if any reference to what we are doing, but it serves our very exact purpose. Thanks to DMc for this trick.


Solution 3 - Server Script + Browser script + Accelerators

This solution was provided by one of our readers Dos and he/she donst use any tricks, just really creative thinking.

This solution is based of a SR "How to launch a popup applet via an applet menu? (Doc ID 762230.1)", which shows us how to use commands to display popup applets.

We are going to take advantage of this behaviour and use some browser script to call our commands.


  1. Configure some commands to display our popup applets



  2. Define the keyboard accelerator to invoke these commands.



  3. Configure hidden applet menus that invoke our commands



  4. Configure some buttons on our applets to trigger a virtual click on our invisible applet menus



  5. Put the follow browser script in your applet, to send keys to the UI, corresponding to our keyboard accelerators


    function Applet_PreInvokeMethod (name, inputPropSet)
    {
    var iOperation = "ContinueOperation";
    try
    {
    switch(name)
    {
    case "EventMethodButton1":
    var WshShell = new ActiveXObject("WScript.Shell") ;
    WshShell.SendKeys("^1");
    WshShell = null;
    iOperation = "CancelOperation";
    break;

    case "EventMethodButton2":
    var WshShell = new ActiveXObject("WScript.Shell") ;
    WshShell.SendKeys("^2");
    WshShell = null;
    iOperation = "CancelOperation";
    break;
    }

    }
    catch(e)
    {
    theApplication().SWEAlert(e.toString());
    }
    finally
    {
    }
    return (iOperation);
    }


  6. Use Serverscript PreCanInvoke to control whether these buttons should be enabled or disabled.

Its encouraging to see so many different solutions for something that is supposedly impossible to achieve. I can imagine all the BAs who are reading this, getting funky ideas on how to use the application.

Because i once told a BA, that doing the above was not possible, i hope that person isnt reading this blog.

Display different Popup applets from a single button click

The frequency of articles on Impossible Siebel has slowed down due to current project responsibilities, but i'd thought i say a quick hello by responding to a reader question.

This article has been requested by our good friend Neel, over at Siebel Unleashed.

Requirement

Display a different popup applet on the same button click depending on certain conditions.

Solution Overview

  1. Create two buttons that will invoke ShowPopup to display our different Popup applets.
  2. The above buttons will be made hidden
  3. Create a master button that will programically click the desired hidden button to display our desired applet


Implementation

Configure two buttons as follows









Control Name: Button1Method Invoked: ShowPopup
User Property NameValue
ModeQuery
PopupPopup Applet 1
Control Name: Button2Method Invoked: ShowPopup
User Property NameValue
ModeQuery
PopupPopup Applet 2


Configure a master button that invokes a custom method and click the above buttons based on a profile attribute.

The following code should be put behind PreInvokeMethod on the applet in browser script


var retOperation = "ContinueOperation";
switch(name)
{
case "EventMethodTest":
retOperation = "CancelOperation";
var oAppl = theApplication().FindApplet("My Applet");

if(theApplication().GetProfileAttr("WhichButton") == "Button1") {
var oCon = oAppl.FindActiveXControl("Button1");
}else{
var oCon = oAppl.FindActiveXControl("Button2");
}
oCon.all[0].all[0].click();
break;
}
return (retOperation);


Once you are happy with the above config, you can make the two ShowPopup buttons hidden.

There are various ways of doing this, you can make the buttons hidden using browser script on applet load.

var ctrl = this.FindActiveXControl("Button1");
ctrl.style.visibility="hidden";
var ctrl = this.FindActiveXControl("Button2");
ctrl.style.visibility="hidden";


Another way is to provide ON and OFF states for the button, and assign it a blank image. Maybe our readers know of better ways to do this, i'll leave this open for comments.