Siebel Open UI – Bringing Back The Context Menu

First a brief teaser about the subject at hand…

…It came ranking at third position in the infamous Siebel Hub’s Pyramid of Pains. Those Siebel High Interactivity features we are missing so dearly in Open UI. And true, this is one which I too would like to count. Though I understand perfectly fine the Siebel development team is not keen introducing features which do not meet the web standards based approach they remain focused on. Using a context menu is one of those debatable subjects, should a context menu belong to a web application?

2015-06-01 17_46_56-EasellyThat said, I reckoned to give it a shot. Why? Because the vast majority of the existing Siebel customer base are Call Center “type” of implementations. At least running on a desktop of some kind, with a mouse attached 🙂

Where did I start? Well, just by fooling around with the Google developer tools. My initial idea was to mimic clicking the menu wheel button. Then trying to move the applet menu which would render to another position. I wasn’t looking forward having to deal with the complexities implementing a custom context menu from scratch. Please no. Why re-invent the wheel?

First of all, would the JQuery trigger() statement work against the menu’s element? Just a random applet on a random view.

2015-06-01 19_43_40-_new  3 - Notepad++

Guess what, the applet menu popped up. Hopeful start. Next finding the appropriate mechanism to capture the right-mouse button + some additional key. Just overriding the browser’s context menu by-default did not seem such a good option.  Rather have a key-mouse combination instead, to selectively switch between the regular context menu and the Siebel context menu. I opted for the “Alt” key and started off with the following piece of test code:

2015-06-01 19_54_38-_new  3 - Notepad++

Also, no problem here. Next step, experimenting with the JQuery’s .animate statement. Googling a bit showed that the usage is dead simple. Obviously I did not want a true animation to appear, rather just take the feature with a sub-second transition time, so the beholder of they eye would not witness any transition.

