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.


Reactions:

0 comments:

Post a Comment

Comments are open to all, please make it constructive.