View Full Version : Refactoring a render to use a layout and render items iinside of a column cell

11 Jan 2012, 6:12 PM
I have inherited some terrible code. I have this grid that uses the renderer property to serially render html content to a column cell.

renderer: function (value, metaData, record, rowIndex, colIndex, store, view) {
//var display = record.get('Indent');
var display = '';
var taskId = record.get('Id');
var isBusy = record.get('IsBusy');

// Get description column width
var colWidth = this.columns[colIndex].width;
// Split value string into array. Each arr val holds 2/3 of max row length
var splitLen = parseInt(colWidth - (colWidth / 3));

// Create a string to inject variable splitLen into RegExp constructor.
var reString = new String('.{1,' + splitLen + '}');

// RegEx matches every nth characters where n = splitLen...
var re = new RegExp(reString, 'g');
// ...and will split string into array.
var valueText = value.match(re);

if (isBusy) {
//display = display + '<img class="expander-image" src="/ExtClient/images/busy.gif"/>';
display = '<div style="float: left"><img class="expander-image" src="/ExtClient/images/busy.gif"/></div>';
} else {
if (record.get('ChildCount') > 0) {
if (record.get('IsExpanded')) {
display += '<div style="float: left"><a style="cursor:hand" href="#" onclick="ToggleNodeExpansion('
+ taskId + ');return false;"><img class="expander-image" src="/ExtClient/images/minus.png" /></a></div>';
} else {
display += '<div style="float: left"><a style="cursor:hand" href="" onclick="ToggleNodeExpansion('
+ taskId + ');return false;"><img class="expander-image" src="/ExtClient/images/plus.png"/></a></div>';
} else {
display += '<div style="float: left"><img class="expander-image" src="/ExtClient/images/blank.png"/></div>';

display += '<div style="float: left; padding-left: ' + record.get('Level') + 'em"><span>'
+ record.get('LabelNumber') + ' - ' + '</span></div>';

display += '<div style="float: left; padding: 0 0 0 .5em"><span>' + valueText.shift() + '</span>';

Ext.Array.forEach(valueText, function (i, e) {
display += '<div><span>' + i + '</span></div>';
// console.dir(i);
}, this);

display += '</div>';

if (!record.get('IsCategory')) {
var initials = record.get('Initials');
//display = display + ((initials == null || initials == "") ? '' : (' (' + initials + ')').italics().fontcolor('gray'));
display += ((initials == null || initials == "") ? '' :
'<div style="float: left; padding: 0 4em 0 1em"><span style="color: grey; font-style: italic;"> (' + initials + ')</span></div>');
} else {
display = display.bold();
//return isBusy ? (display + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUSY'.bold()).italics().fontcolor('gray') : display;
// TODO: inline style is temp hack. Move to external CSS
return isBusy ? display + '<div style="float: left; padding: 0 5em 0 0"><span style="font-weight: bold; color: grey; ">BUSY</span></div><div style="clear: both"></div>' : display + '<div style="clear:both"></div>';

As you can see this thing does a lot. I was supposed to fix an issue with text wrapping, making it so that text that wraps lines up with the first character of the description rather than the beginning of the cell. However, when the size of the column is reduced below a certain threshold, the floated divs begin to stack.

I was reviewing the api docs for column and I see that I can specify a layout and items. How can I move each of these floated divs to a hbox components where each is flexible?

Remember, I need to do condition checking to determine how each sub-component of a cell is rendered. I need to do things like check the isBusy property and inject the loader gif and some text to indicate that the row is loading. Also, the previous developer set it up so that the click handler is attached via onclick in the html of the toggle image. I would eventually like to move this to a component and the function to a controller. However, for now I'll settle for a quick and dirty solution.

12 Jan 2012, 8:01 AM
A cell cannot use layout as it's not a container. That config is leftover from the subclassing of Ext.grid.header.Container