November 26, 2011

Extending ExtJS 4 DatePicker to highlight marked dates


Hi guys,

So today I want to share with you a little extension that I re-wrote for ExtJS 4 DatePicker component.
I say re-wrote, because this is an advanced form of the solution presented here, except that the other one relates to ExtJS 3 and not as robust.

So the basic idea is to have a marked dates on the calendar, same as you would have on your meeting calendar date picker in outlook. I also wanted the component to show some related tooltips for the marked date, and that meant that the data provider for the component is not strictly dates (as in a String, like the other solution), but rather an Objects that contains some metadata for the date.

Let's start with the data that we wish to be displayed. We want to have the date marked, so we need a Date, and for this example we will use the JS Date object, and for each date we want to display tooltip for a mock percentage and cost. So we're actually talking of an object that might look like this:
{date:new Date(2011, 10, 19), percent: '30%', cost:596}
On the component itself we I've created a config member named "markers". This one will hold the array of objects mentioned above.
config: {
    markers: null
},
In addition I want the JS Date object that is given to the DatePicker to use the same date format that is configured for the DatePicker, so for the sake of that lets override the applyMarkers method and in it apply the DatePicker format on each date. With this process we're actually changing the data within the markers from a simple Array to Associative Array, or a Map if you want, where each cell is defined by the formatted date and in it holds the metadata. This will help us later in marking these dates easily.
applyMarkers: function(markers) {
var formattedMarkers = [],
me = this

var formatDates = function(marker) {
var format = me.format,
eDate = Ext.Date,
formattedDate = eDate.dateFormat(marker.date, format)

formattedMarkers[formattedDate] = {percent: marker.percent, cost:marker.cost};
}

Ext.Array.each(markers, formatDates);

return formattedMarkers;
},
We're getting to the heart of the modification. Here we override the fullUpdate method of the DatePicker since it is the one that is in charge of rendering the cells within the calendar, we will add our own "if" statement to ask if there are dates to be marked, and if so we will find the cells that match the dates on the associative Array and append a tooltip according to marker object data.
For convenience purposes I'm only giving the relevant code part:
fullUpdate: function(date, active) {
...
var markers = this.markers;
...
setCellClass = function(cell) {
...
// If we have a need for highlighted dates, let's find the dates
// and start highlighting them
if (markers) {
formatValue = eDate.dateFormat(current, format);
if (markers[formatValue] != null) {
// Use the highlight-date CSS class for highlighting
cell.className = 'highlight-date';
cell.title = "Percent: " + markers[formatValue]["percent"] + "\n" + "Cost: " + markers[formatValue]["cost"];
}
}
};
...
}
Notice that I'm using a CSS class named "highlight-date" to mark the cells. This class, of course, should be included in your CSS file.
And there you have it. A DatePicker that lets you mark dates and append tooltips for it, here is how you use it:
Ext.create('Flashmattic.component.AdvancedDate', {
markers:[
{date:new Date(2011, 10, 19), percent: '30%', cost:596},
{date:new Date(2011, 10, 10), percent: '10%', cost:45},
{date:new Date(2011, 10, 8), percent: '86%', cost:367}
]
})

Have a great week,
Cheers.

November 16, 2011

Apache Flex? Hell yeah

You've probably heard the old news, about Adobe ditching the development for Flash Player on Mobiles devices, but here is something even newer:
From the "your questions about flex" announcement it is pretty sure to say that Adobe has decided to ditch the Flex SDK and BlazeDS development and proposed an offer for the Apache Software Foundation to "incubate" both.
Before you jump into conclusions I strongly suggest that you read the Q&A once again, to understand what this step means to the Flex community. And now that you have, I'll give you my 2 cents on the topic.
Although many will refuse to believe, I did foresee this coming, though I didn't imagine that Adobe will renounce themselves from Flex, and I still stand behind my words that "ditching Flex and moving to HTML5 completely is also not the smartest path to take" but enough quoting myself.
Many might say that this announcement is the final nail in Flex coffin.
I think not.
As a matter of a fact, this might bring the Spring (pun intended) of Flex and maybe put a sock in the mouths of those Java geeks who walked around shouting "Adobe is not a code company" - meaning that Adobe cannot be compared to Oracle (Sun) in delivering a coding platform like Java. Now if Apache takes the wheel this might change for the best.
I will say it again - Flex will lose it's place in the RIA technologies market. HTML5, at it’s uncompleted form today, can already supply 90% of what Flex can offer, however, Flex is still a valid technology, as I see it, and if I came across a project that shouts "Flex!", I will not hesitate.
If Apache will except Adobe's offer, this will mean that Adobe no longer decides where Flex goes - the community does. If back then, we had to scream for better compiler, I believe that in the hands of Apache the response will be quicker and much better.

Just think of it - "Apache Flex".
Too bad Adobe is keeping the development for the Flex Builder, but what can you do.
So - no doubt that the future will be interesting (in spite of HTML and JS) and I do wonder what Adobe and Apache will cook for us. In the meantime, try to remember these unquestionable truths:
  • Flex offers complete feature-level consistency across multiple platforms
  • The Flex component set and programming model makes it extremely productive when building complex application user interfaces
  • ActionScript is a mature language, suitable for large application development
  • Supporting tools (both Adobe’s and third-party) offer a productive environment with respect to code editing, debugging and profiling
Cheers



November 10, 2011

Combine, Minify and Copy your JS's to your .war file using Gradle

So - In the course of work I was introduced to Gradle.
WTF is Gradle, one might ask - in brief? It's a much flexible manner of building your projects than Ant or Maven. It's based on Groovy (which always makes me laugh thinking on the nerd who came up with that name and thought he is so damn cool), and I leave it to you to go and read about it.

