Don’t Loose Your Precious Data

I’m sure if the team at the SiebelHub would in their series of ‘snap polls‘ start another poll soliciting for the top most UX ‘inconveniences’ with Siebel OpenUI, will find among the higher ranking  issues the fact that the ‘back button’ should be used with great care.

Great care, because any uncommitted data will be gone, forever. Have you just spent half an hour on a lengthy call report? The back button will not commit it for you, rather will throw it away… This very issue comes up again and again.

Although there is no water-tight solution, I have been testing a feasible approach using the undocumented method ‘IsCommitPending’. I found that this method of the business component class tells you whether there is in-flight data.

Just entering following on the browser’s console will tell you, if you have in-flight data:

SiebelApp.S_App.GetActiveView().GetActiveApplet().GetBusComp().IsCommitPending();

That’s actually a pretty cool framework feature, though… undocumented (hence it might change, and don’t try to ask Oracle tech support to provide further guidance…)

The IsCommitPending() returns a consistent output. Once you change any data, it will return ‘true’. The moment you either explicitly commit the data using CTRL+S or the applet menu ‘Save Record’, instantaneously IsCommitPending() will return ‘false’. Also stepping of a record, will implicitly commit the data, hence IsCommitPending() will return ‘false’ too.

So, I marched on. I created a simple applet presentation model as proof of concept to capture all ‘FieldChange’ events. On the first ‘FieldChange’ event I create a floating div with the id=datalossWarning and the default class ‘dataloss-warning-disabled’.

Per CSS pseudo-selector I add a font from the ‘oracle’ font, to serve as indicator.

checkred

I further attach a click event, which as part of this proof of concept I added to the presentation model as well. But rather, this should belong in a physical renderer instead… And rather than using the JQuery’s click event, it would be more appropriate to use the Helper class to make behavior consistent across non-touch and touch devices. But that is all for later!

Once the visual check box indicator appears, clicking the same will execute a write record as such:

SiebelApp.S_App.GetActiveView().GetActiveApplet().InvokeMethod(“WriteRecord”);

I choose to make it fade away using a simple transition. The CSS is as simple as effective.

datalosscss

The most relevant lines from the presentation model are presented below. Again, a setTimeout was required to ensure the code to be executed after all other framework code completed. Required to have the IsCommitPending() call to  return the correct value. Inspecting the value, drives simply swapping the CSS class from ‘dataloss-warning-disabled’ to ‘dataloss-warning-enabled’ or vice versa.

datalosscommitpending

The complete presentation model ‘CheckCommitPendingPM’ code for a list applet, is not more than a few lines besides the typical framework code required for any presentation model. I choose to use the ‘Init’ event, but likely the ‘Setup’ would have worked as well. Not sure if there is a benefit for either.

datalosscompletepm

I further added a few lines in my existing post loader, to remove the #datalossWarning div every time a new views loads.

datalosscommitpendingpostload

A brief demonstration puts the cherry on the cake:

Again, this is a proof of concept. Interested to hear feedback :-)

As from previous readings, you might know that enabling this across the application is due a current framework limitation not that straightforward without possible breaking out of the box functionality. Simply overriding the ‘DEFAULT LIST APPLET’ presentation model, will due to the sequence in which the OpenUI framework loads code will prevent a possible out of the box presentation model to load. So be careful there!

–  Jeroen

 

 

 

 

 

 

Catch Those Uncaught Exceptions From Your Browser In Open UI – Part II

bugsnag-logo-1A few weeks back I posted an initial article about my experiences with Bugsnag. On a quest to get more insight in ‘what happens in the browser’, because by and large ‘what happens in the browser, stays in the browser’ I bumped into this neat tool. In this space of error reporting and incident management tools, alternatives exists such as Airbrake, Sentry, Rollbar and Raygun to name a few. I choose for a proof of concept Bugsnag because it appeared to be simple to integrate as well as it’s offered as 100% free trial.

Deploying complex web applications such as Siebel which are built on top of a bundled set of libraries such as JQuery, RequireJS and CKEditor poses a real challenge. Add the diversity of browsers in the mix, and you have a nice cocktail. Just the believe that functionality will work cross-browser is an utopia. Gaining the insight in ‘what happens in the browser’ can be considered a must-have, especially in a diverse environment where Siebel is exposed on different browsers, platforms, devices, in managed desktop environments or to users in the uncontrolled big, bad, world out there.

Setting up your trial account with Bugsnag requires just a few clicks. In return you will be provided an API key and access to your own Bugsnag dashoard.

The Bugsnag ‘notifier’ library is available to be integrated in any web application. Integrating it with Siebel turned out to be extremely simple. Just adding the library as ‘Application’ / ‘Common’ did the job. Setting the apiKey followed by invoking the notify() function in the console is enough to test the essentials.

