bookmark_borderYOUFEB: DynamicViewPanel cannot sort descending?

I have a been troubling why I can’t sort on certain columns. Again after a loooooooooooooooooong time I figured: hell what..

So I changed the sort direction of that column which I could not sort in the dynamicViewPanel. Just out of any other options, something as a “last resort”, or out of desperation.

And who believes it??? Finally I could sort?

So I figured: dynamicViewPanel cannot sort descending?

Anyone can confirm this? Sorting ascending and both directions works, descending nope!

Don’t know if it’s related to the DominoViewCustomizer..

where can I file a bug report?

bookmark_borderYOUFEB: do you want me to share an easy way to configure views in your xPages?

just recently I have found the DominoViewCustomizer to customize the views displayed with the Dynamic View Panel from the extension library.

Of course it was a cool idea but I needed a way to “customize” my views.

Is anyone interested in me sharing this whole “component”? Well it’s not really just one component, a few pieces play together.

If I get a decent amount of comments asking me to share it I will do so.

Just so you know what it would be about:

  • simple way to let users choose from available views
  • in an open view you can call “ColumnCustomizer” which lets you set all properties you can set on a view column
  • additionally some ideas how to add easy filtering on views

I think I would strip down my “framework” to just that piece of functionality 
and put some comments on how to use/implement it online.

I from my side would have question as well:

Does someone know if I can create a (repeat) control which has “computed properties” (eg. the label, or values to choose from) based on not just a simple string but on JavaScript which would be “evaluated” on the fly?

I do know how to evaluate JavaScript with Java, what I am missing though: How can I attach to a new (repeat) component dynamic JavaScript? Dynamic means: the JavaScript is not stored in the component but on a configuration document.

Still confused? An example:
I am looking for a way to fully “customize” my view filter!
I want to put some tags/attributes and some code onto my dynamic column view definitions.
The result would be a fully automated dynamic view filter! Think about dropdownboxes which get their values from the provided JavaScript

At the moment I do have to create in one custom control “hard coded” fields (for each view on a different panel which is rendered only for specific views) for filtering on specific columns. I would like that to be customizable!


bookmark_borderINDIP: sort a document collection in Java (Java heroes may skip this)

Update: the result of the blog below landed here. Thanks to Nathan Freeman, hihi, kudos to me???

In Lotus Script it was not a simple task to sort a document collection. In Java it sort of is.

Idea: use a comparator class, supply with an array of fields upon which the “sorting” should happen and let the Collections.sort do it’s magic:

Comparator class:

public class CollectionComparator implements Comparator<Document> {

String[] sortFields = null;

public CollectionComparator(String[] sortFields) {
this.sortFields = sortFields;
}

public int compare(Document doc1, Document doc2) {

try {
int compared = 0;
// loop all sortFields
for (String field : sortFields) {
Item item1 = doc1.getFirstItem(field);
Item item2 = doc2.getFirstItem(field);
switch (item1.getType()) {
case Item.TEXT:
case Item.AUTHORS:
case Item.NAMES:
case Item.READERS:
String val1 = doc1.getItemValueString(field);
String val2 = doc2.getItemValueString(field);
compared = val1.compareTo(val2);
if (0 != compared) {
return compared;
}
break;
case Item.NUMBERS:
Double d1 = doc1.getItemValueDouble(field);
Double d2 = doc2.getItemValueDouble(field);
compared = d1.compareTo(d2);
if (0 != compared) {
return compared;
}
break;

case Item.DATETIMES:

DateTime dt1 = item1.getDateTimeValue();
DateTime dt2 = item2.getDateTimeValue();
compared = dt2.timeDifference(dt1);
if (0 != compared) {
return compared;
}
break;
}

item1.recycle();
}
return 0;
} catch (NotesException e) {
Logger.logError(e);
}

return 0;
}

}

Calling the sort:
// fill a list with the documents
List<Document> docs = new ArrayList<Document>();
doc = dc.getFirstDocument();
while (null != doc) {
docs.add(doc);
doc = dc.getNextDocument(doc);
}

// sort the list
String[] sortFields = new String[] { “fieldName” }; // you can also supply multiple fields “field1”, “field2”
Collections.sort(docs, new CollectionComparator(sortFields));

// retrieve values
for (Document docSorted : docs) {
values.addAll(docSorted.getItemValue(“Values”));
}
All code samples and downloads are copyright Michael Zischeck and licensed under Apache License 2.0 

bookmark_borderQUINDIP: dynamic “access controlled sections” ;-) in xPages

Some people faced the same problem than me: they wanted something like the “access controlled sections” in plain old LN development.
Mark Leusink
Russell Maher
Jeremy Hodge

None of the articles quite well didn’t explain how to set those ACLs dynamically..

I also tried to get set READER or EDITOR via something like:
return (condition to check) ? “READER” : “EDITOR”

but it wouldn’t work, especially not if in the condition the currentDocument was used. So what next?

