...

View Full Version : Putting reference to instance in onclick



exo
05-30-2006, 01:46 PM
Okay, sorry the title might be a bit vague but the deal is this.

I'm making a TABLE through the DOM. I have a class called DataGrid with a couple of properties

function DataGrid(table)
{
this.Table = table;
this.Columns = new Array();
this.Rows = new Array();
And some methods:


this.AddColumn = AddColumn;
this.AddRow = AddRow;
this.Build = Build;

AddColumn takes an object, with a number of properties to create the headers. These values are stored in the property Columns on the object instance.


var column1 = new Object();
column1["value"] = "Name";
column1["width"] = "200px";

var column2 = new Object();
column2["value"] = "Profession";
column2["width"] = "200px";
column2["classname"] = "end";
AddRow just uses an array with values, which will be stored in the property Rows on the object isntance. The method Build paints it on the screen with the DOM. So in order to create my table it goes a little bit like this:


DataGrid1 = new DataGrid(document.getElementById("tabelletje"));
DataGrid1.AddColumn(column1);
DataGrid1.AddColumn(column2);
DataGrid1.AddRow("Joe", "Student");
DataGrid1.AddRow("John", "Manager");
DataGrid1.Build();



So far it works well, but now I want my tables to be resorted on another column, when the user click a column title. This part of the Build method paints the header cells:


function Build()
{
var objBody = document.createElement('TBODY');
var objHeaderRow = document.createElement("TR");// Adding header cells
for (var i = 0; i < this.Columns.length; i++)
{
var objCell = document.createElement("TH");
if (this.Columns.value)
objCell.innerHTML = this.Columns[i].value; // Value
if (this.Columns[i].classname)
objCell.className = this.Columns[i].classname; // Classname
if (this.Columns[i].width)
objCell.style.width = this.Columns[i].width; // Width
[i]objCell.onclick = new Function("", "sortColumn(??, " + i + ")");
objHeaderRow.appendChild(objCell);
}
objBody.appendChild(objHeaderRow);
this.Table.appendChild(objBody);


So what I want now, is a function sortColumn that goes a little bit like this:


function sortColumn(instance, columnNumber)
{
instance.Rows.sortRows(columnNumber);
instance.Build();
}


But I can't seem to be able to pass the instance to the DataGrid object through the onclick handler. Any suggestions are welcome. If I made any huge errors please correct me, I'm not entirely new to Javascript but this OO approach is posing some problems still.

Thanks in advance.

Beagle
05-30-2006, 03:22 PM
function createSortHandler(p_instance, p_index)
{
return function() { sortColumn(p_instance, p_index); };
}

function Build()
{
var objBody = document.createElement('TBODY');
var objHeaderRow = document.createElement("TR");// Adding header cells
for (var i = 0; i < this.Columns.length; i++)
{
var objCell = document.createElement("TH");
if (this.Columns[i].value)
objCell.innerHTML = this.Columns[i].value; // Value
if (this.Columns[i].classname)
objCell.className = this.Columns[i].classname; // Classname
if (this.Columns[i].width)
objCell.style.width = this.Columns[i].width; // Width
objCell.onclick = createSortHandler(this, i);
objHeaderRow.appendChild(objCell);
}

objBody.appendChild(objHeaderRow);
this.Table.appendChild(objBody);
}

exo
05-30-2006, 04:35 PM
That is so cool! Thank you very much Beagle it works like a charm :thumbsup:

I have one more question tho, hope I'm not asking too much. Besides sorting users must also be able to click on the rows itself, and a function must fire when they do.

That function should receive not only the reference to the instance of the DataGrid, but also a reference to the row the user was clicking on. That way I can set a property of the DataGrid reference, and change the className of the row the user clicked on. So the row changes apperance but the entire table doesnt have to be Build() again.

I haven't gotten this to work yet, I used to do


objRow.onclick = new Function("", "rowClick(arguments[0], this)");


But I can't get this to work when I try Beagle's approach. I hope I'm making some sense. The idea is to get this sort of function:


function rowClick(e, instance)
{
e.srcElement.className = "selectedRow";
instance.selectedRow = e.srcElement.rowNr;
}

Kor
05-30-2006, 04:43 PM
I guess that this is the correct approach

objCell.onclick = function(){somefunction(parameter)}

Kor
05-30-2006, 04:46 PM
and if you wanna use the index somehow, better attach it as a variable to the object

objCell.foo=i;
objCell.onclick = function(){somefunction(this,this.foo)}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum