Dropdown Grid Template
The following is a dropdown grid template I worked up. It basically works like a select template but using a grid as the dropdown. You can specify the column that is used to populate the cell on the parent grid.
// ****************************************************************
// Grid Select Cell Template.
// ****************************************************************
My.Templates.GridSelect = Active.System.Control.subclass();
My.Templates.GridSelect.create = function()
{
var obj = this.prototype;
obj.defineModel("grid");
obj.defineGridProperty("count", 0);
obj.defineGridPropertyArray("rows", 0);
obj.defineGridPropertyArray("columns", 0);
obj.defineGridProperty("valuecolumn", 0);
obj.setClass("templates", "text");
obj.setContent("text", function(){return this.getItemProperty("text")});
function getAbsolutePos(el) {
var SL = 0, ST = 0;
var is_div = /^div$/i.test(el.tagName);
if (is_div && el.scrollLeft)
SL = el.scrollLeft;
if (is_div && el.scrollTop)
ST = el.scrollTop;
var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
if (el.offsetParent) {
var tmp = getAbsolutePos(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};
var template;
function switchToTextMode() {
var ddGridSpan = document.getElementById('ddGridSpan');
if(ddGridSpan) {
ddGridSpan.innerHTML='';
document.body.removeChild(ddGridSpan);
}
if(template) {
template.refresh();
template = null;
}
}
function switchToEditMode()
{
if(template) {
switchToTextMode();
}
template = this;
var grid = new Active.HTML.DIV;
grid.setId("ddgrid");
grid.setClass("templates", "ddgrid");
grid.setContent("grid", function() {
selectAction = function(src) {
selectedRow = src.getProperty("item/index");
var ddData = template.getGridProperty("rows");
template.setItemProperty("text",ddData[selectedRow][template.getGridProperty("valuecolumn")]);
switchToTextMode();
}
var ddGrid = new Active.Controls.Grid;
var ddColumns = template.getGridProperty("columns");
var ddData = template.getGridProperty("rows");
var row = ddGrid.getTemplate("row");
row.setEvent("ondblclick", function(){ this.action("selectAction"); } );
ddGrid.setId("ddGrid");
ddGrid.setAction("selectAction", selectAction);
ddGrid.setRowProperty("count", ddData.length);
ddGrid.setColumnProperty("count", ddColumns.length);
ddGrid.setColumnProperty("text", function(i){return ddColumns[i]});
ddGrid.setRowHeaderWidth("0px");
ddGrid.setColumnHeaderHeight("20px");
ddGrid.getDataText = function(i, j){ return ddData[i][j]; };
ddGrid.setStyle("background-color", "white");
return ddGrid.toString();
}
);
var ddGridSpan = document.getElementById('ddGridSpan');
if(!ddGridSpan) {
ddGridSpan = document.createElement('span');
ddGridSpan.id = 'ddGridSpan';
document.body.appendChild(ddGridSpan);
}
// rigged to capture mousedown events on the grid owning this template. probably a better way to do this.
this.element().parentNode.parentNode.parentNode.onmousedown = switchToTextMode;
ddGridSpan.innerHTML=grid;
var el = template.element();
var pos = getAbsolutePos(el);
grid.setStyle("left", pos.x);
grid.setStyle("top", pos.y + el.offsetHeight);
grid.setStyle("visibility", "visible");
}
obj.setEvent("onfocus", switchToEditMode);
};
My.Templates.GridSelect.create();
Then the CSS:
#ddgrid .active-controls-grid {height: 200; width: 160;}
#ddgrid .active-column-0 {width: 80px;}
#ddgrid .active-column-1 {width: 80px;}
#ddgrid .active-grid-column {border-right: 1px solid threedlightshadow;}
And an example:
var ddGridTemplate = new My.Templates.GridSelect;
ddGridTemplate.setGridProperty("rows", [['0001','Test 1'],['0002','Test 2'],['0003','Test 3']]);
ddGridTemplate.setGridProperty("columns", ["Code", "Name"]);
ddGridTemplate.setGridProperty("valuecolumn", 0);
obj.setColumnTemplate(ddGridTemplate,0);
For some reason column sorting is not working on the dropdown grid in IE. It works fine in Firefox though.
// ****************************************************************
// Grid Select Cell Template.
// ****************************************************************
My.Templates.GridSelect = Active.System.Control.subclass();
My.Templates.GridSelect.create = function()
{
var obj = this.prototype;
obj.defineModel("grid");
obj.defineGridProperty("count", 0);
obj.defineGridPropertyArray("rows", 0);
obj.defineGridPropertyArray("columns", 0);
obj.defineGridProperty("valuecolumn", 0);
obj.setClass("templates", "text");
obj.setContent("text", function(){return this.getItemProperty("text")});
function getAbsolutePos(el) {
var SL = 0, ST = 0;
var is_div = /^div$/i.test(el.tagName);
if (is_div && el.scrollLeft)
SL = el.scrollLeft;
if (is_div && el.scrollTop)
ST = el.scrollTop;
var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
if (el.offsetParent) {
var tmp = getAbsolutePos(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};
var template;
function switchToTextMode() {
var ddGridSpan = document.getElementById('ddGridSpan');
if(ddGridSpan) {
ddGridSpan.innerHTML='';
document.body.removeChild(ddGridSpan);
}
if(template) {
template.refresh();
template = null;
}
}
function switchToEditMode()
{
if(template) {
switchToTextMode();
}
template = this;
var grid = new Active.HTML.DIV;
grid.setId("ddgrid");
grid.setClass("templates", "ddgrid");
grid.setContent("grid", function() {
selectAction = function(src) {
selectedRow = src.getProperty("item/index");
var ddData = template.getGridProperty("rows");
template.setItemProperty("text",ddData[selectedRow][template.getGridProperty("valuecolumn")]);
switchToTextMode();
}
var ddGrid = new Active.Controls.Grid;
var ddColumns = template.getGridProperty("columns");
var ddData = template.getGridProperty("rows");
var row = ddGrid.getTemplate("row");
row.setEvent("ondblclick", function(){ this.action("selectAction"); } );
ddGrid.setId("ddGrid");
ddGrid.setAction("selectAction", selectAction);
ddGrid.setRowProperty("count", ddData.length);
ddGrid.setColumnProperty("count", ddColumns.length);
ddGrid.setColumnProperty("text", function(i){return ddColumns[i]});
ddGrid.setRowHeaderWidth("0px");
ddGrid.setColumnHeaderHeight("20px");
ddGrid.getDataText = function(i, j){ return ddData[i][j]; };
ddGrid.setStyle("background-color", "white");
return ddGrid.toString();
}
);
var ddGridSpan = document.getElementById('ddGridSpan');
if(!ddGridSpan) {
ddGridSpan = document.createElement('span');
ddGridSpan.id = 'ddGridSpan';
document.body.appendChild(ddGridSpan);
}
// rigged to capture mousedown events on the grid owning this template. probably a better way to do this.
this.element().parentNode.parentNode.parentNode.onmousedown = switchToTextMode;
ddGridSpan.innerHTML=grid;
var el = template.element();
var pos = getAbsolutePos(el);
grid.setStyle("left", pos.x);
grid.setStyle("top", pos.y + el.offsetHeight);
grid.setStyle("visibility", "visible");
}
obj.setEvent("onfocus", switchToEditMode);
};
My.Templates.GridSelect.create();
Then the CSS:
#ddgrid .active-controls-grid {height: 200; width: 160;}
#ddgrid .active-column-0 {width: 80px;}
#ddgrid .active-column-1 {width: 80px;}
#ddgrid .active-grid-column {border-right: 1px solid threedlightshadow;}
And an example:
var ddGridTemplate = new My.Templates.GridSelect;
ddGridTemplate.setGridProperty("rows", [['0001','Test 1'],['0002','Test 2'],['0003','Test 3']]);
ddGridTemplate.setGridProperty("columns", ["Code", "Name"]);
ddGridTemplate.setGridProperty("valuecolumn", 0);
obj.setColumnTemplate(ddGridTemplate,0);
For some reason column sorting is not working on the dropdown grid in IE. It works fine in Firefox though.
Austin Mayberry
February 8,