Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 02.09.2008, 13:35
Флудер
Отправить личное сообщение для ZoNT Посмотреть профиль Найти все сообщения от ZoNT
 
Регистрация: 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++] = '&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;
            }
        }
    };
}


<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) Завести один инпут (он будет редактировать значение текущей ячейки)
Ответить с цитированием
  #12 (permalink)  
Старый 02.09.2008, 17:13
Интересующийся
Отправить личное сообщение для gagagogo Посмотреть профиль Найти все сообщения от gagagogo
 
Регистрация: 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>
Ответить с цитированием
  #13 (permalink)  
Старый 02.09.2008, 17:33
Флудер
Отправить личное сообщение для ZoNT Посмотреть профиль Найти все сообщения от ZoNT
 
Регистрация: 25.07.2008
Сообщений: 1,271

Я думаю, что изменение таблицы будет вызывать нехилую перерисовку, так что надо минимизировать кол-во перерисовок таблицы. Соответственно, лучше в данном случае выглядит вариант с абсолютно спозиционированным инпутом, который находится ("летает") выше таблицы...
Ответить с цитированием
  #14 (permalink)  
Старый 03.09.2008, 12:26
Интересующийся
Отправить личное сообщение для gagagogo Посмотреть профиль Найти все сообщения от gagagogo
 
Регистрация: 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>&nbsp;</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>
Ответить с цитированием
  #15 (permalink)  
Старый 03.09.2008, 12:43
Флудер
Отправить личное сообщение для ZoNT Посмотреть профиль Найти все сообщения от ZoNT
 
Регистрация: 25.07.2008
Сообщений: 1,271

У меня в опере всё ОК
Ответить с цитированием
  #16 (permalink)  
Старый 05.09.2008, 11:13
Интересующийся
Отправить личное сообщение для gagagogo Посмотреть профиль Найти все сообщения от gagagogo
 
Регистрация: 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>
Ответить с цитированием
  #17 (permalink)  
Старый 05.09.2008, 11:16
Флудер
Отправить личное сообщение для ZoNT Посмотреть профиль Найти все сообщения от ZoNT
 
Регистрация: 25.07.2008
Сообщений: 1,271

и чем тебе это не нравится?
Ответить с цитированием
  #18 (permalink)  
Старый 05.09.2008, 11:20
Интересующийся
Отправить личное сообщение для gagagogo Посмотреть профиль Найти все сообщения от gagagogo
 
Регистрация: 01.09.2008
Сообщений: 18

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

сам ты корявый...
Ответить с цитированием
  #20 (permalink)  
Старый 06.09.2008, 19:57
Новичок на форуме
Отправить личное сообщение для Kolyaj Посмотреть профиль Найти все сообщения от Kolyaj
 
Регистрация: 19.02.2008
Сообщений: 9,177

Сообщение от ZoNT
и чем тебе это не нравится?
Ну, например, если в коде будет <img src="1.gif" />, то в скрипт придет <img src="1"> (как минимум в FF). Уж лучше тогда в textarea пихать. А лучше все-таки экранировать все нужное.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Скрыть ссылку на js Googert Общие вопросы Javascript 10 21.02.2012 17:29
Нужно с помощью JS записывать данные в БД d!mm Общие вопросы Javascript 2 01.11.2008 18:36
вызов функции, из JS генерируемого на сервере subaru AJAX и COMET 1 12.07.2008 13:44
опубликуйте пожалуйста функционал JS scuter Сайт Javascript.ru 21 05.06.2008 17:44
подключение стороннего js скрипта friend Общие вопросы Javascript 2 24.05.2008 19:51