Upgrading ColdFusion: CFGRID has an inconsistent width attribute

Posted on May 10, 2012

I’m in the process of moving a massive, years-old application from ColdFusion 8 to ColdFusion 9. I’m also testing on ColdFusion 10 (currently in beta). I’ve run into a few issues and will document them here. First up: Setting the width of a CFGRID.

What is CFGRID?

Write a query, pass it to CFGRID and you get a grid of data rendered in either Flash (Flex?) or in HTML/JavaScript via Ext.js. Here’s an example straight from the documentation:

<!--- Query the database to fill up the grid. --->
<cfquery name = "GetCourses" dataSource = "cfdocexamples">
  SELECT Course_ID, Dept_ID, CorNumber,
  CorName, CorLevel
  FROM CourseList
  ORDER by Dept_ID ASC, CorNumber ASC
</cfquery>

### cfgrid Example
_Currently available courses_
<!--- cfgrid must be inside a cfform tag. --->
<cfform>
  <cfgrid name = "FirstGrid" format="Flash"
    height="320" width="580"
    font="Tahoma" fontsize="12"
    query = "GetCourses">
  </cfgrid>
</cfform>

Documentation

Documentation for ColdFusion 8.

<cfgrid . . . width="integer"></cfgrid>

Documentation for ColdFusion 9.

<cfgrid . . . width="integer"></cfgrid>

Documentation for ColdFusion 10.

<cfgrid . . . width="integer"></cfgrid>

Regardless of version, for width:

“In HTML format, can be in any valid CSS measurement unit, and a numeric-only value specifies pixels.”

LIES!

Some of the CFGRIDs currently in use are set to width=”100%” and they’ve been working for years.

<cfgrid name = "FirstGrid" format="Flash"
  height="320" width="100%" <!--- Works in CF8 --->
  font="Tahoma" fontsize="12"
  query = "GetCourses">
</cfgrid>

Run that code in ColdFusion 9 or 10 and BOOM!

Attribute validation error for the CFGRID tag.
height/width attribute cannot be a percentage value.

Is a percentage value a “valid CSS measurement unit”? Yes it is! Was this a CF8 bug that was fixed in CF9? An oversight in documentation? Either way it’s a PITA.

Solution

I tried redefining the classes on the DIVs that make up the grid, but they all have inline definitions, so those <style> entries get overridden. Then I tried using jQuery with setTimeout() to replace the inline CSS values after the page has completed loading, to little effect.

<script type="text/javascript">
$(document).ready(function(){

  setTimeout( function(){
    $('div.x-grid-container').css('width', '100%');
    $('div.x-grid').css('width', '100%');
    $('div.x-grid-topbar').css('width', '100%');
    $('div.x-grid-scroller').css('width', '100%');
    $('div.x-grid-viewport').css('width', '98%');
    $('div.x-grid-bottombar').css('width', '100%');
  }, 2000);

});
</script>

This didn’t affect the width of the column headers (if you set autowidth=”true”, the columns scale to the width of their content and then to the width of the grid container). If you resize the browser, an onResize() function kicks in and the DIVs are reset to their original width.

I’m sure we can replace these grids with something like DataTables or a direct implementation of an Ext JS Grid, but that would incur a lot of regression testing, so that has to wait.

The solution I implemented was to set the width to a static value and move on. If anyone has figured out a way to get these grids to 100% width, I’d love to hear it.

About the Author
Adrian J. Moreno

Adrian is a CTO and solution architect specializing in software modernization. More information