I tried with a Bean, and it worked very smoothly. I put the code into the Bean constructor, the bean itself is a request scope bean, as (for whatever reason) I could not get view scope beans to work:

UIPanelEx panel = null;
ACL acl = new ACL();
ACLEntry aclEntry = new ACLEntry();
if (!(dominoDoc.getValue(“wfCurrentState”).equals(“1”) || dominoDoc.getValue(“wfCurrentState”).equals(“5”))) {
aclEntry.setRight(“READER”);
aclEntry.setType(“DEFAULT”);
aclEntry.setFullName(“*”);
acl.addEntry(aclEntry);

panel = (UIPanelEx) JSFConnector.findComponent(“panelRequestor”);
panel.setAcl(acl);
panel = (UIPanelEx) JSFConnector.findComponent(“panelDetails”);
panel.setAcl(acl);
panel = (UIPanelEx) JSFConnector.findComponent(“panelApprover”);
panel.setAcl(acl);
}


dominoDoc is the document source and the code prevents a few panels from being edited in all but in 2 workflow states (1, 5)

Neat!

bookmark_borderFRULE!!!: 9h to find ignoreRequestParams=”true” needs to be set!!!

In continuation of this I faced another problem in my target database. The first time the dialog for the sensitive data was called, it worked just fine. All subsequent calls just failed. After a very long time (you know it………) I finally figured out: the dialog box was using the parent document in subsequent calls.. but why? And why did it work on my test application.

With help from a coworker I finally, by accident!, figured the only difference between test and my actual database was ignoreRequestParams=”true”!! On test this parameter was set and there it worked. I gave it a try, without actually knowing what I was doing. Why I didn’t know? That’s a rhethorical question, right? 😉 On the web I have been stumbling across some other blogs mentioning it, which might have been the reason why I, ghosted  as I was through the lack sleep, tried it out on test. I honestly don’t know how that parameter came there.

But what the heck… finally my approach worked and I could save all my special infos with special access rights to another document!

Anyone: Would it be possible for someone knowing in detail what this parameter is about to write about it? Would be highly appreciated.

What I then figured was also very interesting in itself: Even though the “events” for the data source were not “visible” in the events viewer they were available! Under all properties etc.. you will find it:

That’s by the way also the place where you can toggle the flag for “ignoreRequestParams”!
The cool thing with those events: my defined document datasource is acting like an xPage in itself! Means I can change fields, run my custom validation approach etc. to my liking. Really neat!

bookmark_borderFRULE: pay attention to access rights, especially when working locally!!!!

In one of our applications we need to store more “sensitive” data with less access rights than the normal documents. In Lotus Notes the parent/child paradigma is just about perfect for this task.

My idea was to have a dialog popup where the user could enter this sensitive data.

I did a test in a test database, with a few hiccups I got everything working. The hiccups were kind of related to the fact:

  1. how do I ensure that every dialog would go to the same child document
  2. how do I ensure that the dialog has the same document mode (read/edit) than the parent
1. I solved by presaving a child, getting it’s unid and adding it to the document source. That was per se not sooo complicated disregarding the fact that the functionality was located on a custom control.
2. Was a bit a weireder (german-english for “more weired”) issue. On the test db all worked fine. The dialog’s document source edit mode was put to the same as the parent document and that worked.
In the actual db where I needed this feature I built everything 100% identical, yet the dialogbox was never going to edit mode. By accident then i figured: if the fields are not bound to the document then they can be edited. Of course they wouldn’t be saved also. So what the heck was going on? Then this morning I had an “almost” revelation: it must be access rights!!! I was sure, not being at the computer, this must be related to insufficient access rights for “anonymous”. When I was back at my computer I was disappointed to find out: that was not the case! Same access rights for anonymous on both dbs.
So I did what I usually do when I’m clueluess: tried to explain it to someone “stupid” (stupid in the sense of having no idea what an xPage is).
And guess what: this time the demo effect worked the other way around! Instead of NOT working during demoing, it actually worked!
So I was happy to find out that my approach did work.
But what was the problem when it did not work?
First you must know: I almost 100% of the time work locally (so I can debug easily my Java code), and working at home i’m not even “online”!
Well.. turns out in the test application I had “Enforce consistent ACL” checked. In the actual application this was unchecked, but by accident during demo I was connected to the server (ie. location=online). So during the demo by some interesting feature I cannot explain the web server could, even though local, determine (cause I was online) the appropriate author access for anonymous, hence the whole thing worked!
Summary:
Do not forget to think about the fact that xPages ARE indeed still Lotus Domino applications with all their nice access rights. And if you work locally ensure that you have always checked “Enforce consistent ACL”!

bookmark_borderINDIP/CRYFH: having legacy Lotus Script code do your work!

In our company we do have a wonderful, flexible, proven, stable own-built workflow engine, but it is written in Lotus Script code. baah..

I didn’t want to rewrite the whole thing in Java…

But you may now think: hey why does he not run an agent?

I tried, and I failed, how else!!! Always the way I understand things, they will never really work!

