Pages

November 04, 2012

Grails r:script and g:include - workaround

Hi,
As others did, I also bumped into this mess. I wanted to include a controller view into another view, and have the nested view contain JS which can be used on that view, but r:script and g:include are not best friends.
I found a workaround you might find useful as well. I simply add an empty r:script tag on the parent view (the one who is using the include) and that's it, like this:

Parent view, on the HEAD tag:
 

And in the nested view:

// Script here


Mind you that we're counting on using the main.gsp layout (or some other layout which supports r:script)

October 31, 2012

Flashmattic has a new code highligt

Hi guys,
A small update - I've took the little time I have to update the way the code is presented in my blog. I must say that I should have done this a long time ago...
You can see a sample here.
Now you will be able to read it easier and use it better. Unfortunately I don't have the time or patience to go over previous posts and modify them so you should only expect it from now on.

Cheers

July 22, 2012

Stop using IE - Start using the web

It appears that many startups are consciously choosing to stop supporting IE ,and by that saving loads of cash and man hours for the project. I'm here to support this decision - IE should be banned out the internet community.

Whilst other browsers offer the freedom and ingenuity, MSIE seems to be stuck in some kind of a religious conservatism of keeping their user, from both ends, suffering.

It is as if that little child has finally raised his head, pointed out shouting "this king is butt naked!", or in other words - if you choose IE7 pay me up some taxes for making me bend in ways developers should not. And I'm saying, why stop at IE7 alone? Here, check this out - The jQuery core team has announced that it will quit supporting IE6/7/8 from it's 2.0 version.

Just think of the amazing stuff that could have been done hadn't IE been around. I know that MS is really trying to catch up (no, really, they are trying so hard it kinda brings tears to ones eyes), but IE9 is not there, and IE10, well - can MS please decide if they're enabling flash content there or not already?! And why should anyone wait for a version that it's feature he can get on other browsers now? indeed, old browser do hold the internet back.

And one might say that the problem is us. I mean, if we, as web consumers will stop using IE that will be it. How hard it is to upgrade your browser into something better? It's like people still want to drive with their bear feet like the Flintstones while there is a brand new Ferrari right next to them.

I must admit, that the only reason I'm still using IE is the fact that almost every government site in IL support IE only. Nothing works on FF or Ch and this is extremely annoying, but let me add that many official state services have started to realize that they need to support other browsers, like banks, healthcare etc.

The title "Internet Explorer" cannot be more misleading. Explorer is someone who boldly goes in search of new exciting adventures and experiments, where IE is more like the little guy at the end of the expedition line carrying everyone's dirty laundry. Far behind FF and Ch which are truly out there, leading the exploration to new worlds.

Stop using IE. Start using the web.

June 23, 2012

Intercepting and Routing AJAX calls with ExtJS

Hi there.
So yeah, I'm still messing around with ExtJS and still discovering it's quirky ways of making the lives of developers easier (to some extent, lets not get to optimistic now, shall we).
Today I want to share with you a nice way for intercepting and then routing AJAX calls from ExtJS. This may come extremely handy when you want to use relative paths within you Model/Store proxies, but want to test them for a specific server, meaning you want that relative URL to be converted into an absolute path. This way you don't introduce new code to the application but rather implement the solution externally (the HTML wrapper of the application is a nice option of doing it).
So say that our model looks like this (taken from Sencha docs):
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email'],

proxy: {
type: 'rest',
url : '/users'
}
});
Now, this Model will fetch data from a relative path to the web application it runs on, meaning that if you are running on http://localhost/myapp, it will go to http://localhost/myapp/users.
But this is not what we want. We want it to go to http://otherdomain/users. Enters the Ext.AJAX singleton.
By using the Ext.AJAX singleton we can intercept any AJAX call on the system and re-route it to a different location - here how it is done:
Ext.require('Ext.Ajax');
var URLPrefix = 'http://otherdomain/'
Ext.onReady( function() {       
Ext.Ajax.on("beforerequest", function(conn, options, eOpts){
options.url = URLPrefix + options.url
});
});
On the code above we're listening on the "beforerequest" event of the AJAX singleton, and the handler alters the URL by adding it a prefix of the desired domain.

That's it. Simple, ain't it?

Cheers.




March 06, 2012

ExtJS Simple Charts Walkthough and Workarounds

Hi guys,

I was in a need for a simple application that displays a nice grid and a chart alongside, both "look" at the same data source with all it means.

The technology at hand is ExtJS (4) and I was wondering, being a Flex fan (wait… yeah, ok), how well did Sencha made their charting framework, and their MVC infra. If you don't have the time to read further, I will sum it up for you - they did a pretty good work at it, but there is still room for improvement. I will try to explain what I mean, and hopefully let you learn from my experience so that you will know how to workaround issues I came across.

