Ext JS Connect 14

This post is in support of the presentation I gave at IBM Connect 2014 – 28th January 2014

To find the demonstrations:

http://demo.xomino.com/xomino/extjs.nsf

To find the Ext JS 4.2 examples

http://docs.sencha.com/extjs/4.2.0/extjs-build/examples/

To find the slide presentation from Connect

http://www.slideshare.net/MarkRoden/presentations

I hope everyone that attended enjoyed the presentation – please feel free to ask questions and / or hit me up on twitter @MarkyRoden

Advertisements

Going porn-mode on your browser

Simple tip to remember when testing your website changes – porn mode

Privacy

Well ok “porn mode” is kinda funny and I am sure has nefarious uses – but there is actually a really good one from a developer’s perspective.

Incognito (Chrome) or Private (Netscape) or InPrivate(IE) mode forces the browser to not use the cache and/or history and stores nothing about your browsing session (hence porn-mode for the cynical)

But what it does for me as a developer is that it forces an empty cache – without me actually having to empty my cache. An empty cache all the time is not really beneficial for a developer and or normal user because there are obvious speed benefits to caching. But when a customer claims the changes you made have not worked – tell them to go porn mode on their browser. Once they understand the issues is caching on their side the conversation changes.

You’ve gone incognito. Pages you view in this window won’t appear in your browser history or search history, and they won’t leave other traces, like cookies, on your computer after you close all open incognito windows. Any files you download or bookmarks you create will be preserved, however. 

Legitimate uses for porn mode

PS
SHIFT-F5 also forces the browser to ignore the cache and reload everything – but that is not as funny 🙂

IBM Connect 14 – My sessions: right now and the future

Last year was a tremendous experience for me speaking at IBM Connect 2013 and I was very flattered and honored to see so many people come out and see what I had to say. This year will be even better. I know there are a lot of clashes going on with the XPages talks this year but here is why I think you should come and see mine. I will show you how to effectively modernize existing notes views into XPages applications and demonstrate a mobile technology which any XPage mobile developer can easily evolve into. The now and the future….maybe 🙂

If you see me in sessions or in the halls – please say hi. Connect is a learning experience for everyone, I want to learn from you as well 🙂

Tuesday Jan 28 – EXTJS in XPages: Modernizing IBM Notes Views Without Sacrificing Functionality – BP203

Dolphin Southern Hemisphere – II

01:30 PM – 02:30 PM

Come and see why I believe Ext JS is a very effective way to modernize a notes view, keeping all the good parts of notes view functionality and adding *so* much more. I will discuss large scale web data management of thousand of documents and how you can effectively manage a great user experience in doing so.

Thursday Jan 30th – IBM Worklight: Going From XPages Mobile to Native Mobile Applications – BP209

Dolphin Southern Hemisphere I

11:15 AM – 12:15 PM

Come and see why John Jardin and I believe that any XPage developer creating mobile applications already has the skillset to immediately start creating native mobile apps with IBM Worklight. We will demonstrate and explain how we created a simple demo of a mobile XPages app to view NAB users and then how we took that to native mobile and added the users seamlessly to a phone contact book and visa versa.

We used less than 100 lines of JavaScript and zero lines of Java – you are ready to start now – come see how !!!

 

 

Polyfill for IE8 and the XPages REST service date format

In my previous post I talked about the date format coming from an XPages REST service – the ISO date format. Well it turns out that IE8 and below do not recognize this date format and will be very upset at you if you try and create a new Date() from it. (It actually return NaN because Dates are really numbers 🙂 )

Example REST data

{
  "@entryid":"21-6CE8F65D7CB43A5185257C06000B8F00",
  "StartDate":"2013-07-01T01:19:19Z",
  "Form":"Position",
  "Title":"Worker"
}

new Date("2013-07-01T01:19:19Z") // NaN in IE8

So I searched the Google-webs and found a polyfill solution which will re-parse the ISO date format back into something all browsers will recognize. This is a necessary evil in my current application but if you do not have to support IE8 then don’t waste to computation.

Add the following code to your JS libraries and use the Date.fromISO() to crate your dates as stated in the original StackOverflow

