Very simple example of grid
This is the very very rought HTML you would need to have a table with a static header. This has 500 itens on it and is quite light.
<html>
<body>
<div id="jsgrid" style="height:200;width:250;overflow:auto">
<div id="jsgrid_header" style="z-index:100;position:relative;top:0">
<table bgcolor="CCCCCC" width="400">
<tr>
<td width="200">header 1</td>
<td width="200">header 2</td>
</tr>
</table>
</div>
<div style="z-index:0;">
<table width="400">
<tbody id="jsgrid_body">
</tbody>
</table>
</div>
</div>
<script>
function obj_jsgrid_scroll()
{
obj_jsgrid_header = document.getElementById(this.id + "_header");
obj_jsgrid_header.style.top=this.scrollTop;
}
obj_jsgrid = document.getElementById("jsgrid");
obj_jsgrid.onscroll = obj_jsgrid_scroll;
obj_jsgrid_body = document.getElementById("jsgrid_body");
for (i=0; i < 500; i++)
{
trElem = document.createElement("tr");
tdElem1 = document.createElement("td");
tdElem2 = document.createElement("td");
str1 = document.createTextNode("teste "+i);
str2 = document.createTextNode("asdf "+i);
obj_jsgrid_body.appendChild(trElem);
trElem.appendChild(tdElem1);
trElem.appendChild(tdElem2);
tdElem1.appendChild(str1);
tdElem2.appendChild(str2);
}
</script>
</body>
</html>
Phackwer
March 8,
This is another code I did, much older (I was trying anything ;-)
This one has an edit option. You double click an item and it becomes a text input field. This one also has reorderable capabilities. Anyway, very old code. I can't show you the final version of the listview I created, because of legal issues (code do not belongs to me.
Have fun!
function editField(obj, bodyValuesName, bodyValues, i, j)
{
enableSelection();
obj = document.getElementById(obj);
content = "<input size='20' id=\"field" + bodyValuesName + "_" + i + "_" + j +"\" type='text' value=\"" + bodyValues[i][j] + "\" ";
content += "onBlur = \"" + bodyValuesName + "[" + i + "][" + j +"] = this.value;this_div=document.getElementById('" + obj.id + "');this_div.innerHTML = this.value; disableSelection();\"";
content += "onKeyDown = \"if(event.keyCode == 13){"+ bodyValuesName + "[" + i + "][" + j +"] = this.value;this_div=document.getElementById('" + obj.id + "');this_div.innerHTML = this.value; disableSelection();}\"> ";
obj.innerHTML = content;
field = document.getElementById("field" + bodyValuesName + "_" + i + "_" + j);
field.focus();
field.select();
}
March 8,
OOPS! Sorry, incomplete code. Check now.
<html>
<head>
<style type="text/css">
.listView
{
table-layout: fixed;
position: relative;
margin: 0px;
font-family: Verdana, Arial;
font-size: 10px;
highlightBackgroundColor: #C1D2EE;
highlightBorderColor: #316AC5;
cursor: default;
}
.listView THEAD TD
{
white-space: nowrap;
border-top: 1px solid white;
border-bottom: 1px solid black;
font-family: Verdana, Arial;
font-size: 10px;
background-color: buttonface;
cursor: hand;
padding-top: 0px;
padding-bottom: 1px;
height: 20px;
}
a
{
text-decoration:none;
}
input
{
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: normal;
font-size: 10px;
width:100%;
border: '1px solid #000000'
}
</style>
<script>
function drawListViewHeaders(tHead_obj_name, headerValues, imgsList, headerValuesName, imgsListName, listViewBodyName, listViewBodyValuesName)
{
tHead = document.getElementById(tHead_obj_name);
while (tHead.childNodes.length > 0)
{
tHead.removeChild(tHead.firstChild);
}
trElem = tHead.insertRow(tHead.rows.length);
for (i=0; i < headerValues.length; i++)
{
prevTdId = tHead.id + "_" + (i-1);
currentTdId = tHead.id + "_" + (i);
if (i != (headerValues.length - 1))
nextTdId = tHead.id + "_" + (i+1);
else
nextTdId = tHead.id + "_" + (i-1);
tdElem = trElem.insertCell(trElem.cells.length);
tdElem.id = currentTdId;
tdWidth = (headerValues[i].length) * 10 + 30;
tdElem.width = tdWidth;
imgId = imgsList[i];
var tdcontent = "<div style='white-space:nowrap;position:inherit;' onClick=\"reorderListViewColumn(" + imgId + "," + i + ",'" + listViewBodyName + "', " + headerValuesName + ", " + listViewBodyValuesName + ", '" + listViewBodyValuesName + "');switchBtn('" + imgId + "'," + imgsListName + ")\">";
tdcontent += " " + headerValues[i] + "";
tdcontent += " <img id='" + imgId + "' src='images/down.gif' border='0' value='down'>";
tdcontent += "</div>";
tdElem.innerHTML = tdcontent;
//acrescenta a barra de redimensionamento das colunas
tdRedimen = trElem.insertCell(trElem.cells.length);
tdRedimen_id = "redimbar" + tHead.id + "_" + i;
tdRedimen.width = 5;
tdRedimen.style.cursor = "w-resize";
tdRedimen.style.backgroundImage = "url(images/handler.gif)";
tdRedimen.style.backgroundRepeat = "no-repeat";
tdRedimen.style.backgroundPosition = "right";
tdRedimen.innerHTML = " ";
tdRedimen.currTdId = currentTdId;
};
}
/*********************************************************************************
FUNCOES DE RESIZE DO HEADER
*********************************************************************************/
//Variaveis globais acessiveis pelas funcoes de ressampler
var beginXpos;
var endXpos;
var curr_obj = null;
function beginDrag(e)
{
if (!e) var e = window.event;
//Pega a posicaum inicial do mouse
if (e.clientX)
beginXpos = (e.clientX + document.body.scrollLeft);
else
beginXpos = (e.pageX + document.body.scrollLeft);
//Pega o ID das colunas redimensionada
if (e.target)
curr_obj = document.getElementById(e.target.currTdId);
else
curr_obj = document.getElementById(e.srcElement.currTdId);
return false;
}
function dragMove(e)
{
if (!e) var e = window.event;
if (curr_obj)
{
//Pega a posicaum final do mouse
if (e.clientX)
endXpos = (e.clientX + document.body.scrollLeft);
else
endXpos = (e.pageX + document.body.scrollLeft);
//subtrae o valor da nova posicaum da posicaum antiga para saber qto mover
size = parseInt(endXpos) - parseInt(beginXpos);
//Largura das colunas a serem alteradas
curr_width = parseInt(curr_obj.width);
//Atualiza tamanho da coluna redimensionada
if ((curr_width + size)>0)
curr_obj.width = (curr_width + size);
//Iguala a posicaum de inicio com a nova, aguardando nova movimentacaum
beginXpos = endXpos;
return false;
}
}
function endDrag(e)
{
curr_obj = null;
return false;
}
function enableSelection()
{
document.onselectstart = new Function ("return true");
document.onmousedown = new Function ("return true");
}
function disableSelection()
{
document.onselectstart = new Function ("return false");
document.onmousedown = beginDrag;
}
document.onselectstart = new Function ("return false")
document.onmousedown = beginDrag;
document.onmousemove = dragMove;
document.onmouseup = endDrag;
/*********************************************************************************
FIM DAS FUNCOES
DE RESIZE
*********************************************************************************/
/*********************************************************************************
FUNCOES DE ORDENACAUM
*********************************************************************************/
//Variaveis exclusivas para reordenacaum
var scol;
//************ FUNCOES GENERICAS ***************
//Funcoes para reordenacaum das tabelas
function changeObjColor(obj, newColor)
{
obj.style.bgcolor=newColor;
}
function upsort(a,b)
{
if(a[scol] > b[scol])
return -1
if(a[scol] < b[scol])
return 1
return 0
}
function downsort(a,b)
{
if(a[scol] > b[scol])
return 1
if(a[scol] < b[scol])
return -1
return 0
}
function switchBtn(btn_obj, imgs)
{
btn = document.getElementById(btn_obj);
for (i=0; i < imgs.length; i++)
{
if (imgs[i] != btn.id)
{
img = document.getElementById(imgs[i]);
img.value='down';
img.src = 'images/' + img.value + '.gif';
}
}
if (btn.value == 'down' || btn.value == undefined)
{
btn.value = 'up';
btn.src = 'images/up_on.gif';
}
else
{
btn.value = 'down';
btn.src = 'images/down_on.gif';
}
}
//Ordena ao mesmo tempo que cria a tabela
function reorderListViewColumn(btn, col, tBody_obj, headerValues, bodyValues, bodyValuesName)
{
tBody = document.getElementById(tBody_obj);
scol = col;
//ordenar array
if ((btn.value == 'up')||(btn == 'undefined'))
func = upsort;
else
func = downsort;
bodyValues.sort(func);
while (tBody.childNodes.length > 0)
{
tBody.removeChild(tBody.firstChild);
}
for (i = 0; i < bodyValues.length; i++)
{
trElem = tBody.insertRow(tBody.rows.length);
for (j=0; j < headerValues.length; j++)
{
tdElem = trElem.insertCell(trElem.cells.length);
tdElem.innerHTML = "<div id='field_" + i + "_" + j + "' onDblClick='editField(this.id, \"" + bodyValuesName + "\", " + bodyValuesName + ", " + i + "," + j + ");' style='white-space:nowrap;position:inherit;'>" + bodyValues[i][j] + "</div>";
//acrescenta a barra de redimensionamento das colunas
tdRedimen = trElem.insertCell(trElem.cells.length);
if (i%2)
tdElem.style.backgroundColor = "#CCCCCC";
else
tdElem.style.backgroundColor = "#FFFFFF";
tdRedimen.style.backgroundColor = tdElem.style.backgroundColor;
}
};
}
function editField(obj, bodyValuesName, bodyValues, i, j)
{
enableSelection();
obj = document.getElementById(obj);
content = "<input size='20' id=\"field" + bodyValuesName + "_" + i + "_" + j +"\" type='text' value=\"" + bodyValues[i][j] + "\" ";
content += "onBlur = \"" + bodyValuesName + "[" + i + "][" + j +"] = this.value;this_div=document.getElementById('" + obj.id + "');this_div.innerHTML = this.value; disableSelection();\"";
content += "onKeyDown = \"if(event.keyCode == 13){"+ bodyValuesName + "[" + i + "][" + j +"] = this.value;this_div=document.getElementById('" + obj.id + "');this_div.innerHTML = this.value; disableSelection();}\"> ";
obj.innerHTML = content;
field = document.getElementById("field" + bodyValuesName + "_" + i + "_" + j);
field.focus();
field.select();
}
</script>
<script>
/****************************************************************************
ARRAYS DE VALORES
?nica parte que deve ser alimentada do c?digo
*****************************************************************************/
//Valores do cabecalho
var columnHeaderValues = new Array
(
"IP",
"Máquina",
"Acesso",
"Criado por"
)
//cria agora o array de imagens baseado no numero de colunas existentes
var listViewImgs = new Array();
for (i = 0 ; i < columnHeaderValues.length; i++)
{
listViewImgs[i] = "img" + "listViewHead" + "_" + i;
}
//Valores do corpo
var listViewBodyValues = new Array
(
new Array("10.0.0.10","qsersfdg sdfg sdfg sdfg ver.aker.com.br","Publico","admin"),
new Array("10.0.0.11","wserver.aker.com.br","Publico","usuario 1"),
new Array("10.0.0.12","eserver.aker.com.br","Reservado","admin"),
new Array("10.0.0.13","rserver.aker.com.br","Publico","usuario 1"),
new Array("10.0.0.14","tserver.aker.com.br","Reservado","usuario 2"),
new Array("10.0.0.15","yserver.aker.com.br","Publico","usuario 2"),
new Array("10.0.0.16","userver.aker.com.br","Reservado","admin"),
new Array("10.0.0.17","iserver.aker.com.br","Publico","usuario 2"),
new Array("10.0.0.18","oserver.aker.com.br","Reservado","usuario 1"),
new Array("10.0.0.19","pserver.aker.com.br","Publico","usuario 2")
);
</script>
</head>
<body topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">
<p>
<table class="listView" cellpadding=3 cellspacing=0>
<!-- Cabecalho do list view-->
<thead id="objListViewHead">
<tr>
<td>
</td>
</tr>
</thead>
<!-- Final do cabecalho -->
<!-- Corpo com lista dos itens -->
<tbody id="objListViewBody">
<tr>
<td>
</td>
</tr>
</tbody>
<!-- Fim do corpo -->
</table>
<script>
drawListViewHeaders('objListViewHead', columnHeaderValues, listViewImgs, 'columnHeaderValues', 'listViewImgs','objListViewBody', 'listViewBodyValues');
reorderListViewColumn(listViewImgs[0],0,'objListViewBody', columnHeaderValues, listViewBodyValues, 'listViewBodyValues');
switchBtn(listViewImgs[0], listViewImgs);
</script>
Phackwer
March 8,
Still throwing error messages :\
Colm Garvey
March 9,
what kind of messages? this is a very rought test, as I said. FInal version of my listview (works as grid and treeview) is much more complete, with editable fields, checkbox, combobox, listbox support, etc...
But for doing this, I had to work with 2 objects, instead of the one you have for grid.
One is the ListView. The other, the ListViewItem. Each row of the ListView is a ListViewItem. ListView has a childList (Array of ListViewItems objects) of it's rows. Each ListViewItem can also have a ListViewItem as child. This allow the treeview to exists throught a recursive function called closeTBosy, which goes throught the array of child lists checking also if the child has an child list and putting blank spaces in front of each grandchild of the listview, so you have the levels required in a treeview. If child has no children, you have the grid. ;-)
The ListViewItem supports the addition of Items throught the method called addItem. This method supports botch the addition of text as well as other Objects. You can them place a checkbox in a cell.
But until you do not work with two objects instead of one, as you do here, you won't have the chance to have a treeview. And it's quite stupid having two objects instead of one since grid is a treeview of one level.
The correct is really calling it a ListView as all other C/C++ libs do.
Here is an example of code using the objects I created (I can't not post the code for the objects, please, forgive me).
<script language="JavaScript" src="../js/akincludes.js"></script>
<script>
//Instancia todos os objetos a serem utilizados na janela
//cria janela
var mainwindow = new AkWindow;
//cria listview
var listview = new AkListView("listview", "lstv");
//Adiciona itens ao listview
var listviewroot = new AkListViewItem("listviewroot", "root", listview);
listviewroot.setopen = true;
var listviewitem1 = new AkListViewItem("listviewitem1", "parent0", listviewroot);
listviewitem1.setopen = true;
//os proximos dois itens saum subitens do primeiro, por isso passa-se o nome do parent
var listviewsubitem1 = new AkListViewItem("listviewsubitem1", "sub0", listviewitem1);
var listviewsubitem2 = new AkListViewItem("listviewsubitem2", "sub1", listviewitem1);
//Aqui volta para o root
var listviewitem2 = new AkListViewItem("listviewitem2", "parent1", listviewroot);
listviewitem2.setopen = true;
//Mais subitens
var listviewsubitem3 = new AkListViewItem("listviewsubitem3", "sub2", listviewitem2);
var listviewsubitem4 = new AkListViewItem("listviewsubitem4", "sub3", listviewitem2);
//root
var listviewitem3 = new AkListViewItem("listviewitem3", "parent2", listviewroot);
listviewitem3.setopen = true;
//Mais subitens
var listviewsubitem5 = new AkListViewItem("listviewsubitem5", "sub4", listviewitem3);
var listviewsubitem6 = new AkListViewItem("listviewsubitem6", "sub5", listviewitem3);
//Adiciona os cabecalhos do listview
listview.resizeable = true;
listview.reordable = true;
listview.width = "300";
listview.height = "100";
listview.addHeader("coluna 1",200);
listview.addHeader("coluna 2",200);
listview.addHeader("coluna 3",200);
listviewroot.addItem("SMTP Gateway");
listviewroot.addItem("");
listviewroot.addItem("");
//Adiciona objetos aas celulas da linha 1, que podem ser de qualquer tipo
//eh preciso passar a propriedade a ser impressa
//Pega automaticamente o icone do objeto passado e o value
listviewitem1.addItem("Servidores");
//Se nenhum objeto for passado, pega a string do ultimo argumento e imprime.
listviewitem1.addItem("Estes saum os servidores");
var combotest3 = new AkComboBox("combotest3","_combotest3");
//combotest3.value = "test1";
//combotest3.status = 'on';
combotest3.addComboItem("test1",null,null,true);
combotest3.addComboItem("test4");
listviewitem1.addObjItem(combotest3);
//Define que o item devera comecar como fechado, sem mostrar os childs (o padraum eh aberto)
//Adiciona objetos aas celulas da linha 1, que podem ser de qualquer tipo
//eh preciso passar a propriedade a ser impressa
//Pega automaticamente o icone do objeto passado e o value
listviewsubitem1.addItem("Servidor 1", "../images/serv_00.png");
listviewsubitem1.addItem("");
listviewsubitem1.addItem("");
//Se nenhum objeto for passado, pega a string do ultimo argumento e imprime.
listviewsubitem2.addItem("Servidor 2", "../images/serv_00.png");
listviewsubitem2.addItem("Descricaum do 2");
listviewsubitem2.addItem("");
listviewitem2.addItem("Dominios");
listviewitem2.addItem("Estes saum os dominios");
var combotest2 = new AkComboBox("combotest2","_combotest2");
//combotest2.value = "test2";
//combotest2.status = 'on';
combotest2.addComboItem("test3",null,null,true);
combotest2.addComboItem("test2");
listviewsubitem3.addItem("Dominio 1", "../images/domn_00.png");
listviewsubitem3.addItem("Descricaum do 3");
listviewsubitem3.addItem("");
listviewsubitem4.addItem("Dominio 2", "../images/domn_00.png");
listviewsubitem4.addItem("Descricaum do 4");
listviewsubitem4.addItem("");
listviewitem3.addItem("Regras");
listviewitem3.addItem("E estas saum as regras");
var combotest = new AkComboBox("combotest","_combotest");
//combotest.value = "test3";
//combotest.status = 'on';
combotest.addComboItem("test0",null,null,true);
combotest.addComboItem("test6");
listviewitem3.addObjItem(combotest);
listviewsubitem5.addItem("Regra 5", "../images/rbl_00.png");
listviewsubitem5.addItem("Descricaum do 3");
listviewsubitem5.addItem("");
listviewsubitem6.addItem("Regra 6", "../images/rbl_00.png");
listviewsubitem6.addItem("Descricaum do 4");
listviewsubitem6.addItem("");
mainwindow.output += "<p><br><br><br>";
mainwindow.addItem(listview);
mainwindow.bgcolor = "#FFFFFF";
mainwindow.drawWindow();
</script>
Comments are written in portuguese, but code is very Object Oriente, being quite easy to be read by OO Developers that created interfaces.
As I said before, I based my objects and its methods on the QT lib by TrollTech and I advice you guys to follow that line as well.
Phackwer
March 9,