Archive

Posts Tagged ‘rendering condition’

Notes: Hide-When Formel in Mails

16/01/2012 3 comments

Heute hatte ich mal wieder eine meiner wilden Ideen. Ist es möglich in E-Mails Hide-When Formeln zu benutzen?

Die Antwort: Ja, ist es!

Es ist sogar ziemlich einfach. Man muss nur den gewünschten Text markieren, rechtsklicken und die Hide-When Formel, wie gewohnt, eintragen. Der Text wird dann entsprechend der Bedingung versteckt.

Dabei gibt es natürlich einiges zu beachten.

1. Die Formel wird vom Domino Server computed, d.h. das funktioniert auch bei externen Mails. Wenn z.B. ein Web.de Account die Mail bekommt und die Bedingung wird auf dem Server als True berechnet, so wird derjenige diesen versteckten Text nie zu Gesicht bekommen. Da die Formel auf dem Domino Server berechnet wird funktioniert das ganze in externen Mails nur begrenzt. Will man z.B. dass eine bestimmte Person den Text nicht sieht, so muss man aufpassen wie man die Bedingung formuliert, denn die Formel wird mit dem Namen des Servers berechnet, dementsprechend wird das extern nicht so funktionieren wie man das beabsichtigt hatte.

2. Bleibt die Mail innerhalb eines Lotus Notes Systems, so wird die Formel nur über den Text gelegt, wenn man sich das Body-Feld, beispielsweise mit dem DocViewer von Domiclipse, ansieht, so steht dort der Text über dem die Formel liegt.

3. Es ist möglich diese Formel auszuhebeln. Schreibt man beispielsweise folgenden Text in eine Mail:

Test 1
Test 2
Test 3

und versteckt Test 3, so kann man wenn man den Cursor hinter Test 2 platziert und ENTF drückt den versteckten Text eine Zeile höher nehmen, wobei die Hide-When Formel ungültig wird. Das allerdings nur bei internen Mails, weil der Text bei externen Mails niemals auf dem Zielserver ankommt.

Jetzt bleibt noch die Frage: Wozu das ganze eigentlich?

Bei uns in der Firma gibt es eine Regelung dass an interne Kollegen eine gekürzte Fassung unseres Mail-Footers gesendet werden soll und nur an externe Kunden der volle Mail-Footer mit dem ganzen rechtlichen Geraffel, einerseits um Speicherplatz auf den Mailservern zu sparen (Ich hab’s hochgerechnet, beläuft sich auf mehrere 100GiB pro Jahr) und andererseits um die armen Kollegen mit BlackBerry nicht zu überfordern (nur eine Vermutung von mir ).

Durch dieses kleine Feature ist es mit ein paar weiteren Tricks möglich das einzurichten, sodass der der arme, sowieso schon mmit Notes überforderte User nicht auch noch eine Signatur auswählen muss.

Dass man mit diesem Trick seinen Kollegen einen kleinen Streich spielen kann ist natürlich vollkommen ausgeschlossen, sowas würde auch niemand von uns tun, dazu sind Notes-Entwickler viel zu ehrlich =)

Ein viel interessanterer Zweck ist natürlich Code-Injection. Ich habe das bisher noch nicht testen können ob dies möglich ist und inwieweit das zwischen Notes-Servern unterschiedlicher Domains möglich ist und welche Spuren derjenige hinterlässt. Auf jeden Fall wäre das aus meiner Sicht technisch möglich wenn man Schad-Code in der Hide-When Formel versteckt. Ich werde das in den nächsten Tagen mal testen und ein Update schreiben. Hoffen wir das beste.

Bleibt ehrlich =)

Notes: Attachments in Subforms

Mal wieder trieb mich Notes in den Wahnsinn, diesmal mit Attachments in RichText-Feldern.

Das Problem war, ich hatte einige Forms, welche im Grunde exakt gleich ausgesehen haben, daher mussten Subforms her.
Ich hatte in jeder Form eine Subform, welche das Layout abbildete und dann noch jeweils eine Subform für den Datenteil der jeweiligen Form und noch eine für die Attachments. Da die Attachments nicht in jeder Form auftauchen sollten, war die entsprechend computed.

Da war dann das Phänomen dass ständig unterhalb der Form noch die Attachments sichtbar waren, also nochmal separat aufgelistet wurden. Sehr nervig.
Normalerweise tritt dieses Phänoment nur auf, wenn das Dokument Attachments enthält, aber das Feld wo es drin liegt, ausgeblendet ist. Das war aber gar nicht der Fall.

Nach einigem hin und her probieren stand dann die Ursache fest. Das Problem war einfach, dass die Subform computed war. Scheinbar wird Notes intern erst dieser Mechanismus durchlaufen, also prüfen ob das RichText Feld da ist, wenn ja dann zeige es dort an, wenn nicht, dann zeig es unterhalb der Form an. Erst danach werden dann die Subforms berechnet. Von daher ist es vollkommen egal ob das Feld angezeigt wird oder nicht, Notes geht erstmal davon aus dass das Feld potentiell nicht angezeigt werden könnte und packt sie zur Sicherheit nochmal unter die Form. Wenn man die Subform so wie sie ist direkt einbaut funktioniert alles wie es soll. Statt der computed subform habe ich dann entsprechend Hide-When Formeln benutzt, dort tritt das Problem seltsamerweise nicht auf, die werden scheinbar vor dem Attachment Mechanismus berechnet.

Notes: Ein- und Ausblenden von View-Actions

Heute mal ein kleiner Tipp für Standard-Notesclient Anwendungen.

Ich hatte die Anforderung bekommen dass in einer kategorisierten View die Actions ein- und ausgeblendet werden sollen, je nachdem ob ich eine Kategorie oder ein Dokument ausgewählt habe. Langes Suchen brachte nichts und auch ein Kollege war der Meinung es geht nicht. Ein anderer Kollege brachte dann aber doch die Lösung:

