Wednesday, March 3, 2010

With a Little Javascript From My Friends

Had an interesting problem with an XSLT data view today.

THE BACKGROUND: I needed to display a document library from another sub-site. I set up an XSLT data view to pull data from that document library. One of the fields I brought over was a multi-select lookup list. The values all came back in a semicolon-delimited format:

This;Is;What;The;Values;Looked;Like

Problem was, a number of rows had a very long list of tags in this column, and it wouldn't wrap on semi-colons...Although it WOULD wrap on hyphens. So sometimes you'd get:

A;Long;List;Of;Hypen-
Delimited-
Entries;That;Linebreak;Like;This

Massively ugly. I tried restricting the width of the column to try and force the data view to add line breaks, but that didn't work - the cells stayed very wide and wouldn't wrap where I wanted them to.

It took a bit of beating my head to my desk before I finally settled on the simplest solution. Convince CSS to wrap on a particular character? Count the number of chars, look for the next semicolon, and insert a page break after that? Rawrgh, too complicated!

Finally, I realized this could be tackled very simply. Word wrapping WAS working - just not on semicolons. What if we replaced them with a semicolon AND a space? This would keep things completely dynamic in case I wanted to change the column width in the future, too. But...how to make that happen?

In the end, I found two solutions. Some smart friends who know their way around Javascript helped put together the following:

function SeparateSemicolons( inStr )
{
var strArray = inStr.split(";");
return strArray.join("; ");
}

var clevervarname = document.getElementsByTagName("td");
var i = 0;

for (i=0; i < clevervarname.length; i++)
{
var place = clevervarname[i];

if( place.id == "TheTDWithSemicolons" )
{
place.innerHTML = SeparateSemicolons(place.innerHTML);
}
}


Placed at the end of the page in the appropriate tag, this did take care of the problem.

In conjunction, I poked around for a solution on the XSL side. I finally found a suggestion from David Carlisle here on replacing characters in XSL. I pasted in his code, changed the from and to parameters, and pointed it at my data field. Voila!

I think it's neater to do this on the XSL side, but it was great to get another round of education on Javascript at the same time.

Back to the grind!