Sorting an unsorted XPages document collection based on a date field

In one of my recent applications I had a requirement to return the top 500 search results, but sort them by a specific date field on the document, in descending order. Due to the size of the database doing a view.FTSearchSorted was not feasible as it was too slow. So I searched around and found some code for sorting a JavaScript Array of objects.

Creating the array

Search the database and push the search results into a JavaScript array

var sSearch = "[FIELD Subject contains smith]"
var dc:NotesDocumentCollection = db.FTSearch(sSearch, 500)
var doc:NotesDocument = dc.getFirstDocument();
var myArray=[]
var i=0
var sTemp = ""
while (doc != null) {
	i=i+1
	var obj={}
	obj.count=i
	obj.Customer = doc.getItemValue('Customer')
	obj.malfunctionEnd = @Text(doc.getItemValue('dateField'))
	obj.unid = doc.getUniversalID()
	myArray.push(obj)
	var tmpdoc = dc.getNextDocument();
	doc.recycle();
	doc = tmpdoc;
}

The sort function

Create a function to return a bubble sort of dates. This function works by comparing if two dates should be sorted based on their “getTime()” which returns a value in seconds.

function custom_sort(a, b) {
var ndtA:NotesDateTime = session.createDateTime(a.dateField);
var ndtB:NotesDateTime = session.createDateTime(b.dateField);

return ndtB.toJavaDate().getTime() - ndtA.toJavaDate().getTime()
}

The final step

Using the JavaScript sort function we can pass in the name of a callback function which adds additional processing to the sort function. The resulting array can then be processed by a repeat control providing the information out to the end user. All the code shown here would be placed in the value parameter of the repeat control.

myArray.sort(custom_sort);
return myArray

Mustache.js – How to create a client side Repeat control in XPages

Whether or not you realize it, everyone who uses a repeat control in XPages development is actually using a server-side template. Let me demonstrate the concept….

We create an object through many different interactions with the XPages back end APIs and Server-Side JavaScript interactions. The object can be many different constructs. The XPages repeat control then iterates through each member within the object and repeats the same thing over and over based on the repeat control’s starting value object.

In the following example we create a repeat control from a JavaScript array control. It iterates over each object within the array allowing the repeat control to work as a template for creating HTML.

<xp:repeat id="repeat1" rows="30" var="myObj">
	<xp:this.value><![CDATA[#{javascript:
	var myArray=[
		 {
			  "@entryid":"1-431C28F894B0548185257C22000A8403",
			  "firstname":"Agnes C.",
			  "lastname":"Smith",
			  "address":"24256 Leisure Lane"
		  },
		  {
			  "@entryid":"2-4ED02366A420D23985257C4F000B0BD7",
			  "firstname":"Albert",
			  "lastname":"Scoggins",
			  "address":"3525 Koontz Lane, second"
		  },
		  {
			  "@entryid":"3-6D8120FA75B4BCCF85257C4F000B0B5D",
			  "firstname":"Alejandra",
			  "lastname":"Dodge",
			  "address":"3044 Simpson Avenue"
		  }
	]

	return myArray}]]>
	</xp:this.value>
	<p>	Hello my is
		<strong>
		<xp:text escape="true"
			id="f1" tagName="h4" disableTheme="true"
			value="#{javascript:myObj.firstname +' '+ myObj.lastname}">
		</xp:text>
		</strong>
	</p>
	<br />
	<p>
		I live at
		<xp:text escape="true"
			id="f2" tagName="h4" disableTheme="true"
			value="#{javascript:myObj.address}">
		</xp:text>
	</p>
	<hr />
</xp:repeat>

The output from this repeat control is shown below

mp1

HTML Templating

Using the mustache.js library we are able to display a JavaScript object using an HTML repeat control in a directly analogous way to the XPages server-side method described above. The following code does pretty much the same as the server side example above.

What is interesting to note is the use of the SCRIPT tag in the following code. By giving it a type of “text/template” the browser does not execute the contents of the SCRIPT tag. But it also ignores the HTML within. We can access the contents of the script as it is a DOM object. This makes for the perfect storage container – we do not have to hide the template HTML with CSS.

The HTML

<!-- mustache uses AMD and as such will not work in R9 unles you add it this way *stupid dojo 1.8 issue*-->
<xp:this.resources>
		<xp:headTag tagName="script">
			<xp:this.attributes>
				<xp:parameter name="type" value="text/javascript" />
				<xp:parameter name="src" value="js/mustache.js" />
			</xp:this.attributes>
		</xp:headTag>
</xp:this.resources>

<script type="text/template" class="template">
{{#items}}
	<br /><p>	Hello my is
		<strong>
		{{firstname}} {{lastname}}
		</strong>
	</p>
	<p>
		I live at
		{{address}}
	</p>
	<hr />
{{/items}}
</script>
<div class="templateHere"></div>

The JavaScript

$('document').ready(function(){

	var myArray={
		items:[
		 {
			  "@entryid":"1-431C28F894B0548185257C22000A8403",
			  "firstname":"Agnes C.",
			  "lastname":"Smith",
			  "address":"24256 Leisure Lane"
		  },
		  {
			  "@entryid":"2-4ED02366A420D23985257C4F000B0BD7",
			  "firstname":"Albert",
			  "lastname":"Scoggins",
			  "address":"3525 Koontz Lane, second"
		  },
		  {
			  "@entryid":"3-6D8120FA75B4BCCF85257C4F000B0B5D",
			  "firstname":"Alejandra",
			  "lastname":"Dodge",
			  "address":"3044 Simpson Avenue"
		  }]
	}
	var e, newStuff, template;
	try {
		 template = $('.template').html();		//Get the HTML from within the SCRIPT tag with the template class
		 newStuff = Mustache.to_html(template, myArray)	//Apply the myArray object to the template HTML
	   } catch (_error) {
		 e = _error;
		 newStuff = e.toString();
	   }
	$('.templateHere').html(newStuff)
})

Here is the web page created
mp2

Below you can see a direct comparison between the repeat control code and the HTML template code

mp3

Implementing a REST service

The example above uses a typed JavaScript object to create the data for the template – and you have probably realized the example I used is the same format as a XPages REST service <xe:viewItemFileService> feed. So with a little bit of AJAX to put in the data object we are able to create the same output using REST data rather than typed object.

$('document').ready(function(){
	var e, newStuff, json, template;
	$.ajax({
		url: 'xRestService.xsp/byFirstName'
	}).done(function(data){
	try {
	     template = $('.template').html();
	     newStuff = Mustache.to_html(template, data)
	   } catch (_error) {
	     e = _error;
	     newStuff = e.toString();
	   }
	   $('.templateHere').html(newStuff)
	})
})

Except in this case we loaded *all* the names in the REST service into the page using the template – in 15 lines of code

mp4

Conclusion

While there may not, on the surface, seem to be much point in using HTML templating when we have server-side repeat control templating, if you want to take your web applications running on XPages into the future, this is the beginning…………More to come on this topic 🙂

Using jQuery to remove Dojo CSS from an XPage

I am currently working on a customer application which is oneuiv2.1 themed and I wanted to create a simple jQuery Mobile site. the dojo css was really messing up the styling and just for interest I wanted to see if I could programmatically remove the dojo css from the page client side

The application has the property checked to use runtime optimized JavaScript and CSS. This combines all the dojo css files nicely into one link.

do1

Using a jQuery selector I can get a handle on that <LINK> as follows

$('link[href*="dojo.css"]') //select all LINK objects where the href contains dojo.css

do2

Once I have that I can just remove the element from the DOM like this

$('link[href*="dojo.css"]').remove()

Unfortunately I cannot show you what this does my customer’s site to make it look all pretty and jQueryMobile like, but I can show you how it blows up a oneui site and you can take it from me this fixed my problem.

Just add the above code in a *SCRIPT* tag within your XPage and it will remove the dojo style before it is rendered to the end user – thus they will never know.

http://xpages.info/xpageshome.nsf/Demos.xsp

Before

do3

After

do4

 

Caveat

Yeah I realize this means the CSS file(s) are downloaded and then removed and I am sure there are more elegant ways to handle the issue server-side.

This was an exercise in learning that jQuery can be used to remove entire CSS DOM objects 🙂

Troubleshooting JavaScript library errors in XPages

Coincidentally on three separate occasion, with three different customers/developers using three different libraries I encountered the same issue last week. I am going illustrate the process I go through when troubleshooting JavaScript libraries and use this one issue as the example.

The same question from each of them: Why is my JavaScript library not working in my XPage?

What does Firebug say?

If you ever ask me for help this will always be my first question – and a significant number of issues can be solved by just looking at the browser console and taking action based on knowing what the failure is.

Typical errors

Here are some typical errors/messages and what can be done about them

  • $ is not defined
    • Problem: This means you have tried to use jQuery (most likely) before the jQuery library is loaded. jQuery plugins are dependent on the jQuery library being loaded before them in the browser.
    • Solution: check that you are adding jQuery, the path is correct and it is being loaded before any other library dependent on it.
  • 404 file not found
    • Problem: Looking through the Net tab in firebug you will be able to check and see if all your files loaded correctly
    • Solution: Right click on the failing URL and open in new tab then you can see the whole URL.
      • Check to make sure the file is in fact where you think it should be
      • Check your spelling
      • Check to make sure that your new design element is built. XPages will report 404 file does not exist if you have not built the new element. Even though it is in your database does not mean it is available.
  • 400 Bad request
    • Check and make sure that the library has not appended anything to the end of the file name making it illegible to the Domino server (see Caching below)
  • General JavaScript errors
    • Problem: a lot harder to troubleshoot. You will get a message saying that the dojo.js or jQuery.min.js has reported an error and it looks like the library has a bug. Chances are though that it is a coding error or a configuration error on your part which is bubbling up as an error in the library using the code you have created.
    • Solution: work back to the example and see where your code is different.

Caching

Many JavaScript libraries append random values to the end of files with the positive intention of avoiding browser cache issues. Ext JS is one example of this – when you ask for the required files within the grid “random crap” gets added to the end of the file name:

Ext.require([
      'Ext.data.*',
      'Ext.grid.*',
      'Ext.ux.grid.FiltersFeature'
    ]);

When the page loads you see nothing and this issue in Firebug

err1

So when we right click and open the file in a new tab we see the following URL in full

The answer is really very simple – IBM Domino is a web server waiting for requests, and if you (or the library you are trying to use) asks the server for something it does not understand it will reject you with a 400 bad request error. In this case it is trying to interpret the _dc= command on the FiltersFeature.js file and failing.

There are two possible solutions and depending on the library configuration you should be able to work around it

  1. Turn off caching if you believe it will not cause issues
  2. Modify the URL of the incoming file by adding ?open& on it

In the case of Ext JS we add the following code to turn off caching

Ext.Loader.setConfig({
  enabled : true,
  disableCaching : false //This turns off caching - nice double negative I know (v4 and above)
});

Ext.require([
      'Ext.data.*',
      'Ext.grid.*',
      'Ext.ux.grid.FiltersFeature'
    ]);

But it *must* come in your code *before* the require code otherwise it won’t work.

Require.js usage in XPages R9

As has been detailed by Sven Hasslebach, along with his solution, Dojo 1.8 (used in R9) does not play at all with other AMD libraries. If your JavaScript library used require.js or an equivalent loader library you must make sure it is loaded in the header before dojo. Check out Sven’s post for the solution/workaround.

Conclusion

Troubleshooting is always easier when you have a checklist of possible issue to go through. The more you do them the more they will become muscle memory. If anyone has any other good tips please feel free to add in the comments 🙂

Exciting changes for 2014 – moving to Chicago

2013 was a fantastic year for the PSC XPages team. We completed work on the world’s largest XPages project, started work for a number of new customers and early in 2014 we are actively looking to hire the best XPages developers available . It is a very exciting time to be taking a leading role within the largest XPages consultancy practice in North America.

With all this comes the opportunity for advancement. I am very pleased to announce that I have been promoted from Senior Consultant to Engagement Manager, and I will be moving from Virginia to Chicago with the family in the summer.

My involvement with the XPages development team has evolved over the past 12 months from that of technical lead to project lead and with that comes different roles and responsibilities within the team. I am not giving up development by any means and although the position is not Engagement “Developer” I will still be very hands on my projects.

I want to thank the entire PSC Collaboration practice and especially the XPage team for their collective efforts over the last 18 months. Without their success and enthusiasm there wouldn’t be a need for someone to take on this role.

I want to thank John Quirk and Andrew Barickman for giving me this opportunity to progress within the company and showing their faith in my abilities and commitment to the company.

Earlier this week in Chicago the temperature was described as somewhere between Antarctica and Neptune, my wife is thrilled……

🙂

Lowering your ODS – an oldie but goodie

After Connect this year I tried to post my Ext JS sample database on my demo site and most users were reporting unsupported notes version. I did some digging and it turns out that amongst everything else R9.0.1 has a newer ODS (52) and therefore would not run on a lower than R9.0.1 server/client.

So after much idiocy and locally encrypted stupidity on my part, I did a search around and found/remembered that you can reduce the ODS aaaaaall the way back to 20 by doing this

  • File – Application – New Copy
  • Name the file .NS4 (backwards compatible to R4 no less)
  • Rename the .ns4 as a .nsf
  • and it worked !!

Obviously XPages will not work on an R4 server – but by reducing the ODS it make it compatible with the R8.5.x servers

Bizarrely enough it was also quite significantly smaller than the nsf copies I was creating ODS 52

My thoughts on Connect 14 – What makes a good presentation?

I wanted to write down some thoughts and ideas, notes almost, after watching the IBM Connect 2014 technical presentations.

Ultimately what I want to understand and be able to execute myself is – What makes a good presenter/presentation?

Let’s ignore the content for the moment. Last week I attended sessions where I was interested in the content but the delivery was poor. I also went to presentations where the content didn’t interest me but the presentation kept my attention. Figuring out how to do a good presentation is very important to me. I would love to get feedback (comments below) on what other people think as I want to learn and I expect others do to.

This is a necessary life skill as a consultant /project lead – you need to be able to capture the attention of your audience even if they do not believe they are necessarily interested in what you have to say.

So what makes a bad presentation?

This is much easier to answer and the opposite is not necessarily true.

  • Reading from the slides
    • Absolute #1 presenter sin in my book. It shows a lack of belief/knowledge in what you are talking about. It is very boring to watch you read from a slide when I can do it myself. It demonstrates very quickly there is no point in me being here as I can get the slides later.
  • Too much code on the screen
    • see above
  • Spending too long explaining abstract concepts in a technical manner
    • On the one hand if this is a technical session, I understand, but if lose your audience at any time during your 10 minute rant about how awesome your code is, they are lost and you have failed.
    • see above
  • A bad abstract
    • Too often an unintentional bait and switch can really hurt a presenter. If your abstract claims that you are going to speak about jQuery then don’t spend 10 minutes bashing Dojo. Stick to the topic. Ensure that you talk to your abstract and don’t include large, previously declared, sections out of the blue; surprising attendees.
    • Many “non-Best Practices” sessions at Connect have abstracts that are vague and non-committal on the subject matter. What this then means is that attendees come to the session expecting one thing and don’t get it. Bad score – regardless of content if it is not why the attendee came you get a bad grade, people walk out, general feeling in the room is lower, bad scores.
  • No demonstrations
    • What do we all enjoy most about the OGS – demos
    • What do we hate most about the OGS – no demos
    • It applies to all of us as well
  • Don’t insult your audience
    • There is no point in going through something which has been discussed frequently on blogs – one slide – go read these links later, is all you need. We are here to learn about new things and be excited – don’t bore us with things we either know or can be looked up easily. (see know your audience and bad abstract)
    • Explaining to me how you make a REST Service work is not necessary when your talk is about something which consumes the REST service – tell me more about the something advertised and tell me where to go to find out more about REST services.

So what makes a good presentation?

  • Structure
    • Everything you create must have a start, a middle and an end. Presentations are no exception.
    • Use slides to break up the flow based on the agenda. This was one of the best things about the template slide decks for this connect14 – purposeful section slides.
    • There is no reason why you cannot break the session up into many sections. But they must make sense, there must be a segue from one to the next and then must flow well. It also forces you the presenter to stay on the pre-planned path and not deviate too much
  • Leave your audience wanting more
    • If everyone walks out going “huh well I guess that is it then” you fail. If they walk out taking notes from your slides because they want to look up the demos or downloads later – then you have won.
    • You do not have to beat a dead horse to get your point across (see less is more below)
  • Practice
    • The only way you get better is practice, analyze, learn from your mistakes
    • Offer to speak at LUGs – they are almost all technical and with friends – you really can’t go wrong !
  • Know your audience
    • Make sure your abstract makes clear what the audience should expect and what level the talk is aimed at. This will ensure a better reception and better transfer of knowledge.
    • For example: I know a thing or two about XPages but I don’t have the faintest clue about what OSGI plugins. If I attended a session about the Extension Library I would be lost in a heartbeat if the first 15 minutes were spent explaining how the ExtLib OSGI plugin concept worked. If OSGI plugins were not mentioned in the abstract I would be scoring low.
    • Equally don’t insult them all by pitching too low either.
  • Vary your presentation method frequently
    • Don’t do the same thing slide after slide after slide.
      • Use visuals
      • Use metaphors
      • Use humor
      • Use demonstrations inter-dispersed with the rest of the content
  • Talk to the audience don’t lecture them
    • A presentation which feels like a conversation is much easier to comprehend than one which feels like a lecture.
    • It is OK to gloss over something – don’t feel like you have to explain everything. You don’t have time so explain the absolute essentials and then stick to generalizations because you don’t have time otherwise (unless this is a show and tell session)
    • Remember – your audience cannot keep up with you and take copious notes in the session. This is not a lecture. This should excite the audience to the possibilities of learning something new and it is not unreasonable for them to go away and do some research themselves. Give the audience the knowledge and the tools (and even code to download) to help themselves. They cannot possibly leave the session being an expert so don’t try and make them one.
  • Less is more
    • Attendees will be happier to finish a few minutes earlier than have to run to their next session. Don’t overfill the slide deck (see making them want more)

And I could go on and on. But please comment and tell me what you think is good and or bad as presentation skills – it is good for all of us to learn from each other 🙂