Archive

Archive for September, 2011

Recommendation: Xpages Blog Hasselba.ch

Hi,

I would like to recommend a Blog (written in german), he belongs to a colleague of mine, which always supported me and became something like my mentor =)

www.hasselba.ch

Thank you again.

Advertisements
Categories: Miscellaneous Tags: , ,

Stolperfalle: Validierung

26/09/2011 1 comment

Heute bin ich auf ein faszinierendes Phänomen gestoßen.

Problem war folgendes:

In einer Anwendung hatten wir 2 Comboboxen. Beide wurden mit Werten aus einem Setup-Dokument befüllt. Zusätzlich fügten wir per Javascript (serverseitig) noch einen Leerstring und den Wert New… hinzu. Bei Auswahl von New… wurde ein Dialog aufgerufen.

1. Phänomen: Schloss man den Dialog so stand der Wert in der Combobox noch auf New… Wollte man nun speichern, so wurde die serverseitige Validierung angestoßen, dort tauchte die Meldung “Entry not found in Index” auf. Keiner wusste woher diese Meldung kam. Ein paar Printouts verrieten uns, dass beim ersten Speichern noch der alte Wert im Frontenddokument stand, also der Wert der vor der Auswahl von New… in der Combobox war. Konsequenz daraus, beim ersten Submit auf ein Feld wird bei fehlgeschlagener Validierung der Wert nicht ins Backend submittet, denn selbst ein getComponent(“feldname”).value brachte uns noch den alten Wert zurück. Beim zweiten Submit, wird der wert dann doch übertragen und erneut validiert. Dies kann zu merkwürdigen und schwer nachzu vollziehenden Fehlern führen.

2. Phänomen: Wo kam die Meldung “Entry not found in Index” her? Nach einigem hin und her probieren wurde klar woher er kam: Aus der Form.
Unglaublich aber war, die serverseitige Validierung schleift Fehlermeldungen von anderen Feldern aus der Form durch. Wir hatten in der Datasource des Dokuments definiert, dass beim Speichern der Datasource die Form computed werden soll. In der Form wiederum hatten wir ein Feld, welches aus der Referenz (der Wert der Combobox entsprach per Alias einer UNID) einen Klartextwert für die Volltextsuche machte. Dort wurde ein @DBLookup durchgeführt. Dieser nahm sich den Wert aus dem Feld (New…) und sucht entsprechend danach. Komischerweise gelangt der Wert nicht ins Backend, aber in den Einflussbereich dieser berechneten Formel. Da der Wert nicht da war wurde ein Fehler geworfen. Nämlich “Entry not found in Index”. Dieser wurde dann durchgeschliffen und auf der XPage angezeigt.

Daraus ergab sich die Möglichkeit in dem eigentlichen Feld, wo der Wert aus der Combobox gespeichert wird, in der InputValidation eine Formel zu hinterlegen welche unseren Feldwert validiert und entsprechend mit @Failure() eine Fehlermeldung zurückgibt. Auch diese wurde dann in der XPage angezeigt. So ergeben sich völlig neue Möglichkeiten die Validierung zu erweitern.

Stumbling Stone: FileUpload-Control

Today I had a tiny problem. Not even a bug, only a small booby trap.

On my page, I had three FileUpload controls and one FileDownload control. It was specified that a user can upload a maximum of three attachments. Therefore I added a rendering condition to all FileUpload controls, which chekcs the number of attachments in the document.
WARNING: The formula @Attachments doesn’t seem to work properly. It seems like @Attachment only checks the backend-document. I want to know how much attachments were uploaded right now to constrain the possibility to upload something. The function “doc.getAttachmentList(‘feldname’).size()” saved my day.

The three controls are placed below another, the first will be hidden if there are thee attachments, the second if there are two and the last one if there is at least one attachment. All this linked to a refresh, which is fired when you delete one attachment, everything works fine.

However, I faced the effect, if I add 3 attachments at once, only two were saved. The attachment from the last FileUpload control was never saved.

Get ready for the reason:

Controls seem to be processed sequential, connected with an internal refresh. That means, the first control is processed and the file is uploaded -> new there is a refresh -> second control is processed, everything is fine, so the second attachment is uploaded -> there is a refresh again -> third control wants to be processed, but there is more than one attachment in the document, so the control is not rendered anymore, therefore, the third attachment goes to hell.

The solution is quite easy, you only have to reverse the order of the number of attachments in the render condition. That means, the first control should be hidden if there is more than one attachment, the second is hidden with two attachments and the third with three attachments. Because the controls are processed in order they are in the code, everything works fine.

Another interesting fact is, that if you have some mandatory fields or have another server-side validation on your form, attachments are uploaded when you click the save button. After that the validation yells. The backend document doesn’t get bothered, but in the frontend document, there are your attachments uploaded, yet. In the context of my problem above, this could be quite confusing, but if you know that fact you can work around that.

XPages: Dojo dialogues

22/09/2011 2 comments

Again, XPages were cracking my head, this time with dialogues.

What was the scenario?