First thing first I wanted to build my .war file. No problem there. Just apply the "war" plugin to your gradle.build file and you're done. Seriously - that's it.

apply plugin: 'war'

So I have my .war file empty and now I want to add my JavaScript to it. Oh, wait - I want to add my minified JavaScript to it, not just that, but I want to combine all of my JS files into one, and just then minify it. To the rescue comes gradle-js-plugin which can minify my files using the infamous Google's Closure Compiler and of course the easy way gradle lets you arrange and configure it's tasks.

So I added this plugin, like this

apply plugin: 'js'

And asked it nicely to combine all the files and simple-optimize it. As you can see, my JS files are under the src/main/javascript directory

combineJs {
input = fileTree(dir: "${projectDir}/src/main/javascript", include: "**/*.js")
output = file("${buildDir}/all.js")
}

minifyJs {
input = file("${buildDir}/all.js")
output = file("${buildDir}/all-min.js")
compilationLevel 'SIMPLE_OPTIMIZATIONS'
warningLevel = 'QUIET'
}

As you remember I wanted to make all that before I copy it into my war so, I've added this procedure before the .war building. Again - compared to Maven, it's done pretty easily by using the doFirst task method

war.doFirst {
tasks.combineJs.execute()
tasks.minifyJs.execute()
}

Ok - so now we have a combined minified JS file on our build directory, the next thing to do is to copy it into the .war file. Here I use the war plugin again and use it's webInf() method to add some content to the WEB-INF. I'm copying the minidified file into the root of the webapp under a directory named "js".
Actually the webInf(method) is responsible for adding resources to the WEB-INF directory, not the root of the webapp, but by adding "/" before the "js" I've worked around it.

war.webInf {
from "${buildDir}/all-min.js"
into "/js/"
}

There you have it. Running gradle build will create our webapp with all the above included.
I guess that this is not the last post on the topic, since gradle will probably walk with me several miles, so stay tuned.

Cheers.

November 05, 2011

Flex Missioner talks ExtJS

The Plot Thickens
You know - It always made me laugh and then feel sorry for the new emerging RIA technologies. As a Flex senior missioner, I found those fail attempts pathetic at. I'm obviously talking on platforms like "Silverlight" (Silver… what? Oh, that project MS closed not so long ago), "Open Laszlo", "JavaFX" (heheh oh boy, the horror!) and the list goes on and on.
To me it appeared that JavaScript is a script (I dare you call it a programming-language!) that played it's part in the web world some 10 years ago, and has no place, but frustration, in today's web technologies.
Alas, Came Steve Jobs and thickened the plot.
HTML5, as the new web standard (you're kidding, right?) enters and changes the game rules. Suddenly we're back at the mercy of JavaScript. Things like the DOM which I happily have forgotten for the sake of Smart View Interfaces, reincarnated and came back to haunt me, along side with browser incompatibilities, poor debugging, and messy code. God damn.

A new hope...
It was then that I have discovered a new hope.
Now, as some of you may know, once upon a time there was ExtJS, which was and still is, a very nice JavaScript library. Then, one day, came the merge with JQTouch which gave birth to "Sencha".
History is lovely, isn't it? Yeah… whatever.

I'm skeptic when it comes to new RIA technologies. Maybe it's because I know what it means to really compete with Flex for territory. I'm not the kind of UI Architects that sees a nice Control or a Component and jumps with joy, pants down, shouting "Eureka!". When it comes to the best UI technology for web applications there are a lot to consider, like: Richness, Extendibility, Community, Browser Support, Vendor liability, Ramp up Time… just to list a few.
ExtJS knocked me down.
I'm used to seeing pixilated controls, with "not quite there" finish to them, but here it actually looks like… well... Flex! Even better to some extents. Going to create a theme in ExtJS, and you will find freaking amazing integration with SASS and Compass that generates you're CSS and with a single variable can alter the entire look of you're application. Now try to extend one of it's components. Again - nothing dodgy there. MVC you say? Well, you have it. I know it's a bit twisted but there is a solution that actually give you the benefits of MVC.
And JavaScript? ExtJS made it so close to OOP, that you even don't feel the heartburn when writing "new" to create an Object.
Oh wait, hold on - what about the client Data package? No problems there, mate. JSON you say? There you go - a verity of "proxies" to integrate with any kind of Web Services out there (though I didn't see any AMF implementation, and as you know AMF out-performs any String based communication when it comes to large masses of data). This, my fellow Flexers, is not some immature platform we're dealing with here. It looks like every aspect was thought of.

Sitting on the shoulders of the giants
So, some might say, and be right about it, ExtJS is sitting on the shoulders of the giants, meaning it looks as if a lot of the component architectures, down to the Data packages ware "inspired" by other technologies, and dare I say, Flex in particular. Do you have a problem with it? On the contrary my friends, I'm good with that.
I must say, though, that the layout configuration is somewhat not intuitive, where words like "fit", "flex" and "stretch" don't do exactly what you thought they would, and hey - don't forget the whole browser compatibility, where extJS 4 doesn't really play nicely with IE9 (CSS gets screwed up and other kinds of glitches)… oh well.

Breathing on Adobe's neck?
Another thing to add to the grill is the fact that Sencha has launched it's own Animator, as if breathing on the neck of Adobe which also, recently, launched it's own solution for animation and transition editing tool for HTML5. now - that's pretentious of Sencha. Why? I believe that the experience that Adobe has in Designer IDE's plus the advantage they have from Flash, plus the integration with other graphic tools (Photoshop, Illustrator) will probably crush any attempts from Sencha, but you can never know. History teaches us that it can take only a single Company to change the entire developing agenda of the web, even if it's taking it 10 years backwards.
:)

Cheers.