Tip of the day: isDocument() for nested data in the Data View control

You can show nested data in the details section of the Data View control. Read about it here: Data Views – Part 10: Nested Repeat in the Detail Section.

In case you have a ‘flat’ Data View (one without collapisble categories) you do not need to detect if your ‘var’ property is a document. But when you have a categorized Data View you better check it otherwise opening/closing categories will give an error…

Summary JSON in XPages

I have written a document summarizing the usage of JSON as data-interchange format in XPages development. The document has no intention to be complete, it only covers the areas I have worked with JSON in XPages (and as far as I remember)

Please feel free to add your examples or links to more supplementary resources.

Happy reading!

https://quintessens.wordpress.com/?attachment_id=1462

Job Wanted

Looking for a creative brain? Choose me!

job-wanted

Dropdown menu from Notes view in Twitter Bootstrap (with XPages)

Introduction

OK, so I was a bit unsatisfied with the navigation list in my previous post. The nav-list component seems not to be destined to contain too many category sub levels.

Dropdowns

Toggleable, contextual menu for displaying lists of links.

Pills

I am not sure how you would describe pills in Twitter Bootstrap but to me they look more like buttons you build a navigation with.

tb pills

Implementation

Again I used Mark Leusink’s Bootstrap4XPages demo site. As source for my documents I am re-using the same view from my previous post:

notesview clean

I found an example code for nesting lists on Fiddle and modified it a bit to my needs.

I display the results via a computed field that looks as followed:

<xp:text escape=”false” id=”computedField1″ value=”#{javascript:getList()}” ></xp:text>

The function getList() is very similar to the one in my previosu post and looks as followed:

function getList() {
var nav: NotesViewNavigator = database.getView(“$v-treeview-clean”).createViewNav();
var entry: NotesViewEntry = nav.getFirst();
if (entry != null) {
var countLevel: Integer = 0;
var curLevel: Integer;
var list = “<div class=\”dropdown\”>”;
list = list + “<ul class=\”nav nav-pills\”>”;
list = list + “<li class=\”dropdown active\” id=\”accountmenu\”>”;
list = list + “<a class=\”dropdown-toggle\” data-toggle=\”dropdown\” href=\”#\”>Home</a>”;
list = list + “<ul class=\”dropdown-menu\”>”
while (entry != null) {
var edoc: NotesDocument = entry.getDocument();
entryValue = entry.getColumnValues().elementAt(1).toString();
var col: NotesDocumentCollection = edoc.getResponses();
curLevel = entry.getColumnIndentLevel();
if (col.getCount() > 0) {
//prep for new entry with response(s)
var difLevel = countLevel – curLevel;
var closure = “”
for (var i = 0; i < (difLevel); i++) {
closure = closure + “</ul></li>”
}
list = list + closure;
list = list + “<li class=\”dropdown-submenu\”>”;
list = list + “<a href=\”#\” tabindex=\”-1\”>” + entryValue + “</a>”;
list = list + “<ul id=\”” + entryValue + “\” class=\”dropdown-menu\”>”;
//increase counter
countLevel = curLevel + 1;
} else {
if (curLevel == countLevel) {
list = list + “<li><a href=\”#\”>” + entryValue + “</a></li>”;
} else if (curLevel < countLevel) {
var difLevel = countLevel – curLevel;
var closure = “”
for (var i = 0; i < (difLevel); i++) {
closure = closure + “</ul></li>”
}
list = list + closure
countLevel = curLevel;
} else {
//
}
}
var tmpentry: NotesViewEntry = nav.getNext(entry);
entry.recycle();
entry = tmpentry;
}
//final closure, last entry could be response doc
var closure = “”
for (var i = 1; i < (countLevel); i++) {
closure = closure + “</ul></li>”
}
list = list + closure
//closure nav nav-list
list = list + “</ul></li></ul></div>”;
//closure well sidebar-nav

return list;
} else {
return “no documents found”;
}
}

Here is what the result looks like:

dropdowndemo

Alternative

The example above looks nice but I am not sure what the purpose of nav-pills are? (don’t ask a Dutch the pills Q)  I guess users would expect site navigation to be in a navigational bar, so expect another post on the nav-bar component.

Job Wanted

Looking for a creative brain? Choose me!

job-wanted

Navigation list from Notes view in Twitter Bootstrap (with XPages)

Introduction

In my previous post I demonstrated how you create breadcrumbs from Notes view in Twitter Bootstrap. A typical Notes application contains an outline (I assume you don’t the Navigator design element anymore). In this post I demonstrate how to create something similar in Twitter Bootstrap, a Nav List.

