Building a search function with DataTables plugin (VI)

Introduction

Often business analists who work with the data in tables eat & sleep in their spreadsheet world so a common asked question is: can we export the data? “Ofcourse you can!” with the datatable component.

Modifications

Below is a short summary of the changed/added items.

Configuration

In order to add the buttons you specify in the datatable configuration which buttons you would like to have e.g.:

dom: ‘Bfrtip’,
buttons: [
‘copy’,
‘csv’,
‘excel’,
{
extend: ‘pdfHtml5’,
orientation: ‘landscape’,
pageSize: ‘LEGAL’,
title: ‘Person Details’
},
‘print’
]

 

Required files

Which files are required for the buttons feature depend on which buttons you would like to display. In the download builder you can specify for which options you would like to go.

AMD fix

An important thing to notice is that most JS files use AMD loading. There have been posted multiple questions and answers how to fix AMD loading with XPages. In my repository I have just removed the amd checking.

Files overview

Probably the files you would like to use will be listed in the Theme design element:

<!– adding buttons –>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/buttons-1.2.1/js/dataTables.buttons.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/buttons-1.2.1/js/buttons.flash.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/jszip-2.5.0/jszip.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/pdfmake-0.1.18/build/pdfmake.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/pdfmake-0.1.18/build/vfs_fonts.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/buttons-1.2.1/js/buttons.html5.js</href>
</resource>
<resource>
<content-type>application/x-javascript</content-type>
<href>DataTables/buttons-1.2.1/js/buttons.print.js</href>
</resource>
<resource>
<content-type>text/css</content-type>
<href>DataTables/buttons-1.2.1/css/buttons.dataTables.min.css</href>
</resource>

 

Result

As a result you will see the buttons displayed above the table. If you apply filtering to the table the buttons will pick up the provided terms.

datatables06

A little less coding than an X-agent to create a PDF or spreadsheet 🙂

A downsize might be that users are not aware of the amount of data that might reside in your datatable (the only x-number of entries are displayed). Pressing the PDF button with 40K of documents in your notes view takes a bit of time…

JQM & Domino Data Service (2)

In a previous post I demonstrated how to use Domino Data Service (as part of Domino Access Service) to populate a listview for jQuery Mobile. Probably the real-world application you want to mobilize has multiple layers of data that is common in Notes (multiple forms & views). I followed Christophe Coenraets’s example and re-used it for the fakenames application.

First let me show you what you get:

Screenshot_1

 

Screenshot_2

 

At first an overview of the People’s view is presented, from here the user can open the Person details page. In Christophe’s example you can find a more nested navigation but our fakenames application is not setup like that.

What this demo includes:

  • 2 XPages; eg people.xsp and person.xsp.
  • Your modified version of employeelist.js and employeedetails.js in the download from Christophe page.
  • The CSS files in the download from Christophe page.
  • The jQuery JS files in the download from Christophe page.

For convenience I have dropped the files from the download via the Package Explorer in the WebContent folder of the fakenames application. In case you want to mobilize your fakenames application a step further e.g. by packaging it via PhoneGap to access device native api’s you don’t want to store these files here and you don’t want to use XPages to render the HTML.

Of course we assume you have Domino Access Service enabled for the Domino server and the fakenames application.

XPage people.xsp & person.xsp

These files do not differ from the index.html and employeedetails.html files in the download from Christophe page. In case you use XPages you should consider to turn of Dojo and Themes.

JS files employeelist.js & employeedetails.js

Since we will provide the information via Domino Data Service these JS files will be altered. Below you find their code:

employeelist.js

var serviceURL = “http://dev1//apps/fakenames.nsf/api/&#8221;;

var employees;

$(‘#employeeListPage’).bind(‘pageinit’, function(event) {
getEmployeeList();
});

