Great conversation with Jesse Gallagher

This week I had the great pleasure of Co-Hosting the Taking notes Podcast with Bruce Elgort and JulieAnn Robichaux – http://www.takingnotespodcast.com/blogs/takingnotes.nsf/dx/TakingNotesEpisode171.htm. This week we were talking to Gigerby Jesse Gallagher about his experience with XPages and his evolution from a Comp Sci Java Developer and self taught Rails guy to Lotus Notes and beyond.

Jesse is a scary smart guy but what is special about him is that he is very eloquent with it. People this smart are rarely blessed with people skills and I think it is clear from the podcast he is very amiable, easy to talk to and scary smart. I had the pleasure of meeting Jesse in Pittsburgh at MWLUG2012 and I look forward to carrying on the conversation over some beers at #Connect13

We talked about Single Page Application development, coding standards, simplifying code development techniques, Java, Dojo, Ruby, Rails, ExtLib, Cats, jQuery and how we are planning to bride the IBM development team to include Web Sockets in the Domino server. #BringWebSocketsToXPages

One of the things I like about this show (and many other Taking Notes Podcasts) is that really sounds like the four of us are sitting around a table having a beer and chatting about life and XPages in general – love it.

Thanks to Bruce and Julian for having me on the show again and I look forward to the next one 🙂

Using jQuery to test if a checkbox on your XPage is checked

Problem
I have a checkbox and if it is checked I need to hide a table. How can I test if it is checked or not in a simple fashion?

Solution
Here is the checkbox

<xp:checkBox text="Audit" value="#{project.audit}" id="checkMarky">
</xp:checkBox>

And here is my table

<xp:table styleClass="markyTable" style="width: 100%">
<xp:tr >
	<xp:td styleClass="td1" colspan="4">
		..stuff
	</xp:td>
</xp:tr>
</xp:table>

When the page Loads
When the page loads I determine if the table needs to be displayed or not based on the checkbox status. Using the “.is()” function I can return true or false and then based on that I can determine if the table is hidden or not.

$('document').ready(function(){
	//test if the id ending in checkMarky is checked
	if ( $('[id$=checkMarky]').is(':checked') ){
		//if so then hide all items with the class markyTable
		$('.markyTable').css('display', 'none')
	}
})

Toggling the Table
And then in the onChange event of the checkbox I make a very simple change using slideToggle. In the onLoad I determined if the table should be hidden or not – so if the status if the checkbox is reversed (changed) then either show or hide the table – and in this case use nice transition as well just as a bonus.

	$(".markyTable").slideToggle()

Conclusion
.is(‘:checked’) is the secret sauce in this example and returns true or false if the checkbox is checked.

library.onLoad – what does it do and who loads last?

In this article I will demonstrate that there multiple methods for determining the “onLoad” event of you page and discuss which method you should use and when.

Introduction

Once upon a time when the world was young and we did not have JavaScript libraries we had the onLoad event of the document.

	<body onload="alert('Hi Marky')">

This caused some issues in itself because it indicated that the HTML was loaded – but did not have any knowledge of the images on the page and they might not have finished downloading – so this was not a reliable way of determining if the page was really loaded.

Then came the Library

If you are including functionality from a Library there is a high probability that the Library is doing some sort of Document Model (DOM) manipulation when the page loads – it has to do this to provide the functionality you are asking it to do.

Take your XPage as a prime example – you are including (well ok the XPage is including) the dojo Library and with that the XSP library built to provide XPage functionality. If you look at the source of an XPage containing a date control you will see this

<input id="view:_id1:_id2:_id39:inputText2" class="xspInputFieldDateTimePicker" type="text" name="view:_id1:_id2:_id39:inputText2" />

But if you look at the HTML created AFTER dojo and the XSP have done their magic the field looks like this!!

