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 🙂

Dealing with Dates, and localization in XPages

In this article I will discuss and demonstrate how to deal with dates in a localized application. We will look at the dojo.locale() library and  discuss how localization affects dates in XPages.

Background

Dates in JavaScript – nasty horrible things, to be avoided at all costs. So much so that there are a number of date handling specific libraries including moment.js and date.js. In addition to these two Dojo has it’s own built in date parsing library and that can also be utilized with multiple languages (localization) and the jQueryUI datepicker functionality also allows for date formatting. So we have a number of options depending on how we want to utilize the available resources.

Localization

Localization is the fancy term for making your application multilingual. For a more in depth look at how to do that at the application level check out http://www-10.lotus.com/ldd/ddwiki.nsf/dx/XPageLocaleTimezone.htm or go see Brad and Kathy at this year’s connect14.

When you turn localization on within your XPages application (R9 – Application properties / Design /International Options) the server generates a dojoConfig.locale variable at the top of your XPages webpage.

date1

This gives us programmatic access to the language at anytime.

For those interested the actual language is passed to the server through the header information when requesting the page. In this case I am telling the server that I was one of three languages (should the application support them)

  1. en, en-us (american english)
  2. fr (french)
  3. de (german)

date2

Within the XPages international options I can specify the languages – and the server will send out the first language supported by the application which coincides with what the browser is asking for.

So if the application supports french, dutch and german – I will get a french page served to me because that comes before german in my list of languages.

Most Americans who have never had to deal with this are thinking – who cares everyone uses mm/dd/yyyy right??? And they would be wrong. Almost nobody else deals with mm/dd/yyyy and if you manually validate mm/dd/yyyy for an international application you will fail in other countries.

Dojo

In XPages we get dojo out of the box and with that we get date formatting functions. The dojo/date/locale() “Creates a string from a Date object using a known localized pattern.“. It is really rather nice and simple and as you can see from the documentation page there are *many* different formats in which you can return the date.

I needed to display the day of the week, month, day number and year at the top of a page, so I created my own date translation function in the code as follows. What this function does is that it accepts a date object and a pattern. The function then returns a string based on the pattern.

require(["dojo/date/locale"])

function formatLocaleDate(date, pattern){
	//example formatLocaleDate(date, "EEE MMM d yyyy")
	return dojo.date.locale.format(
		    date,
		    {
		    	selector: 'date',
		    	formatLength: "short",
		    	locale: dojoConfig.locale,
		    	datePattern: pattern
		    }
		)
};

So in this case the example given would return

“lun jan 13 2014” in french
“mon jan 13 2014” in english

But this still does not determine if mm/dd/yyyy is a valid format in your date field.

Here is the simple date test for that.

If you try the following and dojoConfig.locale = ‘en-us’ you will not pass. But in ‘fr’ you will get a date object.

var temp = dojo.date.locale.parse('20/12/2013',
    {
    locale: dojoConfig.locale,
    formatLength: "short",
    selector: "date"
  })

if(temp){
    console.log('pass')
}

The REST service
A rest service date field comes along in ISO format

