3.2.0

Grid customizer popup

The following is the code for a grid customizer that will let you select which columns will be display for a grid as well as the grid column widths:

<html>
<head>
<link href="css/grid/xp/grid.css" rel="stylesheet" type="text/css" ></link>
<script src="js/grid/grid.js"></script>
<style>
.active-controls-grid {font: menu; height: 280;}
.active-column-0 {width: 200px; vertical-align: middle;}
.active-column-1 {width: 50px; vertical-align: middle;}
.active-column-2 {width: 50px; vertical-align: middle;}
.active-grid-column {border-right: 1px solid threedlightshadow;}
.active-grid-row {border-bottom: 1px solid threedlightshadow;}

.active-templates-input {
overflow: hidden;
height: 100%;
padding: 0px 5px;
margin: -1px 0px;
border: 1px solid #666;
vertical-align: middle;
font: menu;
line-height: 1.4em;
}

.active-templates-input.gecko {
display: block;
margin: 0px;
}

.active-input-checkbox {
overflow: hidden;
width: 100%;
height: 100%;
padding: 0px 5px;
margin: 0px 0px 1px 0px;
vertical-align: middle;
}
</style>
</head>

<body>
<div id="columnGrid"></div>
<input type="button" onclick="toggleColumns()" value="Save"><input type="button" onclick="window.close()" value="Cancel">
</body>
<script>
if (!window.My) My=[];
if (!My.Templates) My.Templates=[];

// ****************************************************************
// Input Cell Template.
// ****************************************************************
My.Templates.Input = Active.Templates.Text.subclass();

My.Templates.Input.create = function()
{
var obj = this.prototype;

// editor is not part of the template,
// there is only one single instance of editor object.
var editor = new Active.HTML.INPUT;
editor.setClass("templates", "input");
editor.setAttribute("type", "text");
editor.setAttribute("value", function(){
return template.getItemProperty("text");
});

// template variable provides temporary reference
// to the parent template during edit mode.
var template;

function switchToEditMode(){
if (template) {
switchToTextMode()
}
template = this;
template.element().style.padding = 0;
template.element().innerHTML = editor;
editor.element().focus();
editor.setEvent("ondblclick", switchToTextMode);
}

obj.setEvent("onfocus", switchToEditMode);

function switchToTextMode(){
var value = editor.element().value;
var originalText = template.getItemProperty("text");
if(originalText != value) {
template.setItemProperty("text",value);
template.refresh();
template.action("changeInputAction");
}
else {
template.refresh();
}
template = null;
}

editor.setEvent("onblur", switchToTextMode);
};

My.Templates.Input.create();


// ****************************************************************
// Checkbox Cell Template.
// ****************************************************************

My.Templates.Checkbox = Active.System.Control.subclass();

My.Templates.Checkbox.create = function(){

var obj = this.prototype;

obj.defineModel("checked");
obj.defineCheckedProperty("true", "Y");
obj.defineCheckedProperty("false", "N");

obj.setClass("templates","checkbox");

var checkbox = new Active.HTML.INPUT;
checkbox.setClass("input","checkbox");
checkbox.setClass("checkbox", function(){return this.getColumnProperty("index")});
checkbox.setAttribute("type","checkbox");
checkbox.setAttribute("checked", function(){
return (this.getItemProperty("text") == this.getCheckedProperty("true"))
});

function toggleValue(){
var originalVal = this.getItemProperty("text");
var newValue = (originalVal == this.getCheckedProperty("true")) ? this.getCheckedProperty("false") : this.getCheckedProperty("true");
this.setItemProperty("text", newValue);
this.refresh();
}

checkbox.setEvent("onclick", toggleValue);

obj.setContent("checkbox", checkbox);

};

My.Templates.Checkbox.create();
</script>
<script>
var columnGrid = new Active.Controls.Grid;
var columnGridColumns = ["Field","Visible","Width"];
var grid;
var currentWidths;

columnGrid.getDataText = function(i, j){
if(j==0) return grid.getColumnProperty("text",i);
else if(j==1) {
if(currentWidths[i]==0) return "No";
else return "Yes";
}
else if(j==2) {
if(currentWidths[i]==0) return 80; // substitute default widths loaded from db
else return currentWidths[i];
}
};
columnGrid.setDataText = function(value, i, j){
if(j==1) {
if(value=="No") currentWidths[i]=0;
else if(currentWidths[i]==0) currentWidths[i]=80; // substitute default widths loaded from db
}
else if(j==2) currentWidths[i] = value;
};
columnGrid.setColumnProperty("count", 3);
columnGrid.setRowHeaderWidth("0px");
columnGrid.setColumnHeaderHeight("20px");

var chkTemplate = new My.Templates.Checkbox;
chkTemplate.setCheckedProperty("true", "Yes")
chkTemplate.setCheckedProperty("false", "No")
columnGrid.setColumnTemplate(chkTemplate,1);

var widthTemplate = new My.Templates.Input;
columnGrid.setColumnTemplate(widthTemplate,2);

function setGrid(obj) {
grid = obj;

currentWidths = [];
var ss = opener.document.styleSheets[opener.document.styleSheets.length-1];
var selector = "#" + obj.getId() + " .active-column-";
var j=0;
for(i=0; i<ss.rules.length;i++){
if(ss.rules[i].selectorText == (selector+j)){
currentWidths[j] = ss.rules[i].style.width.substring(0,ss.rules[i].style.width.length-2);
j++;
}
}
// window["defaultWidths"] = (load these from database based on obj.getId())
columnGrid.setRowProperty("count", grid.getColumnProperty("count"));
columnGrid.setColumnProperty("text", function(i){return columnGridColumns[i]});
document.getElementById("columnGrid").innerHTML = columnGrid.toString();
}
window["setGrid"] = setGrid;

function toggleColumns() {
var ss = opener.document.styleSheets[opener.document.styleSheets.length-1];
var selector = "#" + grid.getId() + " .active-column-";
var j=0;
for(i=0; i<ss.rules.length;i++){
if(ss.rules[i].selectorText == (selector+j)){
if(columnGrid.getDataText(j,1)=="Yes") {
ss.rules[i].style.width = columnGrid.getDataText(j,2);
ss.rules[i].style.borderRight = "1px solid threedlightshadow";
}
else {
ss.rules[i].style.width = 0;
ss.rules[i].style.borderRight = "0px"; //firefox leaves the border behind
}
j++;
}
}
// save preferences to db
window.close();
}
</script>
</html>

and the calling code:

<script>
function gridCustomizer(obj) {
var gc = window.open(
'gridCustomizer.htm',
'', 'dependent,location=no,toolbar=no,resizable=no,scrollbars=no,width=340,height=330'
);
if(gc.attachEvent) gc.attachEvent('onload',function(){gc.setGrid(obj);});
else if(gc.addEventListener) gc.addEventListener('load',function(){gc.setGrid(obj);},false);
}
</script>
<input type="button" onclick="gridCustomizer(obj)" value="Customize Grid">

Where 'obj' is the grid to be customized. It could easily be changed to let the user edit the column names of the grid as well. There is an example at http://www.poeticdata.com/griddemo
Austin Mayberry
February 16,
Sorry, the demo is at http://www.poeticdata.com/griddemo with no trailing [/i]
Austin Mayberry
February 16,
This is very useful stuff - many people were asking how to make this feature. Thanks a lot, Austin! And great job again.

(P.S. I have corrected the link)
Alex (ActiveWidgets)
February 16,
I have made additions to the demo to allow for the ability to change header labels and reorder columns. If anyone is interested.
Austin Mayberry
February 17,
Of course we're interested you silly little man :D
AcidRaZor
February 18,
Really cool demo Austin. It really showcases the possibilities with this excellent grid.
Do you think it could be readily modified to use a select instead of a grid as the cell editor (column 2 in the sample)?
Chris Whelan
February 19,
I have added this to the demo now. I already had the template in my code from another posting. I just didn't have it included as a column.
Austin Mayberry
February 21,
hello

i'm using IE6 and when i click on a checkbox, i get the following error "object does not support property or method"

ths problem comes from this :
this.setItemProperty("text", newValue);

(in the toggleValue function of the checkbox template)

any idea ?

i create my checkbox with this code :

var columns = ["A_INTEGRER", "DATE_COMMANDE", "TR_PAYS", "SOCIETE", "NUM_COMMANDE", "ARTICLES_EN_STOCK"];
var obj = new Active.Controls.Grid;
obj.setColumnProperty("texts",columns);
var chkTemplate = new My.Templates.Checkbox;
chkTemplate.setCheckedProperty("true", "O");
chkTemplate.setCheckedProperty("false", "N");
obj.setColumnTemplate(chkTemplate,0);
document.write(obj);

(i fill my grid with a xml datamodel)

thx a lot
marco_from_france
February 24,
ok, i found out, i had only to implement the setText method for my table
marco from france
February 24,
can i save the grid on cookies for automatic relord when i come back on the page ?
June 10,
Hi Austin
I think the work on hiding the columns is great but my grid has 26 columns. I'd like users to be able to reduce the table width by hiding columns via a filter. I thought your script would do the job but I'm having problems getting it to work in a DIV so that I can still scroll the grid left to right if needed.
Alternatively a check box for each column on the grid itself would be good too.
Thanks
Annabel
June 21,
In the demo customize popup, the lower buttons appear below the box border, with the labels completely hidden, and the box is not set resizable. I'm using IE6, 1400x1050 display at "smaller" text display.
Byron
June 26,
anybody have the customizer working with 2.0?
Ryan
December 12,
Shouldn't this become standard one day?
Lucas
December 13,
I hope so- I really need it to work!
Ryan
December 13,
Does anybody have the grid customizer working for version 2.0?
Javier Varela
March 15,

This topic is archived.

See also:


Back to support forum