<span class="xspInputFieldDateTimePicker" style="display: inline-block;">
</span>
<div id="widget_view:_id1:_id2:_id39:inputText2" class="dijit dijitReset dijitInlineTable dijitLeft xspInputFieldDateTimePicker dijitTextBox">
	<div class="dijitReset dijitValidationContainer"><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" tabindex="-1" type="text" value="? " readonly="readonly" />
	</div>
	<div class="dijitReset dijitInputField dijitInputContainer"><input id="view:_id1:_id2:_id39:inputText2" class="dijitReset dijitInputInner" tabindex="0" type="text" value="" />
		<input style="display: none;" type="text" name="view:_id1:_id2:_id39:inputText2" />
	</div>
</div>

<span id="view:_id1:_id2:_id39:inputText2_Container" class="xspInputFieldDateTimePicker" style="display: inline-block;">
	<span class="dijit dijitReset dijitInline dijitButton xspInputFieldDateTimePicker">
		<span class="dijitReset dijitInline dijitButtonNode">
			<span id="dijit_form_Button_0" class="dijitReset dijitStretch dijitButtonContents" style="background-image: none; margin: 0px; border: none; padding-left: 0px; background-position: 0% 0%; background-repeat: initial initial;" title="">
				<span class="dijitReset dijitInline dijitIcon xspInputFieldDatePickerIcon">
				</span>
				<span class="dijitReset dijitToggleButtonIconChar">?</span>
				<span id="dijit_form_Button_0_label" class="dijitReset dijitInline dijitButtonText dijitDisplayNone">
				</span>
			</span>
		</span>
		<input class="dijitOffScreen" tabindex="-1" type="button" value="" />
	</span>
</span>

And that doesn’t happen in an instant – it takes time……and if we want to programmatically interact with the “new” date picker code we have to wait for the dojo and XSP to do their thang.

Library.onLoad
This is where library.onLoad comes into play – it is an event triggered when the library believes that the page is safe to interact with – i.e. everything it needs to do is complete.

dojo.addOnLoad

The dojo.addOnLoad page explains better than I can

dojo.addOnLoad is a fundamental aspect of using Dojo. Passing addOnLoad a function will register the function to run when the Dom is ready. This differs slightly from document.ready and body.onload in that addOnLoad waits until all dojo.require() (and their recursive dependencies) have loaded before firing.

XSP.addOnLoad

The XSP is a library built on top of a library and has dependencies on the dojo library.

In our XPage environment we have the onClientLoad event accessible from the XPage event section – this is actually the GUI equivalent to XSP.addOnLoad which is a programmatic function we have available through the XSP library.

onClientLoad
onClientLoad

jQuery – $(‘document’).ready()

jQuery’s version of this onLoad capability is described as follows:

While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it’s important to reference external stylesheets or embed style elements before referencing the scripts.

These people are so much more eloquent that I 🙂

So if everyone fires when the DOM is ready then they should all fire at the same time…right?

Well that is what occurred to me and I wanted to find out – people have told me through the life of this blog that I should always use the XSP.addOnLoad because it fires when the XPage is ready – but if I use jQuery is that ready as well?

Experiment

It is really not all that complicated to test who fires first – what I created was a variable to track when the page started to load and then asked each library to subtract the time when they fired “when the DOM was ready” and write it to the page. This code sample was added to the top of my XPage so the variable “a” is created immediately when the page is loaded and each library then triggers when it is ready.

<script type="text/javascript">// <![CDATA[
		var a = new Date()
		document.write("Started at: "+a)

		$('document').ready(function(){
			// alert('jQuery')
			var b = new Date()
			document.getElementById('divJquery').innerHTML = b-a
			var s=document.createElement('div');
			s.innerHTML = "<div>"+"jQuery - "+(b-a)+"</div>"
			document.getElementById('iAmFinished').appendChild(s)
		})

		XSP.addOnLoad(function(){
			// alert('XSP')
			var c = new Date()
			document.getElementById('divXSP').innerHTML = c-a
			var s=document.createElement('div');
			s.innerHTML = "<div>"+"XSP - "+(c-a)+"</div>"
			document.getElementById('iAmFinished').appendChild(s)
		})

		dojo.ready(function(){
			// alert('dojo')
			var d = new Date()
			document.getElementById('divDojo').innerHTML = d-a
			var s=document.createElement('div');
			s.innerHTML = "<div>"+"dojo - "+(d-a)+"</div>"
			document.getElementById('iAmFinished').appendChild(s)
		})