Luckily I then I found Kathy Browns article how to do it and it works!!!

Solution:

  • put some value into the NotesDocument to “control” your logic in the LS agent
  • run the agent with the document as parameter
  • write some field in the agent into your document: NO NEED TO SAVE THE DOCUMENT!!!
  • read the result from you NotesDocument in your xPage code and process it
My mistake was: I tried to update a field which was visible on the xPage, and here my approach failed. 
Or could I manually “refresh” the xPage after the agent has run? Seems to be maybe a “timing” issue, cause the value is there, it’s only just not displayed in the field on the xPage. Anyone?

How we use this technique with our workflow engine:
The engine can require a comment to be given for certain target state. But the target state I don’t know yet in the xPage, cause this logic is handled in LS. But with the technique above I can create an agent provide the target action (reject/approve or something else), calculate the target state and find out if for that state a comment is required. If so I can then call a dialog in the xPage where the user can enter his comment. In the agent which runs then, to process the workflow, I then simply read this comment field and process it. In our case it’s written to a workflow log and also included in the notification to the approver of the next state
Nathan: did you read my comment to your comment? I bow to you..

bookmark_borderunQUINDIPping QUINDIP and other accronyms

according to Tim Tripcony (read the comment on this blog) quindip means confusion, I am now trying to unConfuse you about the confusion I created with my accronyms I use 
  • INDIP: INDispensabletIP (those ones which I deem very important in any xPages developers knowledge bag)
  • QUINDIP: QUickINDIP (those ones I deem quickly explained, 2min to read,  understand and implement)
  • FRULE: FRUstratedLearningExpierence (things I learned the hard way (shall I repeat how hard?), ie. it took me hours/days to get the hang of it and mostly in the end it was so obvious only I lacked some very basic knowledge in the first place)
  • CRYFH: CRYForHelp (when I have no clue anymore how to proceed and I need your input)
  • YOUFEB: YOUrFEedBack required (please gimme comments, ask questions what you want me to blog about etc)
  • DYHOP: DoYouHaveOtherProposals for accronyms? 😉
ups.. something very important I almost forgot…

let the game begin (provide your ideas in the comments): any idea what the anagram of in-mood is?

well.. a hint: in-mood is the anagram of the actual word. When I had my own company few years ago, I was so in (good) mood about stuff I was doing that time.. that I figured: great this will be my company name!

Unfortunately I cannot offer anything as a price to the winner besides maybe some special mentioning in a blog entry or my personal effort trying to help to solve an interesting xPage problem!

bookmark_borderBIG THANK YOU to all my readers

A big “thank you” to all of you. 

You helped raise attention to my blog (as of 2013-04-03 this blog is just under the top 50 of the past 5 days in this list) and it seems some important people in the xPages community do read my blog (at least once in a while 😉 )

I can only assume that the content combined with my, hopefully funny, style to write are responsible for the hits I get.

I don’t know why, but somehow my blog seems to hit some pain points out there.

Maybe some of you might now already why I created this blog:
xPages are a great technology, BUT it’s really hard to find decent documentation.
Everything is POORLY documented and you need to collect bits and pieces all over the web to get some stuff going properly and this is frustrating and takes literally ages!

The xPages TOP CRACKS out there doing some interesting blogging: they know their stuff, too good actually. Sometimes they miss the important little things, the little things which drive us newbies crazy because we don’t get the stuff working.

Example:
The repeat control. Has anyone of you ever wondered why the “Collection name” is called collection name?
I always thought in Lotus Script terms of a collection.
It took me a while to understand that the actual “meaning” of this property was a handle to the single record/data/document within the collection! So why not call this stupid property something like “entity handle” or “entity name” or “single data entry handle”.. or something we newbies can understand well at once!

Take this example video which I think is great, but it has a minor glitch and no-one seems to care 😉
Check out min 1:13. He says: we add a collection name “rows” (plural!) and then he enters anyway “row” (singular). If you don’t pay attention you will never get it to work. I had to zoom in (ie. fullscreen until I figured out where I made the mistake!)

Don’t get me wrong:
I’m not accusing anyone of anything here! I just noticed on my learning way that I was over and over and over and over (how many times shall I repeat?) not really happy with the information I was looking for.

I just think that the beginner xPages developer needs to know also the little details. An attribute wrongly activated/selected etc.. and nothing works. And the error messages you do get, com’on.. you all know it: THEY ARE USELESS!!! It takes you again (shall I repeat?) HOURS to figure out where the actual problem is. Thankfully I did figure out how to debug Java code and this makes my life a whole lot easier.
But again: why does IBM not propagate this great feature more openly??? I would expect it even in the help of the designer!

Summary:
I think I had a great, difficult and bumpy but yet steep, learning curve in the past 6 months, way more to go I assume. But the knowledge I have now is quite sufficient to be a decent xPages developer.

What I expect from you guys out there:
Give me feedback!!!!! Write comments! Ask me questions and I will try to blog about more interesting things.

THANKS FOR YOUR ATTENTION