Datejs / ExtJS Compatibility

842 views
Skip to first unread message

Tim

unread,
Dec 13, 2007, 1:31:15 PM12/13/07
to Datejs - A JavaScript Date Library
Hello,

I am currently putting together a demo / proof of concept page that
has both an Ext.form.DateField component and Datejs. I ran into a
problem. Due to both ExtJS and Datejs extending the Date object, the
Ext.form.DateField control does not work as expected. Specifically,
the prev/next month buttons on the date picker no longer work. If I
remove Datejs, it works as expected.

I was hoping to have a demo ready by Tuesday that would have a
Ext.form.DateField component that would use Datejs to parse the
entered date value on the change event.

I have three questions:
1: Any idea when the Date2 implementation that I've heard about on
this forum will be ready for alpha testing?
2: Any ideas/suggestions for a workaround?
3: In another forum post, I read that you didn't find any major
compatibility issues with ExtJS and Datejs. Did you happen to create a
list of methods that exist in both ExtJS and Datejs? If so, would you
mind posting this? It would save me some time in creating a
workaround.

Thanks,
Tim

Geoffrey McGill

unread,
Dec 14, 2007, 7:38:03 AM12/14/07
to dat...@googlegroups.com
Hi Time,

Integrating Datejs into the Ext.DateField/DatePicker is a fairly
straight forward process, although there is one conflict between the
libraries which causes most of the problems you're experiencing.

Both Datejs and the Ext Date library include a .add() function, although
the libraries take a very different approach in how they treat the
instance of the date object.

The first (of two) and most obvious difference is the function
signature. The Ext library requires both an "interval" and "value"
parameter. The Ext "interval" parameter options include the following:

Millisecond = "ms";
Second = "s";
Minute = "mi";
Hour = "h";
Day = "d";
Month = "mo";
Year = "y";

The Datejs .add() function requires an object literal "config"
parameter. Options include:

millisecond(s)
second(s)
minute(s)
hour(s)
day(s)
week(s)
month(s)
year(s)

Example

// Ext
new Date().add("d", 5);

// Datejs
new Date().add({days: 5});

The second difference is Ext Date .add() makes a new Date object (clone,
exact copy) of the original instance before adding the interval.

Throughout the Datejs library we consistently follow the native
JavaScript convention of treating the Date object as Mutable. Basically,
using Datejs functions like .set() and .add() modify the *original*
object and do not create a new Date object.

Example

// Ext
var d1 = new Date(2008, 11, 14); // 14-Dec-2008
var d2 = d1.add("d", 5); // 19-Dec-2008
alert(d1); // 14-Dec-2008

// Datejs
var d1 = new Date(2008, 11, 14); // 14-Dec-2008
var d2 = d1.add({days: 5}); // 19-Dec-2008
alert(d1); // 19-Dec-2008

Using the code above, with Datejs you would have to clone the d1 date
instance in order to get the same alert date as Ext.

Example

// Datejs
var d1 = new Date(2008, 11, 14); // 14-Dec-2008
var d2 = d1.clone().add({days: 5}); // 19-Dec-2008
alert(d1); // 14-Dec-2008

Within Datejs there are three different syntactic options for
adding/subtracting to/from a date object. The following code sample
outlines the three options in order of fastest performance.

Example

// Fast
Date.today().add(5).days();

// Faster
Date.today().add({days: 5});

// Fastest
Date.today().addDays(5);

When Ext.DateField uses the .add() function, just remember to .clone()
the date instance before using any of the Datejs add options.

Example

// Existing Ext code from Ext.DatePicker
this.update(this.activeDate.add("d", 1));

// New Datejs
this.update(this.activeDate.clone().addDays(1));

// Other options would include...
this.update(this.activeDate.clone().add(1).day());
this.update(this.activeDate.clone().add({day: 1}));
// ... but .addDays(1) is the fastest


That's really the the only breaking collision, although in order to
completely get Datejs (especially the Parser) integrated into
Ext.DateField you're going to have to do a little spelunking.

One other suggestion I have is to make sure you're using the latest code
from SVN. There was a change to .clearTime() after the Alpha-1 release
which avoids a breaking collision between Ext and Datejs.

Example

// Ext
var d1 = new Date();
var d2 = d1.clearTime(true); // clones the date, then clears the time

// Datejs Alpha-1
var d1 = new Date();
var d2 = d1.clearTime(); // no option to clone time
var d2 = d1.clone().clearTime(); // would be same as Ext .clear()

// Datejs latest SVN
var d1 = new Date();
var d2 = d1.clearTime(true); // clones the date, then clears the time

