:: Forum >>

Contribution: Double click header separator to resize column to fit text width

I was reading through http://www.activewidgets.com/javascript.forum.14216.2/double-click-the-separator.html and thought there could be a better way to find the size of the column to fit text width.
The piece of code below copies the text from each column into a hidden span and checks its width to get to know the exact width of the text.

Of course, you will have to set the span to the correct font family and font size you use.
It will also detect multi-line text when you use <BR>.

Due to padding, etc the calculated width might be a bit off.
So, the variable adjust is used to add a fixed value to maxSize.
I've set it to 15, but if you use cell images, you might want to increase it.

Suggestions and improvements are welcome.
Here's the code:

<html>
<head>
<script src="activewidgets/runtime/lib/aw.js"></script>
<link href="activewidgets/runtime/styles/xp/aw.css" rel="stylesheet"></link>
</head>
<body>
<script>

var adjustment = 15;

var myColumns = [
["a","this is some long text", "a very very very long line of text", "another long piece of text"],
["a","this is some long text", "1234", "another long <BR>piece of text<BR>that is multi-line"],
["a","this is some long text", "1234", "another long piece of text"],
["a","this is some long text", "1234", "another long piece of text"],
["a","this is some long text", "1234", "another long piece of text"],
["a","this is some long text", "1234", "another long piece of text"],
["a","this is some long text", "1234", "another long piece of text"],
["a","this is some long text", "1234", "another long piece of text"]
];

var obj = new AW.UI.Grid;
obj.setCellText(myColumns);

obj.setHeaderText(["header 1", "header 2", "header 3", "header 4"]);

obj.setColumnCount(4);
obj.setRowCount(8);
obj.setRowHeight(40);
obj.getRowTemplate().setClass("text", "wrap");
obj.setCellTemplate(new AW.Templates.ImageText);

obj.setCellEditable(true);

obj.getSeparatorTemplate().setEvent("ondblclick", function(event){
this.raiseEvent("onSeparatorDoubleClicked", event, this.$0);
});

obj.onSeparatorDoubleClicked = function(event, col){
if (!col) {
return;
}

var maxSize = 0;
var hiddenSpan = document.getElementById("textSize");

for (var i = 0; i < obj.getRowCount(); i++) {
var text = obj.getCellText(col, i);
var textArray = text.split("<BR>");

for (var j = 0; j < textArray.length; j++) {
hiddenSpan.innerHTML = textArray[j];
if (hiddenSpan.offsetWidth > maxSize) {
maxSize = hiddenSpan.offsetWidth;
}
}
}

var text = obj.getHeaderText(col,0);
hiddenSpan.innerHTML = text;
if (hiddenSpan.offsetWidth > maxSize) {
maxSize = hiddenSpan.offsetWidth;
}

obj.setColumnWidth(maxSize+adjustment, col);
}

obj.setSize(800, 500);

document.write(obj);

</script>
<BR>
<span id="textSize" style="font-size:11px;font-family:Tahoma;width:auto;visibility:hidden;white-space:nowrap;"></span>
</body>
</html>
Ankur Motreja
Thursday, May 10, 2007
Thank you, Ankur - that's a very interesting idea. I just wonder how fast is this for large datasets.

Another possible implementation would be just measure offsetWidth of the text element (virtual mode = false) -

obj.getCellTemplate(c, r).getContent("box/text").element().offsetWidth;
Alex (ActiveWidgets)
Thursday, May 10, 2007
Hi Alex,

I hadn't thought of the offsetWidth of the text element !!
However, one issue is that the text wrap class adds a width:100% style to the text element.
So, offsetWidth of the text element can be used only when not using the text wrap class.

I did a quick check - with 10000 rows and virtual mode on, the hidden span method takes 6-7 secs to resize the column in FireFox.
Ankur Motreja
Thursday, May 10, 2007
Would it be faster to find the cell with max string length (number of characters) and only put this one string into the hidden span to measure the width?
Alex (ActiveWidgets)
Thursday, May 10, 2007
But that may not give the most accurate width.
For example, some sentences with more number of l's might have more characters than a sentence with a number of m's, but it could have a shorter width (since l is less wide than m)

In my app, the server paginates the data and sends it to the client.
So, I never have to deal with a dataset larger than 100 rows.

I guess it ultimately depends on each app as to which method is best.
If it is a large dataset, http://www.activewidgets.com/javascript.forum.14216.2/double-click-the-separator.html might be the best.
Alternately, the string with the maximum characters can be put into the hidden span to get more accurate results than a purely character counting method.
If you are sure of a small dataset, the hidden span method can be used for maximum accuracy.
Its a trade off between a good user experience and max accuracy.
Ankur Motreja
Thursday, May 10, 2007

This topic is archived.


Back to support forum

Forum search