In den View-Einstellungen gibt es eine Option namens “Evaluate actions for every document change”. Das funktioniert deshalb weil auch ein Wechsel der Selektion als Change aufgefasst wird.
Schlussendlich muss man in der Hide-When Formel nur noch auf die Form abfragen. Wenn sie leer ist verstecke den Button, wenn nicht dann zeige ihn an, denn Kategorien haben keine Form.

Darüber hinaus kann man so natürlich noch sehr flexibel entsprechende Actions anzeigen, beispielsweise wenn man in der View mehrere Forms hat.

XPages: Collection of advices

Hi folks,

here is a small collection of some hints which were written by my colleagues and myself throughout time.

Naming of attributes in Internet Explorer

It seems, in the Internet Explorer, Dojo has some problems finding the correct element, while usingattribute selectors, if there is a string reserved by the system in the attribute. (e.g. name or id). Because Dojo uses the selector engine “Sizzle” like JQuery, the same phenomenon can appear using JQuery.

An example for that is an input-field with the name “username”. If you select dojo.query(‘input[id$=”WFApprovalVFL”]’) the field “username” will be selected, too, although it doesn’t end with WFApprovalVFL.

The same happens with keynames in JSON-objects.

Not rendered datasources will always be computed

If you use a datasource in a custom control, the code of the datasource will always be computed, no matter whether you set rendered or loaded to false. The code will always be computed. This could lead to errors hard to track down.

Furthermore, if you use several datasources in different custom controls, which point to the same document, all these datasources will be saved and, eventually, the document is saved more than once with saveing conflicts. To avoid this, you can reference the datasource in your custom controls directyl via the name, or you can pass on the datasource via a parameter of the custom control (compositeData). Therefore you have to select the class of the datasource, which doesn’t appear in the list of available types. The name of the class of a datasource is com.ibm.xsp.model.ModelDatasource.

Check whether a viewPanel is categorized

If we have a view control in our XPage which name is viewPanel1 the following code:

var model:com.ibm.xsp.model.domino.DominoViewDataModel = getComponent("viewPanel1").getDataModel();
return model.getCategoryIndentLevel();

returns the value 0 if view is categorized, it returns -1 if not.

Use case: If you sort a view, the content of a categorized column gets lost. With that you can check whether the view was sorted and reset the view.

Avoid the onChange bug in Internet Explorer when clicking on a CheckBoxGroup

If you use RadioButtonGroups or CheckBoxGroups in an XPage or a custom control, you could face the problem in the Internet Explorer, that after a partial refresh the submitted values of the group are the values from a previous request. This occurs if you click the label of instead of the box, directly. The reason is that the IE submits the partial refresh before setting the new value from the UI.

rendered="#{javascript:context.getUserAgent().isIE()}"


Example
:

There is a CheckboxGroup with the options A, B, C and D. In the onChange event, a partial refresh will be fired on another panel, which hides or shows some elements in dependence of the chosen value. If you click the label for Option A, there is no submitted value. If you click the label of option B, the value A is submitted. If you click after that on the label of option C, Ab and B will be submitted.


Workaround
:

You can fire the partial refresh a second time in the onComplete event of the onClick event.

 <xp:this.onComplete>
<![CDATA[XSP.partialRefreshPost("#{id:refreshPanelID}");]]>
</xp:this.onComplete>

The workaround above doesn’t work if there are additional actions or server-side code. The code will be executed only on the first refresh. To get this event-handler working again, you have to hang out the click-event from the standard-action and execute it by yourself. You can achieve that with a scriptblock (The name of the control is Output-Script, you can find it if you open the list of other controls in the sidebar of the Domino Designer) Because the checkbox itself is inside the label, you have to seperate it from the own execution.

 <xp:scriptBlock id="scriptBlock1"
        rendered="#{javascript:context.getUserAgent().isIE()}">
        <xp:this.value><![CDATA[dojo.addOnLoad(function(){
    dojo.query("label",dojo.byId("#{id:checkBoxGroupID}")).forEach(function(el){        
        dojo.connect(el,"onclick",el,function(e){
            if (e.target.type != "checkbox") {
                e.preventDefault();
                dojo.query("input",this).forEach(function(el){
                    dojo.attr(el,"checked",!(dojo.attr(el,"checked")));
                });
            }    
        });
    });        
});]]></xp:this.value>
</xp:scriptBlock>

Another advantage of this method, compared to workaround 1, is that you don’t need a second request.

Validation of two dependen input-fields

While validating two fields dependent of each other, you have to read the value of the field which is validated. If you compare the value of the second field, validation will not be fired after the first fail and the validation error persists.

Example:

 <xp:inputText id="recipientNotesID"
   value="#{test.recipientNotesID}"
   disableClientSideValidation="true" required="true">
   <xp:this.validators>
      <xp:validateRequired message="Required value."></xp:validateRequired>
   </xp:this.validators>
</xp:inputText>
<xp:inputText id="recipientNotesPW"
   value="#{test.recipientNotesPW}"
   disableClientSideValidation="true" required="true">
   <xp:this.validators>
      <xp:validateExpression>
         <xp:this.expression><![CDATA[#{javascript:((getComponent("recipientNotesPW").getSubmittedValue()||"")!=(getComponent("recipientNotesID").getValue()||""))}]]>
         </xp:this.expression>
         <xp:this.message><![CDATA[#{javascript:"Values must not be equal."}]]></xp:this.message>
      </xp:validateExpression>
      <xp:validateRequired message="Required value."></xp:validateRequired>
   </xp:this.validators>
</xp:inputText>

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.

%d bloggers like this: