Using jQuery for evil
Sometimes you find a tool that's not just good for run-of-the-mill, intended-purpose work, but also for fixing up some bad situations. jQuery is one such tool.
Some work I'm currently doing involves presenting nicely styled pages to the user of a web site. The html I have to work with is not always ideal and needs to be massaged. Because I'm dealing with templates, it's often simply impossible for me to change the html - I can only try to modify the framework around the bits of html I'm given.
Enter jQuery.
Provided the html I get is more or less xhtml compliant, I've got a Document Object Model (DOM) I can work with. Using jQuery, I've found that I can manipulate this to my heart's desire.
Let's say I end up with an table which has an extra row between the header row and the first actual row of data. No problem!
$(document).ready(function() {
$('#mytable tr:nth-child(2)').remove();
});
And that's it! Of course you may get a flicker of the incorrect display because we're making the change only when the DOM is completely built, but we're not really choosy in this situation.
Let's try something a bit harder. How about reformatting a table which contains a single column for debits and credits; the debits formatted with a red <FONT> tag. And before you ask, yes, I'm serious.
We want this table to have a separate column for debits and credits. Again, enter jQuery.
$(document).ready(function() {
// first, deal with the headers
var cell = $('#mytable tr:eq(0) td:eq(2)'); // look at the second cell (contains debits/credits)
var w = cell.attr('width').substr(0, cell.attr('width').length-1); // I know width is a percentage
cell.attr('width',''+(w/2)+'%'); // half the width
cell.text('Credits').before('Debits '); // split Debits and Credits header
// now deal with each non-header row
$('#mytable tr:not(:first)').each(function()
{
$(this).children('td:eq(2)').before(' '); // insert the new column
var redVal = $(this).children('td:eq(3)').html(); // get current column value
if (redVal && (redVal.toUpperCase().indexOf('COLOR=RED') > -1 || redVal.toUpperCase().indexOf('COLOR="RED"') > -1)) // if it's red
{
redVal = $(this).children('td:eq(3)').children('font').text(); // get the actual value to write
$(this).children('td:eq(2)').html(' '+redVal+''); // write to the debit column
$(this).children('td:eq(3)').html('nbsp;'); // erase the credit column
}
});
});
Now this doesn't give me beautiful xhtml, and I'm never going to feel happy about how this works, but it does the job.
Fun stuff.