Upgrading to jQuery 1.6: Problems you may face

I rarely (never?) blog. I’m not used to it. But I had to start somewhen. I think now is a good moment, cause upgrading to jQuery 1.6 pissed me off, as it’s not transparent as older upgrades were. I hope you’ll enjoy this post, Cheers!.

Ok, it’s a happy day, you surf the web and discover  jQuery 1.6 has been born. “New version, that’s cool, let’s upgrade!” you may say.  And you upgrade to the latest version as you usually do… but after some time, suddenly, you see your webpage begins to behave strangely (if not, you’re very lucky or it hasn’t happened yet)… what happened? The reason is that jQuery 1.6 has changed dramatically the behavior of some existing methods, breaking changes indeed…

Changes to .attr() method in 1.6. OMG!!

Maybe the most ‘polemic’ change that doesn’t allow to sleep to many developers (at least me), is the change made to the .attr() function. Now, it returns only html attributes and not dom properties. (If you want to get a dom property value as before, there’s a new method called .prop()). I think this change is crazy (good if jquery would have been born with this, but now, it’s crazy).

Consider the following markup:

<input type="checkbox" id="myCheckbox" checked="" value="1" />

Now consider doing

$('#myCheckbox').attr("checked")

You get the following results:

Code jQuery < 1.6 returns: jQuery 1.6 returns:
$('#myCheckbox').attr("checked")
true
""

Oh oh… Let’s go on and see something more ‘applied’:

if($('#myCheckbox').attr("checked")){
   alert("This executes in jQuery<= 1.5");
}else{
   alert("OMG. This executes in jQuery1.6!");
}

Oh my god. This is a HUGE problem in my opinion.  jQuery 1.6 broke our code.

Some of you may be thinking: I’d never leave an empty ‘checked’ attribute, or I’d not use .attr() to see if a checkbox is checked. Yes, but that’s not the point. The point is that this change isn’t fully backwards compatible. And, you may know your code well, but you don’t know how 3rd party plugins will behave.

Yes, the new .prop() method would do what we want, but this is a new function,  so our old code doesn’t use it.  Big problem

Changes to .data() method in 1.6

Now, the .data() function returns data attributes’ names (those prefixed with data-) with camelCase if you use hyphens, and lowercase if you don’t. Why? Because it’s a W3C recommendation. Why is it bad? Because it can break backwards compatibility.

Consider the following markup now:
<input type="text" id="myTextbox" data-firstName="John" data-last-name="Doe" />
And the following code:

$txt= $("#myTextbox");
console.log($txt.data());
console.log('.data("firstName")= ' + $txt.data("firstName"));
console.log('.data("firstname")= ' + $txt.data("firstname"));
console.log('.data("last-name")= ' + $txt.data("last-name"));
console.log('.data("lastName")= ' + $txt.data("lastName"));

These are the results

jQuery < 1.6 returns: jQuery 1.6 returns:
.data()= { last-name="Doe", firstname="John"}
.data("firstName")= John 
.data("firstname")= John
.data("last-name")= Doe
.data("lastName")= undefined
.data()= { lastName="Doe", firstname="John"}
.data("firstName")= undefined 
.data("firstname")= John
.data("last-name")= Doe
.data("lastName")= Doe

Legend

text Equal between jQuery versions
text Different depending on jQuery version

(Note that only the third and fourth lines return the same results in both cases)

So, if you had the following snippets to say “Hi John”, “Bye Doe” in your old-happy jquery 1.5 code:

alert("Hi, " + $txt.data("firstName"));  //Outputs "Hi John" in jQuery < 1.6
alert("Bye, " + $txt.data()['last-name']);  //Outputs "Bye Doe" in jQuery < 1.6

in jQuery 1.6 it would show undefined in both cases. Not good at all.

Possible solutions

Well, those are the problems. Now, there are some solutions. But unfortunately, none of them is easy.

Solution 1: The obvious, and hardest one:

– Change all the code you have, looking for this .attr() and .data(), and change them (when necessary) to be compatible with jQuery 1.6 (doh!, awful solution!).

– In the case of 3rd party plugins, if they are minified apply this changes to unminified versions, and then re-minify them with some minifier (YUI Compressor, packer, uglify or the one you prefer).

Solution 2: Extend jQuery to have both old and new behaviors

– Write a jQuery plugin, let’s say .oldAttr(). This method would have to behave exactly as the old .attr(). This is not so hard if you check jquery 1.5’s source code (I can do it if there are requests). The same should be done for .data, writing an .oldData() plugin.

– Replace all .attr() and .data() calls with the new .oldAttr() and .oldData() plugins.

– For 3rd party plugins, you should replace in unminified versions and then minify again as explained in the previous solution.

– Then, for your new code, use jQuery 1.6, attr(), prop() and data() as the documentation describes.

Solution 3: Wait and Pray (and pressure!) so jQuery folks regret. (I really hope it)

– Wait until the jQuery Team realizes these changes are EVIL (specially the .attr() case), and correct these changes to be backwards-compatible in the next jQuery version (1.6.1). So, we wouldn’t have to make any changes to our code. I hope it!


Well, that’s it. Do you agree? Have any comments? Do you think there are other solutions? Any comment is welcome.

Posted in jQuery | Tagged , , | 3 Comments

Paginación en SQL Server

La paginación en SQL Server puede ser una pesadilla para muchos, ya que este DBMS no posee una cláusula LIMIT como la de MySQL.

Aqui propongo una equivalencia de la cláusula LIMIT de Mysql en SQL Server 2005.
En Mysql (con LIMIT):

SELECT EST_NOMBRE, EST_NUMEROSERIE
FROM ESTACION
WHERE EST_DESC LIKE ‘%W%’
ORDER BY est_id
LIMIT 2, 6

En SQL Server 2005 (sin LIMIT):

SELECT EST_NOMBRE, EST_NUMEROSERIE
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY est_id) AS nfila FROM ESTACION
WHERE EST_DESC LIKE ‘%W%’
) AS ESTACION_NUMERADA
WHERE nfila BETWEEN 2 AND 8

Espero que les sirva

Posted in SQL Server | 1 Comment