[
  {
      "@entryid":"1-AE3FB4C32057B87C85257C22000A83DD",
      "firstname":"Alfred",
      "lastname":"Hall",
      "address":"2139 Jail Drive",
      "state":"IL",
      "city":"Tremont",
      "noteid":"NT0000BD22",
      "lastMod":"2013-12-20T06:00Z" //ISO date format
  },

and because of that it is language independent (smart that). So if we want to turn that into something appropriate for the french (dd/mm/yyyy) or american (mm/dd/yyyy) we have to use the dojo locale library.

var temp = new Date('2013-12-20T06:00Z')
temp = dojo.date.locale.format(temp,{
    selector: "date",
    formatLength: "short"
  });

In American English we get : “12/20/2013”
In french we get : “20/12/2013”

In this way we get the correct formatting without having to write code in each language.

Conclusion

How ever you are dealing with date formatting, date validation or REST service JSON data (in my case in Ext JS) there are dojo date formatting functions available for free on the server. If you need localization then even better because you life is may significantly simpler than it would otherwise be.

PS 

Before anyone starts to have a go about ooo Marky used Dojo….?!?! Yeah I did, because it made sense to meet the requirement. Would I use Dojo to meet this requirement in a non-XPages application? Probably not 🙂

Remove all classes using dojo and jQuery

One of last week’s challenges on the side was to take this Connections wiki page and make it readable on a small screen – if you drag the right hand side over to the left you will see that the right navigation menu overlays the non-wrapping text. The main section is forced to a 980px width !

http://www-10.lotus.com/ldd/lcwiki.nsf/dx/Best_Practices__Troubleshooting_Lotus_Connections_3.0#Traces

A very brute force approach to this is to remove all the classes from all the elements on the page

In jQuery you would do this:

$('*').removeClass()

in dojo (which the page is written in) it takes slightly longer

dojo.forEach(dojo.query('*'), function(item, i){
    item.className=""
})

It would be relatively simple to turn this into a bookmarklet to run for yourself

Here is a bookmarklet you can add to do it for you – this will also work on other IBM wiki pages

Create any link on your bookmark bar and then edit it. Copy and paste the following as your URL

javascript: dojo.forEach(dojo.query(‘*’), function(item, i){ item.className=”; })

b1

When you go to the wiki page click the bookmarklet and all classes will be removed – this is only work on pages which have dojo on them already (which IBM documentation does).

Decoupling your CSS from your JavaScript, a “well no duh” moment

This weekend I had one of those “oh DUH” moments which I have been struggling with for quite some time. How can I better structure my jQuery selectors and make the code more maintainable? I came across this excellent article – Decoupling your HTML CSS and JavaScript and it all came into focus.

The problem

Using JavaScript selectors (dojo or jQuery) in XPages can be a problem because of the id naming scheme used by the JSP generator “id=”view:_id1:_id2:link5” and how this falls over in a selector. So an alternate to not having to mess with is attributes is to use class selectors $(‘.class’) which is actually much simpler and less troubling to get your head around.

When you are using class selectors for a DOM element which already has a class then awesome I don’t have to add any more classes. Using this bootstrap example there are multiple classes I can get a hold of to manipulate the dialog contents.

 <div class="modal fade myModal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
			<button type="button" class="close modal-maxmin" aria-hidden="true">
				<i class="icon-external-link"> </i>
			</button>
			<button type="button" data-dismiss="modal" class="close" aria-hidden="true">
				<i class="icon-remove"> </i>
			</button>
          <h4 class="modal-title">modal-title</h4>
        </div>
        <div class="modal-body">
         modal-body : HERE GOES THE MESSAGE
        </div>
        <div class="modal-footer">
	        <div class="btn-group">
	          <button type="button" class="btn btn-default modal-cancel" data-dismiss="modal">CANCEL</button>
	          <button type="button" class="btn btn-primary modal-ok">OK</button>
	        </div>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->

To add something to the body of the dialog I would do something like this

  $(".modal-body").html('Hi Marky')

The other problem

This example is very “coupled” code whereby my JavaScript selector is coupled to the real class file used by the HTML code. In reality what it means is that if I have to change the classname for some reason (hmm an example – oh I don’t know – going from Bootstrap2 to Bootstrap3 for example) then my JavaScript breaks down. While tightly coupled code is easy to follow, easy to create initially, it can be an absolute nightmare in the long run.

The epiphany moment

As I am reading Philip Walton’s article  I am struck by the “oh well no duh” moment when he talks about using js-* as a naming convention for classes which only exist for JavaScript selection.

  • My personal recommendation is to use a prefix for all JavaScript hooks. I use js-*. That way, when a developer sees such a class in the HTML source, she’ll know exactly where to look to discover its purpose.

Well no duh – brilliant idea!

In all senses this makes perfect sense:

  • The developer does not have to search through CSS files looking to see if you used the class as a selector as a real CSS marker
    • (well ok they changed something and the CSS broke, then they started to look for it)
  • It is immediately apparent from looking at the HTML that there is some dojo or jQuery selection/manipulation going to go on in this area because of the js-* class naming scheme
  • Within eclipse you can do a quick search and find out what is trying to manipulate this area before you go and ruin it

The new code

A very simple change to the modal-body but this then decouples my code form the bootstrap code – allowing me to make changes to the bootstrap classes int he future without breaking my JavaScript

 <div class="modal fade myModal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
			<button type="button" class="close modal-maxmin" aria-hidden="true">
				<i class="icon-external-link"> </i>
			</button>
			<button type="button" data-dismiss="modal" class="close" aria-hidden="true">
				<i class="icon-remove"> </i>
			</button>
          <h4 class="modal-title">modal-title</h4>
        </div>
        <div class="modal-body js-modal-body"> <!-- js-modal-body change here -->
         modal-body : HERE GOES THE MESSAGE
        </div>
        <div class="modal-footer">
	        <div class="btn-group">
	          <button type="button" class="btn btn-default modal-cancel" data-dismiss="modal">CANCEL</button>
	          <button type="button" class="btn btn-primary modal-ok">OK</button>
	        </div>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->

To add something to the body of the dialog I would now select the js-* class not the modal-body itself

  $(".js-modal-body").html('Hi Marky')

Comment

One of the things I love about my career is that it is an “always learning” experience for me. There are times like this where you think to yourself that is an awesome idea and you are very happy to learn it – and at the same time feel so stupid that you didn’t think of it yourself before 🙂

XPages ND9 (Dojo 1.8) does not work with other AMD loaders (and the work around)

Today I took a new jQuery plugin that I was playing with from an R8.5.3 environment where it worked, to an R9 environment and it failed – I figured it had something to do with something I had been reading about over the last month and in fixing my problem this lead to a more serious realization that I KNOW other people are also going to come across.

Background

A brief scan of the last month’s discussions on Xpages and jQuery Mobile 1.3 reveals a number of posts started by Dave Leedy regarding the use of IBM Notes Domino 9 and jQuery Mobile 1.3

http://notesin9.com/index.php/2013/04/20/jquery-mobile-seems-incompatible-with-xpages-in-domino-9-0

http://hasselba.ch/blog/?p=1216

http://stackoverflow.com/questions/16058039/jquery-mobile-in-xpages-passing-parameters

http://www.eknori.de/2013-04-21/followup-jquery-mobile-seems-incompatible-with-xpages-in-domino-9-0/

What’s going on?

I saw the following Tip from Sven Hasselbach (very smart man!) on Dave Leedy’s blog post

Looks like an AMD loader problem with Dojo & JQM. I have tried out to disable the Factory scan in a test page and this worked for me. To do this I have added the following parameters in the xsp.properties:

xsp.client.script.dojo.djConfig=dojo-amd-factory-scan: false

Maybe this can help you with your problems in ND9.

This lead me to this bug report

https://bugs.dojotoolkit.org/ticket/15616

make dojo work with other AMD loaders

Which then lead me to the realization that this is a bigger issue than just JQM 1.3 and I solved my problem and here is how.

Solution (ND9)

Within the Package Explorer  (Window—open perspective –> xpages) in the WebContent folder for your database you will find the xsp.properties file (as described http://heidloff.net/home.nsf/dx/06172011015521AMNHE8Y7.htm)

xsp1

Click to open the Source Tab

and enter the following

xsp.client.script.dojo.djConfig=dojo-amd-factory-scan: false

And Save – that’s it

Result

If you look at the source code of the created XPage you will see that the new parameter has been added to the script tab creating the dojo.js as a djConfig property

xsp3

doing a quick search explains what this property does

http://dojotoolkit.org/documentation/tutorials/1.8/dojo_config/

“For example, we could disable the amd factory scan (scanning the module for CommonJS require(module) statements to load as deps) with…”

Not only does that solve the problem with jQuery Mobile, it also solved my problem with the jQuery Table plugin which I wanted to use, which used require.js to load the jQuery dataTable plugin.

GENIUS

thank you Sven Hasselbach (again!)

How to tell if your web application has been modified in 4 lines of code

In this article I will demonstrate a simple but effective way to determine if something has changed on your webpage. I will use the MD5 hashing library available in dojo and compares the hash at the start of the process and at the end – if it has changed – something has changed.

Acknowledgements
I have to acknowledge Alex Skinner and Jason Lavoie who first showed me this method many years ago on a .NET project and Troy Reimer who was the Über smart genius to take the idea and apply it so eloquently to XPages using dojo cryptographic libraries. Thanks guys 🙂

Introduction

It has been an age old issue with web form development – how do I know if the user has changed anything?

We could track the start and end value of every field – doable but laborious. Also comes to a stumbling block with you have user interactions which are not field based – like dragging and dropping an employee from one manager box to another.

We could use the XSP._isDirty() function which is provided for us in XPages but that does not apply in all situations and this example will work with any webpage (assuming dojo is loaded)

MD5 Hash

Partially because of my lack of understanding but entirely because of its lack of relevance to this solution I am not going to go into how MD5 hashing works but to suffice to say: – an MD5 hash is an iterative encryption algorithm which can reduce a string of any length down to a fixed length (in our case 16 characters).

Dojo Cryptography libraries

Dojo provides various cryptographic algorithms and you can find out more about them here

http://dojotoolkit.org/reference-guide/1.6/dojox/encoding/crypto.html

In our case we are going to use the MD5 library and we add it to our XPage in the following manner:

	dojo.require("dojox.encoding.digests.MD5");

What needs to be checked?

Well it just so happens (if you hadn’t noticed) that HTML is basically a long text string. So what we are going to do is to put a panel around the form fields we are trying to test again.

<xp:panel styleClass="myPanel">
	web form stuff here
</xp:panel>

And then once the page is loaded we are going to create the MD5 Hash of the HTML within that panel like this.

var oDocHash = oDocHash= dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML);
console.log(oDocHash)

We can then either stick the hash in a cookie – or in a field on the form – or in this case in a windows variable.
(Before the JavaScript purists start to have a go – I know, I know don’t use the windows object to store variables – tough – I said 4 lines of code, didn’t I) 😉

So then the overall code to create the hash looks like this:

dojo.require("dojox.encoding.digests.MD5");
window.docHash = dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML);