Bugsnag.apiKey = “d31fd6cda4a46a9f4e251207c8xxxxxx”;

Bugsnag.notify(“SBL-ERR-BUGSNAG”, “Log this error”);

Logging onto your Bugsnag dashboard should show within the blink of an eye the error!

SBL-ERR-BUGSNAG

Nice. But we need to do better!

When Bugsnag intercepts an uncaught exception, it would be useful to have some contextual information being sent alongside the call stack, won’t it? For that particular purpose, the Bugsnag API allows to add ‘meta data’ by using the ‘beforeNotify’ function.

I ended up with a straight-forward piece of code, which loads as Application / Common file.

  1. It creates a new class ‘SiebelBugSnagNotifier’
  2. Next it creates a dependency on the Bugsnag Javascript API (‘bugsnag-2.min.js’)
  3. Following the apiKey is set (I opted for sake of simplicity to hard-code the key…)
  4. Next the beforeNotify() function is implemented
  5. The ‘metaData’ and ‘user’ JSON objects are populated with contextual information. Other than essential static details such as Login Name, User Responsibilities, View Name & Title – I added also the raw data (if available) from the applet which had focus the moment the exception got caught.

bugsnagnotifier

Now, what happens when I on-purpose generate an uncaught exception? Well, first of all we get a nice call stack leading quickly to the error. And yes, I made a type calling ‘setTimeout’ in the /siebel/custom/CheckCommitPendingPR.js!

samplestack

Further, the view context gets provided…

details3

As well as the raw data…

details2

And the logged in user details too…

details1

All together, quite happy with the end-result. And other than logging uncaught exceptions, calling Bugsnag.notify() anywhere in your code, could be an alternative for SiebelJS.Log(). But use it sparsely in that case, since it will definitely incur overhead. And we do not want to slow-down Siebel, do we?

You can grab the code here. If you have thoughts, let me know.

– Jeroen

Siebel Patch Set IP15.5 / IP14.11 Available

Continuous development, continuous integration, continuous delivery. Siebel Patch Set IP15.5 / IP14.11 has been made available. Besides an import bug fix for those running (or needing to run) Siebel on iOS 9.01 devices… this patch set has the required bug fix for the keyboard to appropriately pop-up in list applets.

Quite a download! But that sheer size has a reason.

IP155_download

Worth to check John Bedford’s post with regards to the enhancements (yes, enhancements in a patch set) becoming available with IP15.5. Factually, IP15.5 is an Innovation Pack in its own right. To take advantage of these enhancements, an Incremental Repository Merge procedure is required.

– Jeroen

Siebel OpenUI – Deselect Content in Text Area Controls While Tabbing

Difficult to give this post a descent title. What this post is all about, is the fact that Siebel will ‘default’ select any text in list applet columns while tabbing through. In itself not such a bad feature. But there are situations where this behavior is by end-users perceived as highly unwanted. Think of notes, where a text area control potentially contains tons of carefully entered text. Tabbing through a list applet makes it prone to unintentionally wipe this precious and entered data at the blink of an eye (or better by almost any keystroke…).

This was brought to my attention by a customer. Luckily enough, the Siebel OpenUI offers such a great extensibility framework! Writing one of the most simplistic control plug-in wrappers ever, does the job. Goal of the plugin wrapper would be to ‘deselect’ the control’s content at the moment it receives focus. Instead of selecting the control’s value, it should just put the cursor at the far end of the text.

The plug-in wrapper is code is not more than a few basic lines, plus the standard skeleton code.

UnselectDataTextArea

Like any control plugin-wrapper, you need to instruct it on what control type and when to act (1). I choose to have it act solely on the “SWE_CTRL_TEXTAREA” control, regardless further context – therefore the “return true;” without any further conditions. In this case we add an additional event on the control, so the BindEvents event makes most sense (2). Finally, the actually magic happens using the “focus” event, on which we trigger a single line of code to reset the selection (3). So simple, yet so powerful.

As any control plug-in wrapper, just administer as Application / Common file.

Enjoy!

– Jeroen

Catch Those Uncaught Exceptions From Your Browser In Open UI – Part I

bugsnag-logo-1With any web application running tons of Javascript, getting track on what’s happening within the browser can be a true challenge as well as nightmare. And with the ever expanding Javascript frameworks and libraries which see the light every day, more, more and more is going on in the browser. And that is no different for Siebel OpenUI.

Recently, I got in a situation where a customer reported data loss. More specifically when sending an outbound email in reply to an inbound email. Where at the moment the user hit the ‘Send’ button, the actual email composed by the user got lost and instead an empty email was sent. Quite annoying, to say the least. More annoyingly, for the end-user: this event would go completely unnoticed. Not reproducible and with a fairly low frequency, but reported by many different users. Finding a pattern led nowhere. Since Siebel leverages the CKEDITOR library for rich text editing, this was for me one of the suspects.