/*
  http://stackoverflow.com/questions/11020658/javascript-json-date-parse-in-ie7-ie8-returns-nan
  In older browsers, you can write a function that will parse the string for you.
  This one creates a Date.fromISO method- if the browser can natively get the correct date from an ISO string, the native method is used.
  Some browsers got it partly right, but returned the wrong timezone, so just checking for NaN may not do.
  Polyfill:
*/
(function(){
    var D= new Date('2011-06-02T09:34:29+02:00');
    if(!D || +D!== 1307000069000){
        Date.fromISO= function(s){
            var day, tz,
            rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
            p= rx.exec(s) || [];
            if(p[1]){
                day= p[1].split(/\D/);
                for(var i= 0, L= day.length; i<L; i++){
                    day[i]= parseInt(day[i], 10) || 0;
                };
                day[1]-= 1;
                day= new Date(Date.UTC.apply(Date, day));
                if(!day.getDate()) return NaN;
                if(p[5]){
                    tz= (parseInt(p[5], 10)*60);
                    if(p[6]) tz+= parseInt(p[6], 10);
                    if(p[4]== '+') tz*= -1;
                    if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
                }
                return day;
            }
            return NaN;
        }
    }
    else{
        Date.fromISO= function(s){
            return new Date(s);
        }
    }
})()
/* end Polyfill */

  http://stackoverflow.com/questions/11020658/javascript-json-date-parse-in-ie7-ie8-returns-nan

and if you need to use it – vote it up on SO !!

You could almost certainly correct this on the server by creating a custom column in your REST service to re-format the back end document date field and send out whatever format you wanted. If you are working with a JavaScript framework or front-end library I recommend against this because you really want your JSON to contain the correct date object. Especially in a localized application you are setting yourself up for unnecessary risk.

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 🙂

One way to validate that two time ranges don’t overlap in JavaScript

Today’s programming challenge was to validate that two time ranges in the same day were not overlapping.

I had written over 50 lines of JavaScript with if this is before that then if this if after that other one then this – OR – the same in reverse and so on and so on. It was a lot of what seemed unnecessary code – un-elegant was how it felt (if that is a word).

So in the spirit of approaching a problem differently (no bullshit box terms here) I came up with the following solution.

We have time range A: 1AM to 3AM
We have time range B: 3AM to 4AM

or we could have the second range before the first

Range A: 3pm to 5pm
Range B: 1pm to 3pm

and I need to make sure they do not overlap – that is the only requirement

So I figured: if I make an array of every minute representing each time range and compared them, if there is no matches then there is no “overlap”.

So for the first time range I create an array of the minute-in-the-day (e.g. 1:01 am would be 61) from start to finish which looks like this [60, 61, 62, 63, 64] and then create another array of the second range [120, 121, 122, 123 ,124 etc] and do a comparison. If no matches then no overlap.

here is the functions:

function createMinuteArray(date1, date2){
	//this function creates an array of the number of minutes (in the day) between the start and end time
	// e.g.[60, 61, 62, 63]

    var arr = []

    var startMinute=(date1.getHours()*60)+date1.getMinutes()
    var endMinute=(date2.getHours()*60)+date2.getMinutes()

    for (var i=startMinute; i<endMinute; i++){
        arr.push(i)
    }

    return arr
}

function diffArray(arr1, arr2){
	//this function runs a test on all the values in arr1 and checks to see if that value is in arr2
	//if that is the case then there is overlap of the arrays and therefore return true
    for (i=0; i<arr1.length; i++){
        //I used jQuery inArray because I have IE8 requirement and arr1.indexOf is not supported
        if ($.inArray(arr1[i], arr2)>-1){
            //we have a match and therefore an overlap
            return true
        }
    }
    return false

}

and this is how they are called

var mealbreak = createMinuteArray(startTime1, endTime1)
var otherbreak = createMinuteArray(startTime2, endTime2)

//Check to see if any of the minutes in one array overlap with the minutes in the other one
var overlap = diffArray(mealbreak, otherbreak)

From there we can determine if(overlap) then fail validation

This could be used for comparing dates but would really be impractical – because that would be enormous arrays to create and compare.

I posted this as much in the spirit of – hey this is a different way of solving a problem, more so that a recommendation for how you should validate dates and times. Just something different 🙂

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