The checking

When you are ready – or the user is not ready to check if anything has changed all we have to do is re-hash and then compare the variables, like this

hasChanged = (window.docHash != dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML))? "This form has changed" : ""
if (hasChanged){alert(hasChanged)}

The overall Code sample

//Load the necessary dojo Crypto Library
dojo.require("dojox.encoding.digests.MD5");

//Get a hash of the innerHTML of the element with the .myPanel class
//Run this when the page is loaded
window.docHash = dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML);
console.log("Stored hash: "+window.docHash)

//determine if a change has been made
//run this when the page is ready to be saved or navigated away from
hasChanged = (window.docHash != dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML))? "This form has changed" : ""
console.log("New hash: "+dojox.encoding.digests.MD5(dojo.query('.myPanel')[0].innerHTML))

//panic panic
if (hasChanged){alert(hasChanged)}

The demonstration

As you can see from the video below we are starting out with a simple XPage – not in Edit mode – I have also added some console logs to the code so that you can see what is going on. I use firebug to alter the HTML – and the hashes do not match. For the icing on the cake though if I put the HTML back to be exactly what it was before we started then the hashes match.

Conclusion

And there you have it – it is simple to implement and you don’t need to understand how the cryptography works to use it. Generally better than way I find because trying to understand cryptography usually causes headaches and nose bleeds.

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>

