Dave Leedy: Drink to 99 at IBMConnect

As many of you are aware – I feel like I owe a personal debt to Dave Leedy because of how he helped support me when I was getting into the community in the last year. Honestly he is fed up of hearing me talk about him (as you are too).

That said this post and subsequent request for help is not about what Dave has done for me – it is what Dave has done for you, and you, and you and the other thousands of YOU!

Notes in 9


XPages cheatsheet

Notes in 9 is over 2 years old and has over 28 hours of XPages related wonderment – if you are reading this blog and have never watched a NotesIn9 video I will be shocked. It is synonymous with the XPages community and is supported by many many contributors.

Not only does Dave invest time and effort into Notes in 9 he also pays for the hosting cost out of his own pocket – that’s right he is paying so that you to become a better developer – the least you can do is to say thank you.

So it is time to say thank you – in the best way we know – BEER

Dave Leedy should not have to buy himself a single beer at IBM Connect this year. Dave needs to get 99 beers to be bought for him to say thank you for the 99 NotesIn9 he has created/masterminded.

I would like to see #DrinkTo99 count=x on twitter so that we can track his progress throughout the week.

As I said on the Dave Leedy Taking Notes Podcast….if you see this man buy him a beer because he has helped you !

Buy this man a beer
Buy this man a beer

Oh and happy birthday mate 😉

Thank you Carl Tyler, Ed Brill and the lotus community.

So it is mid January 2012, somewhere in Orlando, deep in the Dolphin hotel – Gurupalooza is ON. It was my first ever Lotusphere (and last ironically in name at least) and I have to say I was pretty bored of the whole conference by Thursday morning. I was extremely naive about everything which was going on at the conference over the last 4 days. I had attended many sessions but had not learned a whole lot, I had been in bed by 11pm most nights and honestly it was just not what I had been looking forward to for 14 years!!

So I stood up and asked a question of the Gurus – “Why should I come back to Lotusphere next year? I thought this was a developers conference and I didn’t learn anything I couldn’t have learned by reading OpenNTF. Tell me why I should come back next year!” (That’s me middle on the right)

There were some awkward pauses and some comments about how come I didn’t meet new people and experience the conference – and quite frankly I didn’t “get it” – but also hadn’t put in the effort.

Carl Tyler was really the only person with anything positive to say – he was sat right on the left hand end of the stage nearest me and he said “you’ll be here next year because you will be presenting”. Sarcastic or not (I don’t think it was) that was one of two things which stuck out in the conference for me.

The other thing which stood out was my first experience with Social Media. The work colleagues I was with encouraged me to get on Twitter so that we could communicate with each other and see how sessions were going during the day. Earlier on that final day (I think) I happened to be in the session run by Ed Brill with other IBM product managers on the stage – Ed asked for questions from the room and questions from twitter – so I wrote a question on twitter asking if the new web based plugin to run notes client apps spelled the end of the notes client….and amazingly ed picked it out and read it to the room and then he followed me on twitter….my third follower and 1st real one after my work colleagues.

AAAARGH HOLY CRAP ED BRILL IS FOLLOWING ME ON TWITTER !!!! – which lasted for at least 5 minutes until I realized Ed Brill follows thousands of people on twitter. I had pretty much the same reaction about 10 minutes later when Bruce Elgort started to follow me on twitter – HOLY CRAP HOLY CRAP – Bruce…….Elgort…!!! *faints*

So I came away from the conference with a puzzled determination – I really hadn’t enjoyed the conference – but somehow that last morning had unleashed a fire in my belly – I wrote this article as my first blog entry (oh yeah it made me start blogging a few days later)

https://xomino.com/2012/01/22/lotusphere-2012-inspiring-and-not-in-a-way-i-had-expected/

And it started – I made a conscientious decision that I was in control of my destiny and I was going to take it back. As much as I hate to admit it – I like writing, it is cathartic and I love sharing, love teaching – I would be a teacher if it paid half decently. I set myself two goals for the year – to better learn XPages and to speak at Lotusphere next year.