function getEmployeeList() {
$.getJSON(serviceURL + ‘data/collections/name/People?count=1000’, function(data) {
$(‘#employeeList li’).remove();
employees = data;
$.each(employees, function(index, employee) {
var tmp = “”;
tmp+='<li>’;
tmp+='<a href=”person.xsp?id=’ + employee[“@unid”] + ‘”>’ +
‘<img src=”http://greenhouse.lotus.com/plugins/plugincatalog.nsf/NoPhotoPerson.gif”/>&#8217;;
tmp+='<h4>’ + employee.$17 + ‘</h4>’;
tmp+='<p>’ + employee.CompanyName + ‘</p>’;
if (employee.$12!=””) {
tmp+='<span class=”ui-li-count”>’ + employee.$12 + ‘</span>’;
}
tmp+='</a></li>’;
$(‘#employeeList’).append( tmp );
});
$(‘#employeeList’).listview(‘refresh’);
});
}

Walkthrough

At the page initiation the function getEmployeeList is called. This makes an Ajax request to the REST API of Domino Data Service and a document collection with the first 1000 entries (if available) in the view named People is being called.

I have not taken a look yet how to implement lazy loading or appending additional document collection(s) when scrolling. If you happen to know how to implement such function please drop me a line here or send me an email.

Then list items in the employee ID element on the Xpage people.xsp are removed (when available) and we loop through the results returned by Domino. We create a new list and establish a hyperlink to people.xsp and add the UNID of the document as parameter.

At last the result is appended to the (emptied) employee ID element and the listview is being refreshed. Wow! You got now a nice list of persons in the directory.

employeedetails.js

$(‘#detailsPage’).live(‘pageshow’, function(event) {
var id = getUrlVars()[“id”];
$.getJSON(serviceURL + ‘data/documents/unid/’+id, displayEmployee);
});

function displayEmployee(data) {
var employee = data;
console.log(employee);
$(‘#employeePic’).attr(‘src’, ‘http://greenhouse.lotus.com/plugins/plugincatalog.nsf/NoPhotoPerson.gif&#8217;);
$(‘#fullName’).text(employee.FirstName + ‘ ‘ + employee.LastName);
$(‘#employeeTitle’).text(employee.Title);
$(‘#city’).text(employee.OfficeCity);
console.log(employee.officePhone);
if (employee.Manager) {
$(‘#actionList’).append(‘<li><h3>Manager</h3><p>’ + employee.Manager + ‘</p></li>’);
}
if (employee.InternetAddress) {
$(‘#actionList’).append(‘<li><a href=”mailto:’ + employee.InternetAddress + ‘”><h3>Email</h3>’ +
‘<p>’ + employee.InternetAddress + ‘</p></a></li>’);
}
if (employee.OfficePhoneNumber) {
$(‘#actionList’).append(‘<li><a href=”tel:’ + employee.OfficePhoneNumber + ‘”><h3>Call Office</h3>’ +
‘<p>’ + employee.OfficePhoneNumber + ‘</p></a></li>’);
}
if (employee.CellPhoneNumber) {
$(‘#actionList’).append(‘<li><a href=”tel:’ + employee.CellPhoneNumber + ‘”><h3>Call Cell</h3>’ +
‘<p>’ + employee.CellPhoneNumber + ‘</p></a></li>’);
$(‘#actionList’).append(‘<li><a href=”sms:’ + employee.CellPhoneNumber + ‘”><h3>SMS</h3>’ +
‘<p>’ + employee.CellPhoneNumber + ‘</p></a></li>’);
}
$(‘#actionList’).listview(‘refresh’);
}

function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf(‘?’) + 1).split(‘&’);
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split(‘=’);
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}

Walkthrough

The idea behind the details page is similar to the people’s list, except we have now a single object in the JSON.

First the ID provided by the parameter is abstracted from the URL and used in the call to a document source via the Domino Data Service.

From the result a set of details is abstracted and presented to the user. Some HTML5 attributes are used to deliver a more native behavior when clicking anchor links (telephone, mail, SMS).

Some thoughts

jQuery Mobile and Domino Access Service provide good foundations for creating mobile Web apps on Domino. However I am a bit thoughtful on the speed of Domino Access Service. If you happen to know how to speed up performance for this please drop a line here.

In a next post I will write the implementation of CRUD actions with jQuery and DDS.

 

Adding Twitter Bootstrap to the IBM Domino Blog template

Our current design layout for a blog application was mainly based on the ‘by default’ design from the ‘early days’. A three column layout with a header and footer section.

(I guess you recognize this)

All nice wrapped in a HTML table to structure the layout. Maybe not the best and convenient solution, but quiet ‘solid’ compared with CSS layouts.

Nevertheless users were complaining, mainly because they import large images, which look nice on large screens, but not so nice on smaller ones. In such cases the right column was only visible when scrolling.

We have been so nice to add some corporate design guidelines flavours to the design, so users can recognize themselves when publishing within and beyond our corporate walls.

I guess we are talking now years ago, in the days that there were no mobile visitors with smartphones and tablets.

Time to move-on!

Since I noticed some buzz in the collaboration community around Twitter Bootstrap and responsive web design I decided to take a look around to see if we could bring the Domino template to the next level.

I did not take so much time to compare Twitter bootstrap to other frameworks (I leave that up to the pro’s) but after taking a look around, this framework seemed to be pretty solid and includes some other valuable components (which do not win from our oneUI components!).

Here is a summary how I implemented Twitter Bootstrap.

  • Update the Page  Templates documents to support the grid layout.

Here an example how most Page Templates look like (this is code for the homepage)

<!DOCTYPE html>
<html lang=”en”>
<body data-spy=”scroll” data-target=”.bs-docs-sidebar”>

<$DXTemplateBlock Name=”HTMLTop”$>
<$DXTemplateBlock Name=”Banner”$>
<div class=”container container-body”>
<div class=”row-fluid”>
<div class=”span3″>
<$DXTemplateBlock Name=”LeftSideBar”$>
</div>
<div class=”span9″>
<$DXContent$>
</div>

</div>
</div>
<$DXTemplateBlock Name=”HTMLBottom”$>

</body>
</html>

As you can see I have choosen for a ‘2 column layout’. Basically because I did not get the ‘holy 3 column’ layout properly established (with a responsive design). If you got the proper solution, please drop a line in the comments..

  • Update the Block Template documents.

Here is the code for my ‘top navbar’ section:

<head>
<link rel=”icon” type=”image/png” href=”../dx/favicon.ico/$file/favicon.ico” />
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″ />
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
<title><$DXTitle$></title>
<!– HTML5 shim, for IE6-8 support of HTML5 elements –>
<!–[if lt IE 9]>
<script src=”http://html5shim.googlecode.com/svn/trunk/html5.js”></script&gt;
<![endif]–>
</head>

<!– Navbar ================================================== –>
<div class=”navbar navbar-inverse navbar-fixed-top”>
<div class=”navbar-inner”>
<div class=”container”>
<button type=”button” class=”btn btn-navbar” data-toggle=”collapse” data-target=”.nav-collapse”>
<span class=”icon-bar”></span>
<span class=”icon-bar”></span>
<span class=”icon-bar”></span>
</button>
<a class=”brand” title=”<$DXTitle$>” href=”#”><img src=”../dx/logo.gif/$file/logo.gif” border=”0″></a>
<div class=”nav-collapse collapse” id=”topnav”>
<ul class=”nav”>
<li class=””><a href=”#”>Home</a></li>
<li class=””><$DXLogin$></li>
<li class=””>
<$DXAdmin$>
</li>
</ul>
</div>
</div>
</div>
</div>

The HTML5Shim code is needed to insert the HTML5 header and footer elements, which IE7 does not support.

Here is the code for my ‘header section’:

<!– Subhead ================================================== –>
<header class=”jumbotron subhead” id=”overview”>
<div class=”container”>
<div class=”row”>
<div class=”span3″ style=”margin-top:20px;”><img id=’id_photo’ class=’left’ src=’../dx/profileNoPhoto.png/$file/profileNoPhoto.png’ alt=’logo’ title=’logo’ height=’51’ width=’51’ /></div>
<div class=”span6″>
<h3><$DXTitle$></h3>
<h5><$DXDescription$></h5>
</div>
</div>
</div>
</header>

As you can see, you really need that HTML5Shim code here!

Here is the code for my ‘left column’ containing the search bar and navigational links (tag cloud, recent entries):

<!– Docs nav ================================================== –>
<div class=””>
<form class=”search” style=”margin:10px 0 0 0;” title=”Search” method=”get” id=”searchForm” action=”javascript:doSearch(”,”,”,”);”>
<input title=”Search” type=”text” alt=”Search” style=”width:180px;” value=”Search” name=”s” id=”Query” onblur=”if(this.value==”) this.value=’Search’;” onfocus=”if(this.value==’Search’) this.value=”;” />
<input type=”image” src=”../search.gif” title=”Search” alt=”Search”/>
</form>
</div>

<div>
<h4>Hot Topics</h4>
</div>
<ul class=”nav nav-list bs-docs-sidenav”>
<$DXHighlighted$>
</ul>
<div>
<h4>Tags</h4>
</div>
<div class=”tagCloud”>
<ul><$DXTagCloud$></ul>
</div>

<div>
<h4>Latest entries</h4>
</div>
<ul class=”nav nav-list bs-docs-sidenav”>
<$DXRecentSubjects$>
</ul>
<br/>

I wonder how I could get this column BELOW the second, content column, when the media queries kick in for e.g. smaller devices. I have not find out yet how to do this (again you may contribute here to improve my design)…

Then my ‘main / content column’:

<div id=”content”>

<a id=”mainContent” name=”mainContent”></a>

<div id=”entries” class=”entry”>

<div class=”page-header”>
<h3><$DXSubjectLink$></h3>
<p class=”pull-right” width=”80″ height=”80″ alt=”<$DXAuthor$>”/><$DXAuthorImageLink$></p>
<h6><$DXAuthor$> &nbsp;<span class=”date”><$DXLocaleLongDate$> <$DXTime$></span></h6>
<p style=”font-size:0.9em;”><img id=’id_photo’ src=’../dx/tag_blue.png/$file/tag_blue.png’ alt=’tags’ title=’tags’ height=’16’ width=’16’ /><$DXCategory$></p>
</div>
<p><$DXItemContent$></p>
<h4>Comments [<$DXCommentCount$>]</h4>
<p><$DXInlineComments$></p>
<commentblock>
<ul class=”actions inlinelist”>
<li class=”first”><$DXInlineCommentLink$></li>
</ul>
</commentblock>
<br/>
</div>

</div>

Nothing strange here. Therefore a preview:

Finally the footer section. This contains now mainly the navigational links that were displayed in the right column. For performance I load the JQuery and Bootstrap scripts at the end:

<!– Footer ================================================== –>
<footer id=”bottom-nav” class=”footer”>
<div class=”container”>
<p class=”pull-right”><a href=”#”>Back to top</a></p>

<div class=”row”>
<div class=”span3″>
<h4>Feeds</h4>
<ul class=”footlink”>
<li><img src=”../dx/Feed.png/$file/Feed.png” border=”0″><$DXRSS$></li>
<li><img src=”../dx/Feed.png/$file/Feed.png” border=”0″><$DXRSSComments$></li>
</ul>
</div>
<div class=”span3″>
<h4>Blog Roll</h4>
<ul class=”footlink”>
<$DXLinks$>
</ul>
</div>
<div class=”span3″>
<h4>Recent</h4>
<ul class=”footlink”><$DXRecentSubjects$></ul>
</div>
<div class=”span3″>
<h4>Archive</h4>
<ul class=”footlink”><$DXMonths$></ul>
</div>
</div>

<p><$DXCopyright$></p>
</div>
</footer>
<script src=”http://code.jquery.com/jquery-latest.js”></script&gt;
<script src=”bootstrap.min.js/$file/bootstrap.min.js”></script>

Stylesheets

I noticed that default a stylesheet called global.css is loaded (I am not sure where that comes from, but I see it in the page source – please get me some proper system documentation, IBM).

So in this stylesheet I load Bootstrap and it’s responsive part:

/* First, pull in Bootstrap’s stylesheet */
@import url(bootstrap.min.css/$file/bootstrap.min.css);
@import url(bootstrap-responsive.min.css/$file/bootstrap-responsive.min.css);

/*
Custom Blog Stylesheet
*/
/* Now the custom styles */

body{
font-size:0.8em;
font-family:Verdana,sans-serif;
background-color:#FFFFFF;
background-image:url(‘../dx/grid-with-white.png/$file/grid-with-white.png’);
background-repeat:repeat scroll 50%;
}

For the top navbar we have guidelines to use a gradient style. I noticed that IE, Firefox and Safari (remember our mobile target) behave a bit different here so I stated:

.navbar-inverse .navbar-inner {
overflow:auto;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#f8f8f8, endColorstr=#e1e1e1);
-ms-filter: “progid:DXImageTransform.Microsoft.gradient(startColorstr=#f8f8f8, endColorstr=#e1e1e1)”;
background: -moz-linear-gradient(rgba(245, 245, 245, 0.6), rgba(204, 204, 204, 0.6)) repeat scroll 0 0 transparent;
background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#e1e1e1));
border-bottom: 1px solid #DDD;
font-family:Arial,sans-serif;
color: #555555;
}

For the footer we use a gradient image:

#bottom-nav{
font-size:0.9862em/1.5em Verdana,sans-serif;
font-family:Verdana,sans-serif;
background-color:#E1E1E1;
background-image:url(‘../dx/footer-grid.png/$file/footer-grid.png’);
background-repeat:repeat scroll 50%;
}

Before having the HTML5Shim script applied IE7 refused to load an image for the background. Took some time to have that figured out.

Some final thoughts

Am I happy? For sure! In less than a day I transformed the blog application into a compatible site for mobile devices. No data migration to any new system/application or whatever!

Users can continue to work off-line (still a killer feature) just as they are writing a simple mail message. Import pictures taken at site visits all around the world and share it with their colleagues (occasional we notice also pictures from company parties, birthdays and social celebrations).

Blog owners can still modify the look & feel of any blog application, without disturbing anything for other blog applications. I heard stories of vendors that do not recommend to modify the common page of their collaboration platform, duh!

It would be nice if IBM would lift up the design of the DOMINO blog template to 2012 (2013 is also fine for me) with XPages and connection points to other social services.

If not, at least they can provide a complete, proper documentation of the application, so we understand what we implement in our environment. But this last request seems like ‘shouting to the wind’ (a Dutch saying).

Note: this was my first encounter with Twitter Bootstrap, so suggestions for improvement are more than welcome!

Cheers!

Embedding Flash movies in an XPage

I am currently working on an application to distribute movies across the organisation. Something similar as OpenTV on OpenNTF, but then 99% based upon XPages technology.

The movies I have are curently all in FLV (Flash Video) format which is fine for me.

I have taken a look at HTML5 and video, but we still have many Internet Explorer 7 installations which does not seem to run with HTML5 media Libraries that contain fallback scenarios :-/

Therefor I believe I am stucked for now with an Flash Video based solution.

Since I have no experience at this point with integrating Flash in XPages I wonder if you have any recommendations or sample code?

OpenTV seems to be using a JS Library called Swfobject which seems to do the job just fine…