Показать сообщение отдельно
  #8 (permalink)  
Старый 02.09.2008, 12:54
Флудер
Отправить личное сообщение для ZoNT Посмотреть профиль Найти все сообщения от ZoNT
 
Регистрация: 25.07.2008
Сообщений: 1,271

Немного ускорил.
Но структура бредовая...
1) Зачем в каждую ячейку пихать инпут?
2) Зачем на каждый инпут(ячейку) вешать обработчик событий?

/*
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){
            if(r<1 || c<1 || r>this.cells.length || c>this.cells[0].length)
            return;
            with(this){
                cell(this.row,this.col).defaultStyle();
                cell(r,c).activeStyle();
                updateCell(this.row,this.col);
                updateCell(r,c);
                row=r;
                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 border="0">';
            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;"><input autocomplete="off" style="width:100%;border:'+ currenCell.borderWidth +'px '+currenCell.borderColor+' solid" value="'  + currenCell.value +  '"></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><input autocomplete="off" style="width:100%;border:'+ currenCell.borderWidth +'px '+currenCell.borderColor+' solid" value="'  + currenCell.value +  '"></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;
			
            var inputs = this._obj.getElementsByTagName('INPUT');
            var inpCount = inputs.length;
            for(var i=0;i<inpCount;i++){
                inputs[i].onclick= function(){
                    c = this.parentNode.cellIndex +1;
                    r = this.parentNode.parentNode.rowIndex +1;
                    tt.moveTo(r,c);
                };
                inputs[i].onkeydown = OnKeyDown;
            }
            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++] = '&nbsp;';
				
                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;
            }
        }
    };
}



Вызов addHeaders в html должен идти ПЕРЕД show()!!!

Последний раз редактировалось ZoNT, 02.09.2008 в 13:00.
Ответить с цитированием