Since this time last year I have:

  • Learned XPages (well a decent chunk of it anyway)
  • Changed jobs to now work for one of the most well known XPage consultancies in N.America
  • Written over 60 XPage related blog articles (this post will probably push me over 50,000 hits in 11 months)
  • Presented a session at MWLUG in Pittsburg
  • Done two Notes in 9 videos (and been mentioned on two others)
  • Been on the Taking Notes Podcast (with Bruce and Julian…OMG OMG OMG)  – twice !
    and most importantly
  • >>> I am presenting two sessions at IBMConnect 2013 <<<

So first of all I have to say thank you to Carl Tyler for challenging me to stop whining, get off my ass and do something about my career (paraphrasing of course).

I then have to say thank you to Ed Brill (who I am yet to meet) for following me and making me realize the possibility of  social media.

I also have to say thank you to a multitude of people who have accepted me into the community with open arms and have been nothing but supportive, encouraging and have become really good friends – to name but a few:  Paul, Russ, Dave, Bruce, Declan, Mike, Jesse, Mark , Mark, Mark, Thimo, John, John, Paul, Paul, Roy, Thomas, Tim, Nathan, Jeff, Colin, Andrew, Imran, Wil, Steve, Brad, Per, Niklas, Ryan, Martin, Graham, Toby, Devin, Frank, Kathy, Troy, Serdar and everyone else I have not listed and clearly offended by forgetting.

 

Thank you – every single one of you. I am presenting at IBM Connect next month – WOW !

 

jQuery in XPages #17 – nanoScroller (game changing – mini scrollbar)

In this article I will describe how to implement and use the nanoScroller jQuery plugin to create discrete, feature full scroll bars within your XPages applications.

Demonstration

The XPages integration of nanoScroller.js is demonstrated here

As the short video demonstrates below – with 5 lines of code you can turn an ugly scrollbar in the middle of the page to a modern looking scrolling capability which is certain to impress clients.

Music: In Flames – Where The Dead Ships Dwell (The Qemists Remix)

Download

The demonstration database can be downloaded from the link above or from here

nanoScroller.js

Introduction

“nanoScroller.js is a jQuery plugin that offers a simplistic way of implementing Mac OS X Lion-styled scrollbars for your website. It uses minimal HTML markup being .nano > .content. The other scrollbar div elements .pane > .slider are added during run time to prevent clutter in templating. The latest version utilizes native scrolling and works with the iPad, iPhone, and some Android Tablets.”

As you can see from the picture below – the nanoScroller allows for a discrete, easy to style/configure scrollbar to be added to a panel within your XPages.

For my personal development, finding this is a game changer – seriously that important – having a normal scrollbar in the middle of the screen is always undesirable and confusing to a user – this is AWESOME !

nanoScroller applied to an XPages viewPanel
nanoScroller applied to an XPages viewPanel

How Does it work?

We add the jQuery library and the nanoScroller.js library file(s) to the database by adding them to the Web-Contents folder accessible via the package explorer.  (Window–>Show Eclipse Views–>Package Explorer) and drag and drop the two libraries from your computer into the “js” folder.

We add the libraries to our XPages like this in the source panel

	<link rel="stylesheet" href="css/nanoscroller/nanoscroller.css"></link>
	<link rel="stylesheet" href="css/nanoscroller/main.css"></link>
	<link rel="stylesheet" href="css/nanoscroller/style.css"></link>

	<script src="js/nanoScroller/jquery.nanoscroller.min.js"></script>
	<script src="js/nanoScroller/jquery.js"></script>
	<script src="js/nanoScroller/overthrow.min.js"></script>

I have to admit that I had some issues implementing the examples myself – so I copied and pasted the example from the nanoScroller demonstration page and then started hacking out the pieces I didn’t need down to the basic shell.

<div id="main">
    <div class="nano">
      <div class="overthrow content description">
            YOUR CODE HERE
      </div>
    </div>
</div>

I then inserted my ViewPanel right int he middle there – nothing more complicated that that.

The basic nanoScroller capability is then created using the following code on the XPages source panel

	$(function(){
	  $('.nano').nanoScroller({
	    preventPageScrolling: true
	  });
	});