// ]]></script>

and in the onClientLoad event


		<xp:this.script><![CDATA[
			var e = new Date()
			document.getElementById('divOnClientLoad').innerHTML = e-a
			var s=document.createElement('div');
			s.innerHTML = "<div>"+"onClientLoad - "+(e-a)+"</div>"
			document.getElementById('iAmFinished').appendChild(s)
			]]>
		</xp:this.script>

Demonstration

You can see the page I created to test this experiment here

http://demo.xomino.com/xomino/xPlay.nsf/xOnLoad.xsp

You will see that there are a lot of typeAhead and date picker fields on the page – the reason I did this was to slow down the loading of the page – The libraries were all firing very close together and I wanted to see if I could separate them by delaying the page loading – it didn’t see to make a difference they all fired with the same delay between them.

The results

Well I have to say I was surprised and very glad that I created this experiment because it will change how I determine when the DOM is ready in the future. You can keep testing this for yourself by refreshing the test page above but you will see consistently that the libraries fire in this order:

Library Time to
DOM ready (ms)
Dojo 198
XSP 197
onClientLoad (XSP) 198
jQuery 209

As you refresh the page you will see different load times but they are always grouped XSP, clientOnLoad

results of load order
results of load order

Why are these different?

Each library determines when they believe the DOM is ready differently – each one is assuming that the DOM is ready when everything is loaded for it’s own library (naturally dojo doesn’t care when jQuery is loaded). For some insight check this StackOverflow post out

How does the jQuery ready() function work?

From my experiments I noticed that dojo, XSP and onClient load were always no more than 1 milisecond apart and each one of them sometimes came first – i think there is an aspect of the fact that they are all trying to create a DIV and append it to the page (my test code) and that has some nominal time associated with it and they are all trying to append to the same DOM element – for the sake of statistical accuracy my observation is that dojo is usually the first to record a result but because it is not always first I cannot claim that categorically.

I also have to add that there is a discrepancy with the onClientLoad test because it does not use the same variable as the other libraries – because it is being added to the page in a different fashion it is not an identical test. I am not however going to add the whole of the code to the onClientLoad event because then I would be asking the onClientLoad event to trigger the other libraries which isn’t right.

Conclusion

So here is the important things to remember when you are developing your xPage

  1. Never use dojo.addOnLoad – it fires almost exactly the same time as the XSP but more importantly your xPage XSP library is not ready
  2. If you are using jQuery *always* use $(‘document’).ready()
  3. Otherwise use XSP.addOnLoad/onClientLoad

It is interesting to see that jQuery takes longer to be ready and why that is, is way beyond the comprehension of this developer but there is a clear separation and because almost all of my work uses jQuery in one fashion or another I will always use $(‘document’).ready()

Please feel free to argue my experimental methodology if you think it can be improved 🙂

Auto-focus – Do it! It’s just lazy not to.

In this article I will discuss the need as a developer to use an auto-focus on your XPages. You do this when the end-user needs to type something onto your webpage and should not have to use their mouse to click in the field first.

Introduction

You’ve been there – you go to a website internal or external to your company and you have to login in or type something into the page – the search field or something of that ilk. It is the only field on the whole page and you have to use your mouse to focus on the field – frustrating beyond belief and quite frankly, lazy on the part of the developer. It is a pet peeve of mine when something as simple as one line of code can make a big difference to the first thing a user does on your site.

Can you imagine going to Google.com and having to focus on the field to get started on your search? Stupid idea – or so you would think.

Login Pages

The login page is perhaps the most obvious thing – as the developer you should ALWAYS focus on the username field – it is just lazy not to! It is harder on the user to have to click in the field and they are entering your website with an irritation on their mind already.

Auto-focus on the Username field
Auto-focus on the Username field

 

So how do we do this?