Well, that was the idea. The .animate routine accepts coordinates to instruct where to animate a certain DOM element towards. Just by inspecting the DOM I found that once clicking the menu button identified in this example by the selector $(“#s_at_m_5”), the actual menu appearing would be identifiable by $(#s_at_m_5-menu”). And the event parameter passed by JQuery would provide using e.pageY and e.PageX the needed target coordinates where the mouse pointer was located at the time the .mousedown event occured. Nice.

2015-06-01 21_26_58-_new  3 - Notepad++

So, at the point the context menu started appearing more or less where I expected. More or less because there was a strange Y-axis offset. Interestingly enough when logging the coordinates, these turned out to be correct. But the .animate would give an offset of exact 150px . I can live with that, did not care for now to research this particular point deeper.

2015-06-01 17_30_19-My Accounts_ 3 Com

Because I want to suppress the default context menu from the browser, some additional logic was needed. Googling a bit revealed the simplicity of the solution.

2015-06-01 21_39_45-_new  3 - Notepad++

But what to re-instantiate the default functionality again? Simply the opposite of binding to the “contextmenu” event, unbinding the event.

2015-06-01 21_45_57-_new  3 - Notepad++

Things are looking great so far, time to build an actual applet physical renderer. Starting of as always from solid boiler plate code. Really, it saves you loads of time. Much better than copy/pasting from a previous file.

First of all I had to deal with the simple stuff of making use of dynamic selectors instead. Since I found the menu button and the menu itself (which essentially is a list of links) are created by Siebel using the Applet’s Id being respectively $(“#s_at_m_5”) for the button and $(“#s_at_m_5-menu”) for the menu itself.

Using a straight-forward regular expression (straight-forward here means, I Googled it instead of re-inventing it) I was able to substring this number from the applet’s full Id.

While further building the PR and testing it along, I found that it did not work that well. Inconsistent. Sometimes the default context menu did not get suppressed, sometimes the applet menu showed up but did not animate, sometimes the default context menu did not get re-instantiated, sometimes a mix of these… I believed this to be a timing issue. Therefore setTimeout to the rescue. Maybe there is a better alternative like using the stopPropagate to prevent any events from bubbling up the DOM tree. For now I did not really care to research this further, as I found inserting two setTimeouts did the job.

Code wise this became the end result.

2015-06-01 22_08_11-_Z__Client_PUBLIC_enu_23044_SCRIPTS_siebel_custom_SiebelContextMenuPR.js - Notep

For now I just build it as stand-alone physical renderer for list applets. No big deal to create one for form applets too. Obviously if this should be application-wide behavior we would need to override the respective DEFAULT LIST RENDER and DEFAULT FORM RENDERER physical renderer files instead. An interesting previous post on this subject can be found here, while discussing rendering navigation buttons as glyphs instead of the ugly out-of-the-box sprite.

This concludes this post. I am looking forward to comments, suggestions and improvements. An issue I was yet unable to tackle is that the first time I request the Siebel context menu, it shows up in its original location. Doing a second “Alt” + “Right mouse click” fixes that. Other small deficiency is that sometimes you will see the applet menu flickering in its original location before showing up at the cursor’s location.

The complete PR can be grabbed here.

– Jeroen



5 thoughts on “Siebel Open UI – Bringing Back The Context Menu

  1. Hoi Jeroen!

    I am a recent reader of your blog, and a fairly recent (~1.5 years) Siebel developer. Thank you for all the great information you publish!

    I am attempting to implement this right-click menu functionality. Using your code, some code from @lex for something similar, and some code from stackoverflow, I am using .contextmenu rather than .mousedown. I have it working (woo!), but I am having the exact same problem as you: the first time I right-click the menu appears in its original position.

    I have attempted various “fixes”, especially attempting to modify the .css of the “-menu” item first before triggering the click (via a couple of different ways). [I have to interject here that I only started to learn Javascript and jQuery in the past few months as well.]

    All that to no avail.

    Did you happen to ever look back at this and figure out why this is behaving this way and/or how to fix it? Did any of your readers?

    Dank je wel (or is it “dankjewel”?),

  2. I left a comment on 29 July 2016 stating that we were trying to implement this using a slightly different approach (directly on “.contextmenu” instead of a right-click) and yet we were having the same issue with the first click opening the menu in the original location. I then asked if anyone had overcome that issue. It seems that comment never appeared.

    In the interim, I believe that I determined the root cause of the issue: That menu does not appear initially in the DOM – it seems to be created/added dynamically by code after clicking on the menu button for the first time. (After that, it stays in the DOM with “display: none” when not on screen; but initially it cannot be found). So attempting to animate (or in our case, directly changing the styling using “.css”) a non-existent element will not work.

    My solution:
    Using jQuery’s “.on” you can add an event handler to a yet-to-exist element – as long as the non-existent element is (will be) a child of the element on which you use the “.on”. The menu element in our case is a sibling and not a child of the menu button, so I used “.on” on the immediate parent which is a with class “.miniBtnUIC”.

    Using Joroen’s variable, it looks like this:
    $(‘.miniBtnUIC’).on( [event], selBtnSiebelMenu + ‘-menu’, function () { … });

    For my [event], I originally tried to use ‘click’, but that only works if you click on the menu itself once it appears. After really looking at it, the most logical (to me) candidate seemed to be ‘focusin’. However, ‘focusin’ is not a mouse-driven event, so there is no “pageX” or “pageY” associated with it.

    I then researched ways of determining/being notified when an element is added to the DOM. i found a good way, but again, there were no mouse pointer coordinates to be had.

    So what I ended up doing (in my development, this is currently limited to one List Applet’s Physical Renderer) was creating two “global” variables that hold the pointer coordinates whenever there is a ‘.mousedown’ event. Then I added the handler to the ‘.focusin’ event mentioned above, and used those “global” variables inside the handler function to set my ‘top’ and ‘left’ CSS for the menu itself.

    It works!

    The only sort of drawback is, since this occurs any time the menu is being given focus (not just a right-click), when you left-click the menu icon, the menu appears with the top left corner at the mouse pointer – rather than appearing centered directly below the icon. To me that is not a big deal since the icon is small (so the menu does not move it that much) and most of our users will right-click anyway if they can.

    Now I am trying to make other tweaks like: not letting the menu go off-screen if the right-click takes place close to the right edge; not letting the window or Applet scroll down (especially in IE11) if the right-click takes place close to the bottom edge; having the right-click also select the row that the mouse is on so any menu selection will affect that row.

    If anyone finds a better way to implement the main right-click functionality from first click onward, please let me know.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s