navlist example

Nav Lists

A Nav list is a simple and easy way to build groups of nav links with optional headers. They’re best used in sidebars like the Finder in OS X. You can nest nav-lists and then they come quit close to categorized or hierarchical structured documents (e.g. parent & response).

Implementation

As  a start database I used Mark Leusink’s Bootstrap4Xpages demo site which you can download here.

As source I am also using a similar view as I used in my previous post. Here is how it looks like:

notesview clean

I found an example code for nesting lists on Fiddle. Note that you can extend nav-list with mouse over behavior but I fear for mobile phones and tablets this will be a crime.

I display the results via a computed field that looks as followed:

<xp:text escape=”false” id=”computedField2″ value=”#{javascript:getNavList()}”></xp:text>

The function getNavList() looks as followed:

function getNavList(){
var nav:NotesViewNavigator = database.getView(“$v-treeview-clean”).createViewNav();
var entry:NotesViewEntry = nav.getFirst();
if (entry !=null){
var countLevel:Integer = 0;
var curLevel:Integer;
var list = “<div class=\”well sidebar-nav\”><ul class=\”nav nav-list\”>”;
while (entry !=null){
var edoc:NotesDocument = entry.getDocument();
entryValue = entry.getColumnValues().elementAt(1).toString();
var col:NotesDocumentCollection = edoc.getResponses();
curLevel = entry.getColumnIndentLevel();
if (col.getCount()>0){
//prep for new entry with response(s)
var difLevel = countLevel – curLevel ;
var closure = “”
for (var i=0; i<(difLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure;
list = list + “<li>”;
list = list + “<a href=\”#\” data-toggle=\”collapse\” data-target=\”#” + entryValue + “\”>” + entryValue + “</a>”;
list = list + “<ul id=\”” + entryValue + “\” class=\”collapse in\”>”;
//increase counter
countLevel = curLevel + 1;
}
else{
if(curLevel==countLevel){
list = list + “<li><a href=\”#\”>” + entryValue + “</a></li>”;
}
else if(curLevel<countLevel){
var difLevel = countLevel – curLevel ;
var closure = “”
for (var i=0; i<(difLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure
countLevel = curLevel;
}
else {
//
}
}
var tmpentry:NotesViewEntry = nav.getNext(entry);
entry.recycle();
entry = tmpentry;
}
//final closure, last entry could be response doc
var closure = “”
for (var i=1; i<(countLevel); i++){
closure = closure + “</ul></li>”
}
list = list + closure
//closure nav nav-list
list = list + “</ul>”;
//closure well sidebar-nav
list = list + “</div>”;
return list;
}
else{
return “no documents found”;
}
}

In order to make it look nice embed the computed field in div element and give it a span class.

Below you see the final result:

result nav list

 

 

You notice directly an obvious problem: the long title references which are typical for Notes documents.

Alternative

Twitter Bootstrap offer other alternatives which might be more suitable for transforming Notes views. And example is the dropdown. This you can extend with the dropdown JavaScript plugin.

Point for improvement

A class I did not use for the LI element is nav-header. This gives a nice outstanding header, which are great for categorized views.

A class I did not use for the LI element is active which highlights a list item. When using the nav-list on documents opened via an XPage I guess it is best practice to add the class name when the document is ready on the client.

The HREF attribute is not computed but this can be extracted from the viewentry.

Performance. The view above contains very little documents. I still have to test it with larger databases. Some examples where I want to use the nav-list contain more than 15000 documents in the view. I wonder how much I can use sessionScope or place the HTML in a profile document. Any suggestions here are welcome.

Tools used

Beside DDE is used heavily NotePad++ to check the generated HTML.

Job Wanted

Looking for a creative brain? Choose me!

job-wanted

XPages question: How to set a value for a checkbox group based on condition?

I would like to set a value for a checkbox group when clicking on a link.

In the example below you see a table on the right. The icons in the header reflect values in check box groups on the left.

I think it will be more easy to understand for users when they could also click the icons. Eventually I could hide the checkboxes in a later stage…

Getting the values of a checkbox is not so hard:

var component=getComponent(“nameOfCheckBoxGroup”).getAttributes().get(“value”);

But untill now I have not found a working example how to set values based upon the condition that a check box group does not has the value. Server-side JavaScript is not my thing right.

Setting the values should be done according the following method (I guess):

getComponent(“checkboxID”).getAttributes().put(“value”,arrayofvalues);