Dojo Firebug Extension – from an XPage developer’s perspective

In this article I take a rather irreverent look at, and describe some what I was hoping would be, the useful capabilities of the dojo firebug extension available at https://addons.mozilla.org/en-US/firefox/addon/dojofirebugextension/

Introduction

I love firebug for my client side JavaScript development – for many reasons too numerous to mention here. If you have no idea what firebug is then you should google it and find out – USE IT and you will never go back…..

So what’s this Dojo extension all about then ?

Right off the bat I loved finding this quote “The Dojo Firebug Extension started as an internal IBM initiative to help IBMers working with Dojo.”, and more importantly got me straight off on the thought of what can this do for me in my XPages?

The documentation is available here – https://getfirebug.com/wiki/index.php/DojoFirebugExtension_Reference_Guide and as firebug extensions go – this one is fairly well documented – nice job 🙂

You have to download a different version based on your firebug and your firefox version….that’s kinda weird and disconcerting and they don’t have my version of firebug or firefox – but hey we truck on in hope.

So What does it do for me as an XPages developer?

Good question – let’s find out…

Well the first thing it showed me was how MASSIVELY complicated the Dojo integration with XPages is……check out some of these idTags on this Tab Container!! 😮

Dojo Firebug extension in action
Dojo Firebug extension in action

 

