Fixing the XPages R9 dojo define.amd problem once and for all

Last week I blogged about the fact that select2 v4 used define.amd and because of that dojo screws up the jQuery plugin.

This has been a significant issue – not hard to deal with but comes up all the time for XPages eedevelopers.

In the blog post comments Ferry Kranenburg posted a link to a solution he uses which is also an XSnippet. It is brilliant.

What he does in the XSnippet is:

  1. duplicates define.amd to define._amd
  2. deletes define.amd
  3. loads the AMD enabled jquery plugin (successfully)
  4. duplicates define._amd back to define.amd
  5. deletes define._amd

Rather than post the code here I want you all to go to the XSnippet and get it from there – and vote it up while you are there.

f1

Personally I would prefer not to use <xp:this.resources> or at best use them wisely and you could easily write this without using resources should you so chose.

Big Problem – simple and elegant solution – well done Ferry and thanks for Sharing

Now go vote up his XSnippet !!!

 

Advertisements

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 🙂

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).

Future-proofing yourself.

The other day I got an interesting comment on an old blog post of mine and I felt like it really deserved a separate post in response rather than being lost in the comments. This is a personal assessment of my skills and the need to future proof myself – it is not a sermon – just personal musings which will hopefully inspire.

The Comment

I have copied the comment here for context.

The past several months, I’ve been working on many Notes client applications, but now we’re ready for a big web based application! So, back to jQuery (YAY!) and some dojo (boo!).
Outside of the XPages world, it seems that jQuery is overtaking everyone else. In fact, I heard that the next version of javascript is taking elements of jQuery! I remember there were Mootools, Scriptaculous, Prototype and TONS of others over the years! Just check the stats of how many Stackoverflow questions there have been for various js librairies: http://stackoverflow.com/tags. It’s not even close! So, for the sake of argument, what if dojo shuts down within 3-5 years, and only Xpages are using them. Then what?

From the outside world, it just seems that jQuery is the better long term decision. Any thoughts?

The Answer(s)

So a couple of things to address directly from the comment:

  1. IBM is a significant contributor to Dojo and has been for many years – I think it is unlikely to “shut down”
  2. jQuery may be “the world’s most popular JavaScript library“, but who’s to say it will be that in 3-5 years? In terms of the internet that is a lifetime away.
  3. JavaScript is an evolving language and of course it will take into consideration any techniques and desires that the development community wants/needs. IFRAME, AJAX and parts of the HTML Spec which we take for granted today were invented as IE only tools which make it into the spec (yeah Microsoft was really groundbreaking in some senses)
  4. I do not agree that jQuery is a better long term decision – I think it is a much better “today” decision and probably at least the next couple of years decision – but what is “long term” anyway? 🙂
  5. Learning the fundamentals of JavaScript I believe is the best long term decision and then the actual library becomes much less of a conversation.

So What?

So I really take the original question as one about future-proofing yourself rather than XPages specifically. For those of you who have already taken the plunge to XPages you have already “evolved” your skillset and you have almost certainly learned new skills (like them or not). Really that is what is important is the adaptability of your skillset – not what should I learn today and what should I be ready to learn tomorrow.

So having learned XPages, what is the hardest thing you have had to learn? For me it is all of the server side controls and the JSF component model. It still causes me mental heartache today and probably always will. I am sure it is obvious to anyone who regularly reads my posts, I am much much happier in the user interface, Client Side JavaScript is my thing, it always will be. I am content that that decision will not harm my future work prospects.

Future Proofing Marky

So for me future proofing myself happened the day I realized that I had been “programming JavaScript” for over 10 years but I had not been a “JavaScript developer” for any of it. If these terms are not familiar to you then you are also not a JavaScript developer: closures. object literals, prototypal inheritance, callback functions, IIFE.

So I set out to learn……and jQuery helped me do that. But……..

There are people who believe that jQuery is an unnecessary safety blanket used by people who do not really understand the language. They also believe that jQuery encourages people to be able to program websites using plugins while they understand very little of the underlying concepts. To that I say *crap*. I do not understand how C and C++ work but I use an operating system and developer tools written in those languages – is anyone fussing about not knowing that? I think not.

My point is, that learning jQuery itself will not teach you to be a JavaScript developer – but it most certainly can help.

  1. The code is free and easy to read – the non-minified version is well documented, easy to read and well laid out
  2. There are many blog posts on how does jQuery work (this is the funniest)
  3. You owe it to yourself to better understand web technology. It is not going away. You may as well start using the tools and understand them as you go along.

I am not saying you must learn JavaScript or you will fail as a developer – far from it. But I will challenge anyone who thinks they are a web developer and is not a JavaScript developer then you are fooling yourself.

JavaScript is not only restricted to web development. As we all see in XPages it is also a server side language and in node.js the fastest growing server side technology for web application development.

Conclusion

So for Marky, JavaScript is the obvious choice. It is not Java, it never will be for me, and I am happy with that decision. I am also convinced that my action will determine my fate. I will not wait for fate to tell me what to learn after my job no longer exists.

The conversation shouldn’t be about what is the best library to use for the future but what skillset do you need to be able to adapt. If you build web sites then JavaScript has to be the way to go.

Web technology moves on a <2 year cycle – welcome to the future of constant re-invention of your skillset if you want to remain relevant.

For your own sake, make yourself better and more flexible – you have no one else to blame if you don’t and the worst happens.

For the record

If XPages is no longer in 3 years what will you do? 2.5 years from now will not be the time to figure that out.

I have no evidence or reason to believe XPages will be going away any time soon 🙂

Dojo is a fantastic JavaScript library. It was never designed to make sexy websites, it was created as a framework for application design. XPages is a fantastic example of how to use Dojo to build a framework – well done IBM.

jQuery is not intended to build “websites”. It is intended to help in the development of websites and simplify the developer experience through standardized functions and removal of browser dependencies.

Ember.js, Angular.js, backbone.js and many others are the new, modern “today” libraries for architecting websites. MEAN is the new LAMP stack and if that all means nothing to you – you should at least do yourself the service of some reading.

Sheer coincidence that I saw this from Tim Tripcony today – same deal – different perspective – same conclusion (metaphorically speaking) 🙂

 

 

 

 

 

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.