There's only one spot in Ext.DatePicker where .clearTime(true) is used,
so if you're using the Datejs Alpha-1 release, you'll have to call
.clone().clear(). With the latest SVN code no change is required.

It might be a good idea to just replace .clearTime(true) with
.clone().clearTime(), then you don't have to worry about Alpha-1 vs SVN
Datejs. I find .clone().clearTime() to be a little more explicit and
obvious about what's happening anyways.

Hope this helps get you started.


Tim

unread,
Dec 14, 2007, 11:52:08 AM12/14/07
to Datejs - A JavaScript Date Library
Wow, the support for this library is just fantastic. Geoffrey, thanks
for all of the info. I also received two emails regarding this issue.
Thanks to all who helped me with this issue.

I have implemented a simple workaround that allows the Datejs library
and the Ext.form.DateField (or Ext.DatePicker) to work nicely together
based on code that Mark was nice enough to email me with. Here's his
code (hope you don't mind, Mark):

$P.extAdd = $P.add;
$P.add=function(config, extVal){
if(typeof config=="string"){
var d=this.clone();
return d.extAdd(config, extVal);
}
if(typeof config=="number"){this._orient=config;return this;}
var x=config;if(x.millisecond||x.milliseconds)
{this.addMilliseconds(x.millisecond||x.milliseconds);}
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
if(x.hour||x.hours){this.addHours(x.hour||x.hours );}
if(x.week||x.weeks){this.addWeeks(x.week||x.weeks);}
if(x.month||x.months){this.addMonths(x.month||x.months);}
if(x.year||x.years){this.addYears(x.year||x.years);}
if(x.day||x.days){this.addDays(x.day||x.days);}
return this;
};

This would require modifying the latest Datejs source from SVN.
However, I have decided to implement a method that does not require
changes to the source of ExtJS or Datejs. Here's the code:

//Load Ext first then execute this code

//This stores the Ext Date.add function as Date.extAdd before being
overwritten by Datejs
Date.prototype.extAdd = Date.prototype.add;

//Load Datejs then execute this code

//Store the original Datejs Date.add function as Date.datejsAdd
Date.prototype.datejsAdd = Date.prototype.add;

//Overwrite the Date.add function. If an object is passed as the first
param,
//then assume that the Datejs Date.add function is being called.
Otherwise,
//assume that the Ext Date.add function is being called.
Date.prototype.add = function(config, extVal) {
if (typeof config == "object") {
return this.datejsAdd(config);
} else {
return this.extAdd(config, extVal);
}
};

By implementing this code, there appears to be no collisions between
DateJS and ExtJS. The Ext.DatePicker works as expected, and Datejs
works as expected. This was briefly tested with ExtJS 2.0 and the
latest Datejs source from SVN.

This is just a simple solution that may help anyone who's using ExtJS
and Datejs together and want to avoid incompatibilities. I think the
best solution would be to have some sort of plugin for ExtJS so that
it can use Datejs. Let's see what we can come up with.

Thanks again to all who helped.
Tim

Geoffrey McGill

unread,
Dec 14, 2007, 4:10:28 PM12/14/07
to dat...@googlegroups.com
Hi Tim,

I added all the required modifications to an Ext override file as you
suggested offlist. See attached.

Now all you have to do is include the Datejs library after the Ext
library, then include the attached ext_datepicker_overrides.js file
after Datejs.

script Order

1. Ext Library
2. Datejs Libary
3. ext_datepicker_overrides.js

With the overrides file, the Ext DatePicker/DateField now includes FULL
support for the Datejs library. This includes support for the Datejs
Parser. Users can type in a huge variety of date strings and the Datejs
library will fire back a date.

For a fairly complete list of what the Datejs Parser will support,
please check out the Test Suite (http://www.datejs.com/test/).

One of the coolest things is the Ext DateField includes realtime
validation, just like the "Mad Skillz" widget on the www.datejs.com home
page. The users date input is validated as they type... and it's ninja fast!

The overrides file could be smaller if you stripped out all the
redundant code left over from the Ext Date library, but I left it in for
reference.

You can find any revisions and/or comments I added by searching for
"///" (three forward slashes).

Hope this helps.


ext_datepicker_overrides.txt

Tim

unread,
Dec 18, 2007, 10:25:54 AM12/18/07
to Datejs - A JavaScript Date Library
Hi Geoffrey,

Thanks for supplying us with this file! I'll probably end up using it
in a future project.

I'm happy that my suggestions helped.

FYI: I put in an official change request in the ExtJS forums for
integration with Datejs. I haven't gotten a response yet. I'll keep
this thread updated with any new news.

Regards,
Tim
Reply all
Reply to author
Forward
0 new messages