смотри:
/* 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) Завести один инпут (он будет редактировать значение текущей ячейки) |
Переписал генерацию таблицы и шапки на 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> |
Я думаю, что изменение таблицы будет вызывать нехилую перерисовку, так что надо минимизировать кол-во перерисовок таблицы. Соответственно, лучше в данном случае выглядит вариант с абсолютно спозиционированным инпутом, который находится ("летает") выше таблицы...
|
Я тут переписал свой код. Когда курсор на нижней строке и мы нажимаем вниз - добавляется новая строка. Но в опере текст который я туда записываю не отображается в таблице. В 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> |
У меня в опере всё ОК
|
Наверное глупый вопрос, но всёже.... Как можно передать большой кусок html в функцию на JavaScript. В строку просто так не запихнёш - надо экранировать кавычки пробелы удалять. Я ничё лучше не придумал:
<div style="display:none" id="content123">сюда я помещаю весь текст<br><hr> и тд.</div> <script> function foo(content){ alert(content); } foo(document.getElementsById('content123').innerHTML); </script> |
и чем тебе это не нравится?
|
коряво как то)
|
сам ты корявый...
|
Цитата:
|
Часовой пояс GMT +3, время: 11:58. |