Open API documentation

This *could be* really useful – if you can get over how useless the API documentation site is – let me paraphrase…….IF you understand how the Dojo API documentation works this *could be* fantastically helpful…..

In my previous article on how I figured out how to use the Dojo Tab Container doLayout (where the screenshots come from) I was struggling to find out what I needed to make the Tab Panel heights dynamic. Would this have helped?….I was kinda bitter at this point as I figured it would have….so i soldiered on..

Select the tab container and look at the extension

Selecting open API documentation
Selecting open API documentation

 

and opening the API documentation

Dojo API documentation
Dojo API documentation

 

*yawns* – so not really – but stay with me

The next options *looks* more useful (so why did you show us the API link? Yes you guessed it…… it *is* ‘cos I hate you and I wanted to force you to look at Dojo API documentation – get over it and don’t ask daft questions)

Open Reference Guide Doc

Open Reference Guide Doc
Open Reference Guide Doc

 

Which shows you this…….

Dojo Reference Guide Documentation
Dojo Reference Guide Documentation

 

First of all I am really impressed that this actually links to the 1.8 version which was only released this week – but that is also not helpful because XPages 8.5.(What I am using) uses 1.6 so which a quite switch over on the right hand side

Switching to 1.6
Switching to 1.6

We get…

Aw Butts - really?/?
Aw Butts – really?/?

And I was just saying how awesome you guys were – CRAP.

As it turns out the plugin is too smart and not smart enough to detect 1) the version of dojo I am using and 2) that this feature it thinks I am using is available in 1.6…

DOH
DOH

DOH *grrr*

Que?

So I didn’t solve that problem but I did find another one – I noticed that IBM modified the Dojo specifically for the extlib!! …if you look at the code reference in the extension

Well that is kinda interesting I guess..
Well that is kinda interesting I guess..

[view:_id1:_id2:_id39:djTabContainer1 (Widget extlib.dijit.TabContainer)]

and when we select to go to the Reference Guide Docs – the URL it is sent to

http://dojotoolkit.org/reference-guide/1.8/extlib/dijit/TabContainer.html

You will see that extlib has been inserted into the URL

the REAL documentation is here

http://dojotoolkit.org/reference-guide/1.8/dijit/layout/TabContainer.html

dijit/layout and not extlib/digit.

If you look at an example from david walsh’s blog you can see the difference…

vive la difference
vive la difference

 

Anything else?

Well I found out how to manage FireFox profiles – http://www.howtogeek.com/howto/internet/firefox/use-multiple-firefox-profiles-at-the-same-time/ which is kinda useful – so I did learn something useful from this investigation.

There are a number of cool Dojo debugging capabilities if you are really into writing seriously with the dijits whereby you can subscribe to the data and watch it move all over the place – kinda cool – not helpful for XPage development though.

So is this really useful for an XPages developer?

Well I have to say from an purely educational perspective it is really interesting to get an insight into how the dijits work…

Some really complex cool stuff going on  in here
Some really complex cool stuff going on in here

 

But I think my overall impression of the extension is that it will not help an XPage developer develop their XPages at all in any sort of way

Shame really 😦

PS

Let me rephrase that last sentiment – I think this COULD be really useful if IBM were inclined to apply some time and effort to making a similar extension for XPages Dojo development – but isn’t the point of XPages is kinda so we don’t have to worry about Dojo…so it would be an uber-dojo-geek expert XPages developer tool only…meh…who wants to do that?? 😉

Shame really 😦

PPS

That is two blog articles in a row about dojo – don’t worry I am not going back to the dark side – jQuery still rocks my world 😉