Note: for those of you wondering what $(function(){ is…it is just an anonymous JavaScript function same as this….

	  $('.nano').nanoScroller({
	    preventPageScrolling: true
	  });

Except that because it is wrapped in a function it makes it anonymous – frankly IMHO unless you are writing your whole application in JavaScript then who cares – but some very influential people in the JavaScript world do 🙂 Check this video out for a great explanation of why you should use these in Javascript development Paul Irish’s 10 things I learned from the jQuery source

Extra Cool functionality

As you can glean from the documentation nanoScroller has multiple events/properties which you have access to which make this even more of a slam dunk when it comes to replacing the way you have used scrollbars before. Here are two examples:

scrollend

  $(".nano").bind("scrollend", function(e){
    alert('You have reached the end');
    $("[id$='button1']").css('display', 'block')
  });

A simple Use Case for Binding the scrollend event would be when you have some Terms of Service and you wanted to make sure that the user had scrolled to the end of the agreement before they click the “I Accept” option. In the example I just use an alert and used it to make visible the accept button.

iOSNativeScrolling

Enabling this option allows for the iOS5+ native scrollbar on your iPad (for example) to be displayed.

And there are many more – check out the documentation and excellent examples!!

Conclusion

As I said before and hopefully my enthusiasm shows in this article – this really is a game changer for me – sure the example styles need to be played with to fit your OneUI style sheet but that is not hard. The overall effect is so much more pleasing on the eye, takes up less space on the page and significantly improves the overall user experience.

There aren’t any plugins which I use in *every* project – but this may well become the first !

jQuery in Xpages #16 – Avgrund (dialog depth perception)

In this article I will describe how to implement and use the Avgrund modal dialog which uses CSS transitions to give the effect of depth between the dialog and the page.

It is hard to believe that it has been two months since the last jQuery in XPages article – and for that I apologize. My current project requires most of my time to be away from the XPages DDE and as such the opportunity to find new and exciting plugins is decreased. But I came across this one today and figured I would take the time to write it up.

Demonstration

The XPages integration of avgrund.js is demonstrated here

Download

The demonstration database can be downloaded from the link above or from here

Avgrund.js

Introduction

Avgrund is a very simple 2k jQuery plugin which uses a CSS transition to shrink the visible page while displaying a modal dialog to the user. This gives the perception of depth between the page and dialog and a neat visual transition between the two. The plugin also uses IE alpha filters to fail back for IE<10 browsers which do not have CSS transition support (nice touch).

Avgrund dialog
Avgrund dialog

How does it work

We add the jQuery library and the avgrund.js library file to the database by adding them to the Web-Contents folder accessible via the package explorer.  (Window–>Show Eclipse Views–>Package Explorer) and drag and drop the two libraries from your computer into the “js” folder.

We add the libraries to our XPages like this in the source panel – the avgrund.js also comes with two sample CSS files for the demonstration.

	<script type="text/javascript" src="/xomino/jQinX.nsf/jquery-1.7.1.min.js"></script>
	<link rel="stylesheet" href="avgrund/style/style.css"></link>
	<link rel="stylesheet" href="avgrund/style/avgrund.css"></link>
	<script src="avgrund/js/jquery.avgrund.js"></script>

The plugin itself is very simple to instantiate and use, and the properties are self explanatory and well explained in the demo file:

	$('element').avgrund({
		width: 380, // max is 640px
		height: 280, // max is 350px
		showClose: false, // switch to 'true' for enabling close button
		showCloseText: '', // type your text for close button
		holderClass: '', // lets you name custom class for popin holder..
		overlayClass: '', // ..and overlay block
		enableStackAnimation: false, // another animation type
		onBlurContainer: '', // enables blur filter for specified block
		template: 'Your content goes here..'
	});

The CSS transition is contained within the avgrund.css file and amongst other things scales the page to 0.9 of it’s size when active. A blur effect is also applied for greater visual effect.

body.avgrund-active {
	-webkit-transform: scale(0.9);
	-moz-transform: scale(0.9);
	-ms-transform: scale(0.9);
	-o-transform: scale(0.9);
	transform: scale(0.9);
 /* overflow: hidden;  TIP: disables scrolling for long documents */
}
.avgrund-active .avgrund-blur {
	-webkit-filter: blur(1px);
	-moz-filter: blur(1px);
	-ms-filter: blur(1px);
	-o-filter: blur(1px);
	filter: blur(1px);
}

In this case the element in question is the Show button.

Demonstration

The XPages integration of avgrund.js is demonstrated here

 

Community Blogging and why you shouldn’t give a &^%$ what anyone thinks

Background

I have a Ph.D in Chemistry (yay me…). I spent 3 years making many previously undiscovered compounds and characterized them! What I created and the papers I published were no use to anyone as far as I knew at the time – but in the future if someone else who I will never know needs to create a chemical with specific properties, my papers are out there and will help. In the same way that my research depended on those who came before me – my research will help those who come after me. It was the purest form of research. There was no company sponsoring it, needing results to justify their investment. It was funded by a purpose and a desire to further knowledge – which is what I did………That mindset is how I approach blogging.

Community Blogging – why?

Why do people blog? There are many reasons…..and you know people who fit these categories:

  1. Egotistical desire to let everyone else know how awesome they are
  2. People who are insecure and need a voice……
  3. People who are naturally sharing individuals who truly care about increasing the communal knowledge
  4. People who are trying to get ahead and make themselves stand out in a tight job market
  5. People who are all of the above in some way shape or form depending on day/mood/alcohol or caffeine intake

This post is aimed at the staggering amount of Notes/Domino people who are doing really cool &^%$ every day and want to share but have way to many inhibitions to do so. “Noone cares”, “I can’t write”, “I would be wasting my time” – whatever!

Don’t be selfish – you learned from others after all….

Don’t be so selfish and keep everything to yourself………after all you are reading this and you know the benefit of learning from others – give something back once in a while. Call be a raving socialist but I believe that we as a whole community can be better as a whole when everyone shares their knowledge. You learned from others and took their ideas and modified them to make it your own………….

I think (as the title suggests) you need to understand is that it doesn’t matter what anyone else thinks about your blogging – it is all about what you think and more importantly about what you do to share it.

Even if it is as simple as – I came across this cool idea the other day but I don’t know what to do with it, people will read it, people will contribute, people will benefit and people will make you better.

Blogging is easy

WordPress is free – takes 5 minutes to set up
PlanetLotus.org – takes a few minutes and an email to get registered – if you need help buzz me – marky @ thiswebsite.com

To all those people who have thought about it and wondered who cares? Stop giving a crap about who cares and start sharing………

  • Find a topic which interests YOU (for me jQuery and User Experience)
  • Write about it (Just like I tell my kids – the more you write, the better writer you will be)
  • Don’t stress – you are not going to get criticized about how you write
  • Do it (as the slogan goes)

Why my blog?

My blog is purposefully not full of business speak – I can do business speak but I think it is harder to read as a community blog. I started this blog for two reasons:

  1. It  forced me to learn XPages which is something I felt I needed to do to get ahead
  2. I wanted it to help me get ahead! and it worked! – not because it made me any smarter, but it made more people aware of my skillset.

I don’t care if people read the blog or not (liar) and I more importantly want to give back to a community which I have been taking from for over 10 years and anything I can do to help another developer is time well spent.

There is no bigger rush than knowing that something you wrote about helped someone else – try it, you’ll be surprised!

Don’t worry about what other people think……..

If you want a voice but don’t want to manage a blog, let me know and I will help you publish.
If you have a voice – use it.

Stop giving a &^%$ what people think about what you say – you’ll be surprised how appreciative they are that you took the time to do something for them !

 

Do it !

How to always show OneUI action buttons with a simple CSS trick

In this article I will show how your ExtLib Application Layout Control action buttons (OneUI) can remain on the page at all times with a simple CSS Trick.

The following was created using the Extension Library Application Layout control – with OneUI v2.1 using the silver theme.

Introduction

OneUI is a great, simple layout for a nice clean application layout without too much worry about CSS and other complicated design things. There are some nice examples on the OpenNTF site about using the OneUI layout. The http://xpages.info/XPagesHome.nsf/Home.xsp website uses the same layout and you can see for yourself how the top bars scroll out of the screen as you move down the page.

The buttons in the PlaceBar stay put as the page scrolls down – as the page gets larger this becomes more of a pain for the user to have to scroll back to the top to get to the Save button.

The desired effect

My requirement in modernizing my current R5 web based application was to keep the look and feel as close to the original frameset as possible. The buttons were in the top frame and therefore visible on the page at all times. Without wanting to revert back 15 years and use frames in the XPage I had to come up with a way to keep the buttons on the page at all times.

The initial look

The initial buttons look like this in the placebar – nothing spectacular to see here

Save and Cancel button
Save and Cancel button

 

Using what else – FireBug 

So I had to figure out first of all what the CSS was for the buttons and then if I could change them. Looking at the HTML in FireBug you can see that the buttons are in a DIV with two classes: .lotusPlaceBar and .lotusBtnContainer

Looking at the OneUI buttons in FireBug
Looking at the OneUI buttons in FireBug

 

Fixing the position

Fixing the position of the buttons is as simple as using “position: fixed” and then they stay in that place on the screen. I added some other styling to pad it a little, and move at away from the side of the screen like this

Fixing the button position
Fixing the button position

This is achieved by adding the following style to the XPage

		.lotusPlaceBar .lotusBtnContainer {
		    background: url("/xsp/.ibmxspres/dojoroot-1.6.1/dijit/themes/claro/images/titlebar.png") repeat scroll 0 0 #EEEEEE;
		    border: 1px solid #CCCCCC;
		    float: right;
		    padding-bottom: 0.3em;
		    padding-right: 0.3em;
		    padding-top: 0.3em;
		    position: fixed;
		    right: 20px;
		    z-index: 99999;
		}

There we have it – fixed buttons on the page

As you can see from the picture below – the buttons stay in exactly the same place on the screen as the user scrolls down the page

Buttons fixed in place
Buttons fixed in place

All the way to the bottom of the screen

All the way to the bottom
All the way to the bottom

Why XPages should get Web Sockets

Web Sockets

Web Sockets is not “new” but it is, in the sense that it is an HTML5 standard which is not implemented yet in all browsers. For more information check out this excellent article on it. Written two years ago !!! And yet many people have not yet heard of it.

http://www.html5rocks.com/en/tutorials/websockets/basics/

So what’s the big deal? We have web polling right now….

In a nutshell Web Sockets allows for an open connection to be maintained between the server and the client. Que? So what? I hear you say…

If you think about your twitter feed, facebook update feed or your Social information stream in Connections or Notes Social, the way it works is via a one way “polling” from the browser to the server – the conversation looks something like this via an ajax request

Browser: “Do I have anything new?”
Server: “Nope”
5 seconds goes by
Browser: “Do I have anything new?”
Server: “Nope”
5 seconds goes by
Browser: “Do I have anything new?”
Server: “Nope”
5 seconds goes by
Browser: “Do I have anything new?”
Server: “Nope”
5 seconds goes by
Browser: “Do I have anything new?”
Server: “Yes here is a new message”

What this does is create a huge amount of unnecessary bandwidth on the network – and just as importantly requires the server to maintain a ton of open threads at all times to allow for the constant polling – slowing down the server – all in it is a very expensive (but necessary) methods for getting “real-time updates” to the browser client. It also it (in shall we say less sophisticated browsers) causes a RAM increase and memory leaks – over time resulting in browser failure.

All change with Web Sockers

Web Sockets allows for an open connection – just as if your computer is on the LAN – traffic can flow both ways.

So there is no longer a need for “polling” in the same fashion.

Use Case example

If I had Web Sockets this would be the first demonstration I would do. it is directly applicable to our work environment and would :

User A

Creates an expense claim request and submits it to User B for approval.

On the server we are running a scheduled agent (or equivalent) which picks up the approval is required

User B

Logged into the intranet 3 hours ago and has not been into the expense system once.

Because she is logged into the system the supervisor has an open Web Sockets connection to the server.
The server “pushes” the new approval request to the supervisor’s browser without the need for polling and it pops up in her “stream” as a task which requires her action.

One HTTP transaction instead of many.

Other examples

Other tangible examples are :

  • Real time charting – updating your corporate stock ticker, but only when a change is necessary
  • A sidebar chat capability, changes pushed not polled
  • Web conferencing (with HTML5 audio and video tools)
  • Online games

Here’s what Jesse Gallagher told me: Having a “direct feed” between the client and backing objects on the server could lead to all sorts of interesting applications, even better than the remote services in the ExtLib

Conclusion

Web Sockets is a new technology, now supported in IE10 and will provide multiple advantages to the corporate infrastructure:

  1. Significantly reduced Web based LAN traffic due to the removal of “polling” from the browser
  2. Faster servers requiring less resources due to to the reduced traffic requests
  3. It will save money and resources
  4. It will provide for a faster browser – improving user experience.

#BringWebSocketsToXPages

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 🙂