I implemented a presentation model to catch the EmailSend method on the “Comm Outbound Item Form Applet New” applet, in order to get some grip on the situation. I found that by logging each and every EmailSend event through the central error logging facility exposed as business service in this implementation, that somehow in certain situations truly the data in the CKEDITOR control would be different from the data saved on the business component (and sent…). But still now clue on the “why”.

Typically a situation where you’d want to have an eye on each of the user’s browser consoles to see if any uncaught (or caught) error got reported. And especially that is a problem. Where debugging Siebel traditionally has been pretty much server-centric, the browser plays a huge role these OpenUI days.

I reckoned, I’m surely not the only one facing this challenge! Imagine you run a multi M$ or B$ eCommerce site, you surely want to have comfort and confidence that your platform runs fine on any browser or device. Assume that on Android 3.x using Firefox as browser you cannot conclude a purchase because of some unexpected error happening which no developer nor tester could have foreseen (“who runs Android 3.x with a Firefox browser”)?

It turns out there are quite some error handling frameworks out there: Sentry, Airbrake, Rollbar to name a few. And Bugsnag. Bugsnag seemed to be pretty flexible. Bugsnap is a paid service. Now one issue which might immediately come to mind: can we use such as cloud service? I agree, that might be a showstopper from a data-privacy or company policy point of view. But Bugsnag also allows for an on-premise ‘implementation’. That said, I was interested enough to give it a go. And really, working with Bugsnag is child’s play. After creating a trial account, I got it working in a matter of minutes just by adding the Bugsnag “notifier” library per Siebel manifest administration. Setting the Bugsnap API Key in the browser’s console followed by a call to the notifier’s Bugsnag.notify() and bob’s your uncle.

bugsnagerror

bugsnagerror2

So that worked out pretty fine so far. And that’s interesting too, through the Bugsnag notifier you’d have an alternative for SiebelJS.Log() for situations where it would make sense. But more importantly I needed to verify whether those nasty uncaught exceptions would be be caught by the Bugsnag notifier too, which should be the core reason to use it after all. The Bugsnag notifier hacks into the window.onerror to achieve this. To test this, I just added a throw() to one of my existing customizations to simulate it.

uncaughtexception1

You’d already see the exception’s trace mentions ‘_super.bugsnag’. So something’s going on!

uncaughtexception2

Unfortunately, not too much detail. But at least the Bugsnag notifier logged the exception. In the next post I will explain how to integrate Bugsnag properly into Siebel and how to add more Siebel contextual details whenever an uncaught exception gets logged (or when an error is logged by code per design or for debugging needs). To eventually get something similar to this….

uncaughtexception3

– Jeroen

Bye SQL Anywhere – Hello Oracle XE

oraclexe150x150

Oracle-Siebel’s product manager John Bedford published the official statement that SQL Anywhere will be replaced with Oracle XE (Express Edition) with the release of Siebel Innovation Pack 2015 Patch Set 5.

SQL Anywhere, being a SAP-owned product after the acquisition of Sybase in 2010 has served a long time. Especially in late 90s SQL Anywhere was considered a flag-ship product, with advanced capabilities. And Siebel has been bundling it with Siebel Remote & Siebel Tools ever since, quite successfully.

Other than the Mobile Web Client alone, Siebel Tools truly has been ‘fueled’ by this small and agile database engine. That said, being a 3rd party product – Oracle does own its own alternative: Oracle XE. Myself, I have no previous experience with Oracle XE and will be looking forward how Oracle XE will turn out as new platform for Siebel Tools and the Siebel Developer’s Web client.

What will be interesting is the fact, that Oracle XE can be connect to with SQL Developer as any other Oracle database. That surely will be much better that DBISQLC.EXE ;-)

– Jeroen

Firefox To Drop NPAPI Support Late 2016

Firefox-DisabledJavaPluginThe word is out from the Mozilla blog: Firefox will de-support NPAPI Plug-ins late 2016. Mozilla following the same path as Google but with a remaining grace period of about 15 months. Although Mozilla announced it will still support Flash, Java will be a dead-end in the browser. Even though Siebel Open UI does not heavily rely on Java there are some bits and pieces which do. The most important obvious one would be the ‘inline editing’ mode of Siebel attachments. And then obviously there are customers who have resorted to a Java applet for some kind of desktop integration, replacing the traditional HI / ActiveX Web Client Automation Server capabilities to attach to a Siebel web session.

Good to know, with Innovation Pack 2016 there is a planned feature to replace current Java applet based functionality with an open Web Socket framework. Check the Innovation Pack 2016 Statement of Direction to get more details. The Web Socket framework will be open and published as API for customers to take advantage of.

– Jeroen