Taming the categorized views - reloaded
My previous solution was designed for categorised views that don't use column totals. The difference between a view control with and without column totals is subtle but important. Without totals a category row is rendered with a colspan attribute that allows the categories to freely flow over the whole width of the table. Are column totals present no colspan is used and the column for the category must be wide enough to accommodate the full content. With a little JavaScript that can be fixed. The server side JS now looks like this:
while the client side JS now is this:
As usual YMMV.
-
function getClientJSforTableLayout (tableID ) {
-
/**
-
* This code has as result JavaScript source code that is send down to the client]
-
*/
-
var curTable = getComponent (tableID ) ;
-
var curID = getClientId (tableID ) ;
-
var tablewidth = extractWidthFromStyle (curTable. viewStyle ) ;
-
var result = "fixCatTableSpan(\"" +curID ;
-
result += "\");\n" ;
-
result += "fixCatTableWidth(\"" ; // This holds the JavaScript we return to the browser
-
result += curID + "\",[\"" ;
-
// Here we compute the sizeString
-
-
var kids = curTable. getChildren ( ) ;
-
var defaultPercent = Math. floor ( 100 /kids. size ( ) ) + "% " ; // You have to love flexi data types
-
var perCentArray = [ ] ;
-
for ( var x in kids ) {
-
var styleCandidate = x. style ;
-
if (styleCandidate == null ) {
-
perCentArray [perCentArray. length ] = defaultPercent ;
-
} else {
-
var candidate2 = extractWidthFromStyle (styleCandidate ) ;
-
if (candidate2 == "" ) {
-
perCentArray [perCentArray. length ] = defaultPercent ;
-
} else {
-
perCentArray [perCentArray. length ] = candidate2 ;
-
}
-
}
-
-
}
-
result += perCentArray. join ( "\", \"" ) ;
-
result += "\"],\"" +tablewidth + "\");" ;
-
return result ;
-
}
-
-
function extractWidthFromStyle (styleCandidate ) {
-
var result = "" ;
-
var whereisWidth = styleCandidate. indexOf ( "width:" ) ;
-
if (whereisWidth < 0 ) {
-
result = "" ;
-
} else {
-
var workString = styleCandidate. substr (whereisWidth + 6 ) ;
-
var hasSemiColon = workString. indexOf ( ";" ) ;
-
if (hasSemiColon < 0 ) {
-
result = workString ;
-
} else {
-
result = workString. substr ( 0 ,hasSemiColon ) ;
-
}
-
}
-
return result ;
-
}
-
-
function fixCatTableWidth (tableID , sizeArray , tableSize ) {
-
// Reset the outer table width
-
var outer = dojo. byId (tableID + "_OUTER_TABLE" ) ;
-
if (tableSize == null || tableSize == "" ) {
-
outer. style. width = "100%" ;
-
} else {
-
outer. style. width = tableSize ;
-
}
-
-
var max = sizeArray. length ;
-
// Get the table and all header elements
-
var table = dojo. byId (tableID ) ;
-
var allHeaders = table. getElementsByTagName ( "th" ) ;
-
var maxHeaders = allHeaders. length ;
-
for (i = 0 ;i <maxHeaders ;i ++ ) {
-
var curWidth = (i > max ) ? sizeArray [max ] : sizeArray [i ] ;
-
allHeaders [i ]. style. width = curWidth ;
-
}
-
}
-
-
/**
-
* Finds for a given element inside a table hierarchy the table data
-
* element it is contained in
-
**/
-
function getEnclosingTdTag (startElement ) {
-
var parent = startElement. parentNode ;
-
while (parent != null ) {
-
if (parent. tagName == "td" || parent. tagName == "TD" ) {
-
break ;
-
}
-
parent = parent. parentNode ;
-
}
-
return parent ;
-
}
-
-
/**
-
* Gets all categorized rows and replaces empty td with colspan
-
**/
-
function fixCatTableSpan (tableID ) {
-
var tbl = dojo. byId (tableID ) ;
-
var allButtons = tbl. getElementsByTagName ( "button" ) ;
-
var max = allButtons. length ;
-
for (i = 0 ; i <max ;i ++ ) {
-
var curButton = allButtons [i ] ;
-
if (curButton. title == "collapsed" || curButton. title == "expanded" ) {
-
//We need to process it
-
var curTD = getEnclosingTdTag (curButton ) ;
-
if (curTD != null ) {
-
replaceEmptyTdWithColSpan (curTD ) ;
-
}
-
}
-
}
-
}
-
-
/**
-
* Finds all empty td tags after a given start tag and removes them
-
* also inserts the colspan attribute into the start tag
-
**/
-
function replaceEmptyTdWithColSpan (startElement ) {
-
// No action needed if colspan is aleady > 1
-
if (startElement. colSpan > 1 ) {
-
return ;
-
}
-
var colSpan = 1 ;
-
-
var nextSibling = startElement. nextSibling ;
-
-
while (nextSibling != null ) {
-
var following = nextSibling. nextSibling ;
-
-
if (nextSibling. nodeName == "TD" ) {
-
// We stop at the first non empty node
-
if (nextSibling. firstChild == null ) {
-
nextSibling. parentNode. removeChild (nextSibling ) ;
-
colSpan += 1 ;
-
} else {
-
break ;
-
}
-
}
-
nextSibling = following ;
-
}
-
-
if (colSpan > 1 ) {
-
startElement. colSpan = colSpan ;
-
}
-
}
-
-
Posted by Stephan H Wissel on 09 July 2010 | Comments (3) | categories: XPages