Ok, so ExtJS MVC infra has really made it simple. I had a Model that defined the fields and the proxy (a RESTFul service, providing JSON responses). Then I created a Store that would link to that Model and have it auto load the data when initialized. This pretty much concludes all the "data" section of the application. Out-of-the-box configuration, nothing to it.

Moving to the view, I've created a simple Viewport that contains the Grid and the Chart. On this note, I would like to say that Sencha still have a lot to improve on layout-ing. I always get mixed up with "flex", "fit", "stretch" etc. it is so confusing and not intuitive, unlike Flex layout-ing. I ended up using an "hbox" layout… oh, well.
No controller was involved in the process yet, but we'll get to that in a minute.
My data model contained a "name" field and 2 numeric fields. I wanted these 2 to be on 2 different Y axis, where the name played the part of the "category" axle. So here are my axes:
axes: [
{
title: 'Score',
type: 'Numeric',
position: 'left',
fields: ['score'],
minimum: 0
},
{
title: 'Hits',
type: 'Numeric',
position: 'right',
fields: ['hits'],
minimum: 0
},
{
title: 'Player',
type: 'Category',
position: 'bottom',
fields: ['player'],
label: {
rotate: {
degrees: 60
}
}
}
]

You see what I did there with the label on the "Player" axle? I had to, for if the labels don't have enough room to be displayed to the fullest, they are simply trimmed off leaving not-so-nice gaps , so having them rotated a bit was a good enough solution for that.

I then created the series, and here comes the frustrating part. It is not as trivial as you might think. I assumed that if I create 2 column series and define the yField that each relates to, I'm done. But no. when you do that you get an overlapping series, where the columns stand on over the other on the same category, and not one next to the other. If you want it to be one next to the other they need to share the same Y axle, which was not my goal.

After a quick search I understood that this is a well-known bug and if I desire something that will be readable, I have to use different types of series, so I ended up using "line" and "columns". That's kinda sucks. As I see it, it is a level 0 defect of Sencha charting.

Ok, so after having that figured out I wanted to change the scale of the Y axes I had, meaning that each will go from 0 to it's max, where max is relative to the max value it may contain according to the data given. I've set the axes "minimum" property to 0 and didn't set the max, as the documentation suggested. Running the application caused the 2 series to be relative to a single axle. What? Why? Well, it appears that if you don't specify the series the axe it relates to, it relates to the first axle it finds. It’s pretty stupid, since I've already defined the yField the series works with, and on the axes definition I've defined which axle work with which yField so… can't ExtJS figure it out by itslef? That should be the default behavior where if I wanted something more advanced I would gladly define the axes for each - not mentioning that the documentation really lacks in that aspect. Why should I find this "trivial" information on a blog? Why should you?

I ended up with the following definition of my Series:
series: [
{
type: 'column',
xField: 'player',
yField: 'score',
axis: 'left',
style: {
fill:'#77AECE'
},
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('player') + ' score: ' + storeItem.get('score'));
}
}
},
{
type: 'line',
xField: 'player',
yField: 'hits',
axis: 'right',
style: {
stroke:'#77AECE'
},
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('player') + ' hits: ' + storeItem.get('hits'));
}
}
}
]

Ok, this was starting to look good. I must admit that the binding done between the Store and the grid/chart was impressive. I would sort the grid, and the chart would change accordingly with no intervention by me. The animation was playing smoothly, everything was scaling and resizing nicely. Well done, Sencha. The code lines that ware involved were narrowed to just what needed. A simple application remained simple in code terms, while still enforcing the principals of MVC.

Moving forward, I wanted to create a "stupid" polling that will fetch the data every 5 minutes. This is where the Controller came to the rescue. I've created a controller, that referenced the store I'm working with, and when initializing it, I used the TaskManager to create a timed event. Here is the code:
stores : ['PlayersStore'],
init : function() {
Ext.TaskManager.start({
run: this.refreshData,
interval: 300000,
scope: this
});
},
refreshData: function() {
this.getPlayersStoreStore().load();
}

That is it!

Pretty simple, won't you think? I must say that I am (yet again) impressed with the work Sencha have done. I admit that having this in Flex would have been probably as easy to do, but playing with it's scale would have been a little scary. Altogether, ExtJS gives you some kind of assurance that everything will render as expected. This is something, I have to admit, that I did not take for granted using Flex.

1 hour and you have an application that sums up the best part of UI concepts in RIA development today.

Hope it helped you.



Cheers.