Some function in one of my application should be packed into dialogues. For instance one agent, which offers an excel-file for download which needs two different buttons to pass on some parameters to the agent. Therefore I had to call the URL of the agent, directly. Useally a simple task.
In rationally working browsers all works fine, until some genius thought it would be quite intelligent two try to click one button shortly after the other one. First button was working fine, but the second one wasn’t reacting. I fact, after that, nothing was working after that. When I reloaded the page, everything was working fine again, until someone was trying to click both buttons again.
The reason for this behavior was Dojo. One clever developer thought, to reduce the server load, he could implement a timeout for special situations. This function is hidden in the depths of theDojo source files. Who wants to check that, look here:

~NotesDatadominojsdojo-1.4.3ibmxspwidgetlayout

There are the source files of Dojo, quite useful if you want to debug your program effectively and never want stuck in some error messages like “Error in line 16, charackter 18564” again, because there are also the uncompressed sources.

There is one tiny file, called xspClientDojo.js with a tiny, nasty function:

/**
* The number of milliseconds allowed between page submissions,
* see XSP.canSubmit().
*/
// 20 sec if the latency after to re-enable the submission
// - asked by customers
this.submitLatency = 20*1000;

this._allowDirtySubmit = true;
this._dirty = false;
this._dirtyFormId = null;

this.djRequire = function x_djreq(name) {
   return dojo["require"](name);
}

“Asked by customers”, it’s sad that developers have to excuse themself for the wishes of some customers.
The bottom-line is that 20 seconds has to pass by between two submissions. Actually, that works! if you let pass 20 seconds after the first submissions, everything works fine again, even in my application.

Of course it is a little bit nasty to let customers wait 20 seconds between all submissions, tempting, but not acceptable. But Dojo has some workaround for that:

/**
* If the page is not submitted after a call to canSubmit(),
* this should be invoked to re-enable page submission.
* @return void
*/
this.allowSubmit = function x_as() {
   this.lastSubmit = 0;
}

This function resets the timestamp of the last submissions and allows some new submissions.

If we add this line of code to our program, we can avoid this problem.

XSP.allowSubmit();

You can imagine this wasn’t the end of the story. I mentioned rationally working browsers, in other browsers (Internet Explorer) it wasn’t possible to get the dialogues running.
Useally, the following meta header solves this problem:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

Unfortunately, most physical laws of the web are rather optional guidelines in XPages.

Dojo knows this problem, there is a fix for that, you can find it here: Bugs.dojotoolkit.org

Due to some timeline problems it wasn’t possible to make this fix working in short time. Therefore, the consequences are quite down-to-earth: For this application you have to use a smart browser (Firefox, for example) or rather the IE9 isn’t supported.

After this experience I will try to use dialogues only if there is no other way, that means, if the customer really wants them. I hope that in one of the next versions (maybe 8.5.3) everything gets better =)

UPDATE 2011/15/11:We could localize the problem. In fact, it is only one small CSS-Rule, called: “filter: progid:DXImageTransform.Microsoft.Aplpha(Opacity=0);”
Unfortunately we didn’t manage to remove this rule, so far. Somewhere deep in the code, it seems, it is added manually and we can’t do anything to prevent that.

UPDATE 28.03.2012: In Notes 8.5.3 and the new Dojo version it seems to work fine.

XPages: Control-hierarchy

A small advice for the horror we call XPages

This is a page which I use from time to time. It shows the hierarchy of the controls you can use in your XPages: Control Hierarchie

But not only the standard-controls, it also shows the controls from the Extension Library, which I would recommend to you: ExtLib

XPages: Eventparameters

Here is another advice for the horror we call XPages.

In XPages you have, theoreticaly, the possibility to pass a parameter along with an event. Sounds quite useful, doesn’t it? Unfortunately, they don’t work properly. It wasn’t possible for me to pass on some eventparameters. They simply didn’t arrive at the target.

Here is a workaround:

You can pass the parameter clientside and use them serverside after the request:

var docId = new CGIVariables().getURLParam("documentId");

Here is a link to a quite useful library which I use from time to time in my XPages:10.lotus.com

I added the following function:

this.prototype.getURLParam = function (name){
   name = name.replace(/[[]/,"\[").replace(/[]]/,"\]");
   var regexS = "[\?&]"+name+"=([^&#]*)";
   var regex = new RegExp( regexS );
   var results = regex.exec( "?" + this.request.getQueryString() );
   if( results == null ) {
      return "";
   } else  {
      return results[1];
   }
}

XPages: Validation of Tabbed Panels

This article shall start my Blog about the horror we call XPages.

One or another has certainly noticed that, when you use a TabbedPanel on an XPage, the whole validation of the form is screwed. If you change to another tab, where are no fields which should be vaildated, you can save the whole document without filling the mandatory fields on the other tabs.

This is, IBM-typically no bug, it’s a feature.
If the tab is not shown, it isn’t rendered, so he doesn’t exist. Therefore it is clear that the validation of this tab can’t be executed.

IBM knows this problem, there is already an Enhancement-Request since February 2010… unfortunately there hasn’t happen anything
This is the official workaround: 10.Lotus.com

Unfortunately, this isn’t quite elegant.

Here is another solution:

If you add a save-event in the onClick-event of every tab in the tabbedPanel, the XPage tries to save the document everytime you want to change the tab, which fires the validation. The catch is, of cource, you have to accept that the document is saved on every change of the tab. This solution is only vaild, if you have all your mandatory fields on one tab.

Attention: You shouldn’t check “Process Data without validation”. Also you should pay attention, that the document is only saved in the edit-mode.

%d bloggers like this: