02.09.2008, 13:35
|
Флудер
|
|
Регистрация: 25.07.2008
Сообщений: 1,271
|
|
смотри:
/*
SpreadSheet.js
*/
Array.prototype.search = function(search){
for(var i=0,l=this.length;i<l;i++)if(this[i]==search)return i;
return false;
}
/*
ЯЧЕЙКА ТАБЛИЦИ
*/
function cell(){
this.r = 0;
this.c = 0;
this.parent = null;
this.value = '';
this.borderColor = '#7F9DB9';
this.borderWidth = '1';
this.defaultStyle = function(){
this.borderColor = '#7F9DB9';
this.borderWidth = '1';
}
this.activeStyle = function(){
this.borderColor = '#000000';
this.borderWidth = '3';
}
this.setAutoCompleter = function(url){}
this.findTableCell = function(r,c){
var t = this.parent._obj.getElementsByTagName('TABLE');
return t[t.length-1].getElementsByTagName('TR')[this.r-1].getElementsByTagName('TD')[this.c-1];
}
}
/*
ТАБЛИЦА
*/
function sheet(obj){
return {
row:1,
col:1,
cells:[], // хеш массив ячеек
_obj:obj,
cell:function(r,c){
var rCount=0,cCount=0;
while(this.cells.length < r){
this.cells.push([]);
rCount = this.cells.length - 1;
while(this.cells[rCount].length < c){
this.cells[rCount].push(new cell());
cCount = this.cells[rCount].length - 1;
this.cells[rCount][cCount].r = rCount+1;
this.cells[rCount][cCount].c = cCount+1;
this.cells[rCount][cCount].parent = this;
}
}
return this.cells[r-1][c-1];
},
moveTo:function(r,c){
var t = this;
if(r<1 || c<1 || r>t.cells.length || c>t.cells[0].length) return;
t.cell(t.row,t.col).defaultStyle();
t.updateCell(t.row,t.col);
t.cell(r,c).activeStyle();
t.updateCell(r,c);
t.row=r;
t.col=c;
},
updateCell:function(r,c){
var input = this.Table.rows[r-1].cells[c-1].firstChild;
var C = this.cell(r,c);
input.style.borderWidth = C.borderWidth;
input.style.borderColor = C.borderColor;
if(''!=input.value && input.value!=C.value)
C.value = input.value;
input.value = C.value;
input.focus();
},
show:function(){
var t=[],i=0,currenCell;
t[i++] = '<table cellspacing=0 cellpadding=0 class="Table">';
var rCount = this.cells.length;
var cCount = this.cells[0].length;
var tt = this;
var OnKeyDown = function(e){
e=e||event;
switch(e.keyCode||e.charCode){
case 37: tt.moveTo(tt.row,tt.col-1); break; // move left
case 38: tt.moveTo(tt.row-1,tt.col); break; // move up
case 39: tt.moveTo(tt.row,tt.col+1); break; // move right
case 40: tt.moveTo(tt.row+1,tt.col); break; // move down
}
}
t[i++] = '<tr>';
var h = this.Header.rows[0];
for(var c=0; c<cCount; c++){
currenCell = this.cells[0][c];
t[i++] = '<td style="width:'+h.cells[c].offsetWidth+'px;"></td>';
}
t[i++] = '</tr>';
for(var r=1; r<rCount; r++){
t[i++] = '<tr>';
for(var c=0; c<cCount; c++){
currenCell = this.cells[r][c];
t[i++] = '<td></td>';
}
t[i++] = '</tr>';
}
t[i++] = '</table>';
this._obj.lastChild.innerHTML = t.join("");
this.Table = this._obj.lastChild.firstChild;
this.Table.style.width = this.Header.offsetWidth;
window.onunload = function(){tt.cleanUp(tt)};
},
addHeaders:function(labelsList){ // labelList format: {name1:isSortable,name2:isSortable}
var labels = [],h = [],k=0;
for(var key in labelsList)
labels.push({name:key,isSortable:labelsList[key]});
var rCount = this.cells[0].length;
var cCount = this.cells.length;
var t = this._obj;
h[k++] = '<div><table cellspacing="0" cellpadding="0"><tr>';
for(var i=0;i<rCount;i++){
h[k++] = '<td>';
if(i<labels.length){
if(labels[i].isSortable){
h[k++] = '<select style="background:#99CCFF;"><option>'+labels[i].name+'</option>';
var options=[];
for(var j=0;j<cCount;j++){
var v = this.cells[j][i].value;
if(false===options.search(v) && ''!=v){
options.push(v);
h[k++] = '<option value="'+v+'">'+v+'</option>';
}
}
h[k++] = '</select>';
}
else h[k++] = labels[i].name;
}
else h[k++] = ' ';
h[k++] = '</td>';
}
h[k++] = '</tr></table></div><br><div></div>';
t.innerHTML = h.join("");
this.Header = t.firstChild.firstChild;
},
getValueList:function(collIndex){
var list = [],v;
for(var i=0;i<this.cells.length;i++){
if(!list.toString().match(this.cells[i][collIndex].value)){
v = this.cells[i][collIndex].value;
list.push('<option value="' + v +'">' + v + '</option>');
}
}
return list.join('');
},
cleanUp:function(tt){
// избегаем утечку памяти в Microsoft Internet Explorer
for(var i=0;i<tt.cells.length;i++){
for(var j=0;j<tt.cells[0].length;j++){
tt.cells[i][j].parent=null;
if(tt.cells[i][j].AutoCompleter){
tt.cells[i][j].AutoCompleter = null;
}
}
}
var inp = document.getElementsByTagName('INPUT');
for(var l=0;l<inp.length;l++){
inp[l].onclick = inp[l].onkeydown = null;
}
}
};
}
<html>
<head>
<style>
.Table {
border-collapse:collapse;
}
.Table td {
border:1px solid #7F9DB9;
height:18px;
}
</style>
</head>
<body>
<script type="text/javascript" src="sheet.js"></script>
<div id="SpreadSheet" align="center"></div>
<script>
var b = new Date();
var s = new sheet(document.getElementById('SpreadSheet'));
s.cell(800,14);
s.addHeaders({'Адрес установки':1,'Дом':1,'Под':1,'Switch':1,'IP адрес':1,'serial sw':1,'модуль':1,'1 модуль':1,'2 модуль':1,'Заказан':1,'Подготовлен':1,'Выдан':1,'Установлен':1,'Пометки':1});
s.show();
alert(((new Date()) - b)/1000);
</script>
</body>
</html>
Осталось только:
1) повесить обработку событий на саму таблицу (то есть обработчик будет всего один)
2) Завести один инпут (он будет редактировать значение текущей ячейки)
|
|
02.09.2008, 17:13
|
Интересующийся
|
|
Регистрация: 01.09.2008
Сообщений: 18
|
|
Переписал генерацию таблицы и шапки на php, щас буду писать обработчики событий для перемещающегося INPUT. Что посоветуеш сделать ? removeChild INPUT из старой ячейки и appendChild INPUT в новую ? Или может сделать position:absolute и перемещать координаты INPUT? Мне вообщето больше второй вариант нравится.
<html>
<head>
<style>
.SpreadSheet{border-collapse:collapse;}
.SpreadSheet td {border:1px solid #7F9DB9;height:18px;}
.SpreadSheet select{background:#99CCFF;}
</style>
</head>
<body>
<table class="SpreadSheet" id="3482624id"><th><select name="street"><option value="Адрес установки">Адрес установки</option><option value="Лесная">Лесная</option></select></th><th><select name="home"><option value="Дом">Дом</option><option value="25">25</option><option value="26">26</option></select></th><th><select name="porch"><option value="Под">Под</option><option value="1 подвал">1 подвал</option><option value="3 подвал">3 подвал</option></select></th><th><select name="dev_desc"><option value="Switch">Switch</option><option value="DES-3526">DES-3526</option></select></th><th><select name="IP"><option value="IP адрес">IP адрес</option><option value="10.100.40.28">10.100.40.28</option><option value="10.100.40.29">10.100.40.29</option></select></th><th><select name="serial_sw"><option value="serial sw">serial sw</option><option value="00-1C-F0-0F-9A-63">00-1C-F0-0F-9A-63</option><option value="00-1C-F0-0F-9A-9F">00-1C-F0-0F-9A-9F</option></select></th><th><select name="module0"><option value="модуль">модуль</option><option value="DEM-310GT V.D1">DEM-310GT V.D1</option></select></th><th><select name="module1"><option value="1 модуль">1 модуль</option><option value="E60N176001096">E60N176001096</option><option value="E60N176001091">E60N176001091</option></select></th><th><select name="module2"><option value="2 модуль">2 модуль</option><option value="E60N176001099">E60N176001099</option><option value="E60N176002084">E60N176002084</option></select></th><th><select name="orderDate"><option value="Заказан">Заказан</option><option value="39595">39595</option></select></th><th><select name="readyDate"><option value="Подготовлен">Подготовлен</option><option value="39597">39597</option></select></th><th><select name="givenDate"><option value="Выдан">Выдан</option><option value="39601">39601</option></select></th><th><select name="mountedDate"><option value="Установлен">Установлен</option><option value="39606">39606</option></select></th><tr><td>Лесная</td><td>25</td><td>1 подвал</td><td>DES-3526</td><td>10.100.40.28</td><td>00-1C-F0-0F-9A-63</td><td>DEM-310GT V.D1</td><td>E60N176001096</td><td>E60N176001099</td><td>39595</td><td>39597</td><td>39601</td><td>39606</td></tr><tr><td>Лесная</td><td>26</td><td>3 подвал</td><td>DES-3526</td><td>10.100.40.29</td><td>00-1C-F0-0F-9A-9F</td><td>DEM-310GT V.D1</td><td>E60N176001091</td><td>E60N176002084</td><td>39595</td><td>39597</td><td>39601</td><td>39606</td></tr></table> <script>
function sheet(objTable){
var _sheet = {
cell:document.createElement('INPUT'),
moveTo:function(row,coll){},
init:function(){
// ОБРАБОТЧИКИ СОБЫТИЙ ДЛЯ INPUT
}
};
_sheet.init();
return _sheet;
}
s = new sheet(document.getElementById('3482624id'));
</script></body>
</html>
|
|
02.09.2008, 17:33
|
Флудер
|
|
Регистрация: 25.07.2008
Сообщений: 1,271
|
|
Я думаю, что изменение таблицы будет вызывать нехилую перерисовку, так что надо минимизировать кол-во перерисовок таблицы. Соответственно, лучше в данном случае выглядит вариант с абсолютно спозиционированным инпутом, который находится ("летает") выше таблицы...
|
|
03.09.2008, 12:26
|
Интересующийся
|
|
Регистрация: 01.09.2008
Сообщений: 18
|
|
Я тут переписал свой код. Когда курсор на нижней строке и мы нажимаем вниз - добавляется новая строка. Но в опере текст который я туда записываю не отображается в таблице. В IE & FF, работает как надо. Как с этим бороться ?
<html>
<head>
<style>
.SpreadSheet{border-collapse:collapse;}
.SpreadSheet td {border:1px solid #7F9DB9;height:18px;}
.SpreadSheet select{background:#99CCFF;}
.SpreadSheetActivCell{border:3px #000000 solid;}
</style>
</head>
<body>
<table class="SpreadSheet" id="9394688id"><th><select name="street"><option value="Адрес установки">Адрес установки</option><option value="Землянского">Землянского</option><option value="Удмуртская">Удмуртская</option></select></th><th><select name="home"><option value="Дом">Дом</option><option value="9">9</option><option value="29">29</option></select></th><th><select name="porch"><option value="Под">Под</option><option value="2">2</option><option value="1">1</option></select></th><th><select name="dev_desc"><option value="Switch">Switch</option><option value="DES-3526">DES-3526</option></select></th><th><select name="IP"><option value="IP адрес">IP адрес</option><option value="10.102.32.13">10.102.32.13</option><option value="10.108.12.233">10.108.12.233</option></select></th><th><select name="serial_sw"><option value="serial sw">serial sw</option><option value="PL0A175001634">PL0A175001634</option><option value="PL0A175001635">PL0A175001635</option></select></th><th><select name="module0"><option value="модуль">модуль</option><option value="DEM-310GT V.D1">DEM-310GT V.D1</option></select></th><th><select name="module1"><option value="1 модуль">1 модуль</option><option value="E60N164003935">E60N164003935</option><option value="E60N166003929">E60N166003929</option></select></th><th><select name="module2"><option value="2 модуль">2 модуль</option><option value="E60N164004518">E60N164004518</option><option value="E60N164005657">E60N164005657</option></select></th><th><select name="orderDate"><option value="Заказан">Заказан</option><option value="39358">39358</option></select></th><th><select name="readyDate"><option value="Подготовлен">Подготовлен</option><option value="39358">39358</option></select></th><th><select name="givenDate"><option value="Выдан">Выдан</option><option value="39360">39360</option></select></th><th><select name="mountedDate"><option value="Установлен">Установлен</option><option value="39384">39384</option></select></th><tr><td>Землянского</td><td>9</td><td>2</td><td>DES-3526</td><td>10.102.32.13</td><td>PL0A175001634</td><td>DEM-310GT V.D1</td><td>E60N164003935</td><td>E60N164004518</td><td>39358</td><td>39358</td><td>39360</td><td>39384</td></tr><tr><td>Удмуртская</td><td>29</td><td>1</td><td>DES-3526</td><td>10.108.12.233</td><td>PL0A175001635</td><td>DEM-310GT V.D1</td><td>E60N166003929</td><td>E60N164005657</td><td>39358</td><td>39358</td><td>39360</td><td> </td></tr></table> <script>
function sheet(objTable){
var _sheet = {
rowIndex:null,
collIndex:null,
cell:document.createElement('INPUT'),
_objTable:objTable,
moveTo:function(row,coll){
try{
this.save();
var rowMax = this._objTable.rows.length-1; // число рядов
var collMax = this._objTable.rows[1].cells.length; // число колонок
//if(undefined==row || undefined==coll) return false;
if(coll>collMax)coll=collMax; // проверяем чтобы не вылететь за граници таблицы
if(row>rowMax)row=rowMax; // проверяем чтобы не вылететь за граници таблицы
if(row<1)row=1 // проверяем чтобы не вылететь за граници таблицы
if(coll<1)coll=1 // проверяем чтобы не вылететь за граници таблицы
this.rowIndex = row;
this.collIndex = coll;
coll--;
cell = this._objTable.rows[row].cells[coll];
var position = pos(cell);
this.cell.style.top =position[0];
this.cell.style.left =position[1];
this.cell.style.width =cell.clientWidth;
this.cell.style.height =cell.clientHeight;
this.cell.value =cell.firstChild.nodeValue;/**/
}catch(e){
alert(e);
return false;
}
return true;
},
save:function(){
if(null==this.rowIndex || null==this.collIndex ||
undefined==this.rowIndex || undefined==this.collIndex
)
return;
var cell = this._objTable.rows[this.rowIndex].cells[this.collIndex-1];
if(this.cell.value!=cell.firstChild.nodeValue){
cell.firstChild.nodeValue = this.cell.value;
}
},
addRow:function(){
maxColl = this._objTable.rows[1].cells.length+1;
var td,tr = document.createElement('TR');
tbody = this._objTable.rows[1].parentNode;
tbody.appendChild(tr);
for(i=0;i<maxColl;i++){
td = document.createElement('TD');
tr.appendChild(td);
td.appendChild(document.createTextNode(''));
}
//this.moveTo(this.rowIndex+1,this.collIndex);
//this.cell.focus();
tr=td=maxColl=null;
},
init:function(){
// ОБРАБОТЧИКИ СОБЫТИЙ ДЛЯ INPUT
this.cell.style.position='absolute';
document.body.appendChild(this.cell);
this.cell.className='SpreadSheetActivCell';
this.cell.autocompliter='off';
var tt = this;
this.cell.onkeydown = function(e){
lastCellIndex = tt._objTable.rows.length-1;
e=e||event;
switch(e.keyCode||e.charCode){
case 37: tt.moveTo(tt.rowIndex,tt.collIndex-1); break; // move left
case 38: tt.moveTo(tt.rowIndex-1,tt.collIndex); break; // move up
case 39: tt.moveTo(tt.rowIndex,tt.collIndex+1); break; // move right
case 40: if(tt.rowIndex+1>lastCellIndex){tt.addRow();}tt.moveTo(tt.rowIndex+1,tt.collIndex); break; // move down
}
}
objTable.onclick = function(e){
e=e||event;
sorce = e.srcElement || e.target;
var row = sorce.parentNode.rowIndex
var coll= sorce.cellIndex+1;
if(!tt.moveTo(row,coll))return;
tt.cell.focus();
};
this.moveTo(1,1);
this.cell.focus();
}
};
_sheet.init();
return _sheet;
}
s = new sheet(document.getElementById('9394688id'));
function pos(obj){
var x=0,y=0;
do{
x += obj.offsetTop;
y += obj.offsetLeft;
}while(obj=obj.offsetParent)
return [x,y];
}
</script></body>
</html>
|
|
03.09.2008, 12:43
|
Флудер
|
|
Регистрация: 25.07.2008
Сообщений: 1,271
|
|
У меня в опере всё ОК
|
|
05.09.2008, 11:13
|
Интересующийся
|
|
Регистрация: 01.09.2008
Сообщений: 18
|
|
Наверное глупый вопрос, но всёже.... Как можно передать большой кусок html в функцию на JavaScript. В строку просто так не запихнёш - надо экранировать кавычки пробелы удалять. Я ничё лучше не придумал:
<div style="display:none" id="content123">сюда я помещаю весь текст<br><hr> и тд.</div>
<script>
function foo(content){
alert(content);
}
foo(document.getElementsById('content123').innerHTML);
</script>
|
|
05.09.2008, 11:16
|
Флудер
|
|
Регистрация: 25.07.2008
Сообщений: 1,271
|
|
и чем тебе это не нравится?
|
|
05.09.2008, 11:20
|
Интересующийся
|
|
Регистрация: 01.09.2008
Сообщений: 18
|
|
коряво как то)
|
|
05.09.2008, 11:44
|
Флудер
|
|
Регистрация: 25.07.2008
Сообщений: 1,271
|
|
сам ты корявый...
|
|
06.09.2008, 19:57
|
Новичок на форуме
|
|
Регистрация: 19.02.2008
Сообщений: 9,177
|
|
Сообщение от ZoNT
|
и чем тебе это не нравится?
|
Ну, например, если в коде будет <img src="1.gif" />, то в скрипт придет <img src="1"> (как минимум в FF). Уж лучше тогда в textarea пихать. А лучше все-таки экранировать все нужное.
|
|
|
|