Well it depends on what takes your fancy that day…..but this is normally something you would do within some <script> tags on your web page.

Using the plain old JavaScript method

  document.getElementById("username").focus()

In Dojo

  dojo.byId("username").focus()

In jQuery

  $("#username")[0].focus()

NOTE

We use the [0] to get the DOM Node element and use the HTML focus() method
.focus() when applied to a jQuery object is an event handler which determines what happens when you focus on something  – be careful to use correctly

$('#target').focus(function() {
  alert('Handler for .focus() called.');
});

In HTML5

The autofocus attribute of a field is new in HTML5 (thanks to David Walsh). You can also focus on a button and other DOM objects

<input autofocus="autofocus" />
<button autofocus="autofocus">Hi!</button>
<textarea autofocus="autofocus"></textarea>

Change the name of your file with – HTML5 “Download” attribute

In this article I will show you a very simple way to change the name of a file when the user downloads it using the new HTML5 “download” attribute.

The download Attribute 

This is unfortunately only support in Chrome so far but it is coming – the HTML5 download attribute – very simple and very effective. In the old days we had to fiddle with content-type and content-disposition to rename a file on the way out of the server – now much easier.

What we are trying to create is HTML which looks like this

	<a href="/jQInX.zip" class="xspLink" download="MarkySampleDatabase">
		Download the sample database - with download attribute
	</a>

The download=”MarkySampleDatabase” is the important part – it changes the name of the file in the a href to be “MarkySampleDatabase”

The XPages code

The following is 8.5.3 Xpage Source Code adding the download Attribute via the attr properties of the


	<xp:link escape="true" text="Download the sample database - with download attribute" id="link1" value="http://demo.xomino.com/xomino/jQinX.nsf/SampleDB/jQInX.zip">
		<xp:this.attrs>
			<xp:attr name="download" value="MarkySampleDatabase"></xp:attr>
		</xp:this.attrs>
	</xp:link>

Demonstration

And that is pretty much it – from the example which can be seen here there are two links both link to the sample jQinX.nsf sample database

Demo Page
Demo Page

Viewing the source shows us both links are the same…

The same link
The same link

But the one with the download attribute, downloads with a completely different name

Download Attribute in action
Download Attribute in action

Custom date field format in an XPage – mm/dd/yyyy

I was banging my head against the desk this morning for way too long…….

I have a date field which is displaying the date as 1/2/2012 and I need 01/02/2012 and that isn’t an option

Date field options
Date field options

And as I poked around I found “Custom date range” and looky there it is – wasted WAY too much time on this

Custom date options
Custom date options

And then 79 search and replaces in the database and we are all updated – YAY eclipse client

YAY search and replace
YAY search and replace

Using jQuery plugins – the version is important

A couple of times in the last week I have been trying to help a community member with their jQuery in XPages and it has turned out that the problem was because of the new jQuery v1.8 core library – something I had not thought about and wanted to clear up. I am always tell people in my article to just go to jQuery.com and get the latest core library – well now I have a caveat and will be more specific in future articles.

As best as they can, like all library developers, the jQuery team (unless otherwise stated) try to ensure the jQuery core library should be backwards compatible but there are specific things which are deprecated and dropped in subsequent versions. There are thousands of qUnit test modules created to do regression testing on the jQuery core but that doesn’t mean everything is caught – it is impossible to foresee every combination in every project – does this sound familiar…

When you download a plugin, you should always check the release notes to determine which version of jQuery core this plugin was written for/with. Especially with the older plugin written circa 2008/2009 they are many version of jQuery core behind and might not be forward compatible.

Many plugins (especially when downloading from gitHub) package a version of jQuery with that version – I recommend you first test with that version of the core and make sure it works in your xPage before moving to a newer version of the core library.

You also need to be careful that the plugin you are using is compatible with an older core library you might be using – sounds like common sense but it might not always be possible in a production environment.

Personally I have not had any issues with jQuery core v1.7.x running older plugins but I have not yet tried v1.8.

If you need an older version of the jQuery core they are all available here…

http://code.jquery.com/