(DOM/AJAX/PROTOTYPE) Alle Zeilen einer Tabelle entfernen
Alexander R
- javascript
0 nils21 Detlef G.0 Alexander R0 nils2
Hallo zusammen,
ich verzweifel bereits schon an diesem Problem. Zur Erläuterung noch: Ich verwende prototype (bzw. AJAX-Requests) um meine Tabelle mit Ergebnissen zu befüllen. Nun klappt das Befüllen ganz gut und ich möchte natürlich vor jedem Refresh wieder alle Zeilen löschen.
Meine Tabelle sieht folgendermaßen aus:
~~~html
<table id="searchResults">
<thead>
<tr>
<th>Datum</th>
<th>Stellenname</th>
<th>Unternehmen</th>
<th>Standort(e)</th>
</tr>
</thead>
<tbody id="searchResultsBody"></tbody>
</table>
Das Befüllen geschieht mit Hilfe folgender JS-Funktion:
~~~javascript
var row = document.createElement('tr');
// create cells
var col1 = document.createElement('td'); col1.innerHTML = item['date']; row.appendChild(col1);
var col2 = document.createElement('td'); col2.innerHTML = item['title']; row.appendChild(col2);
var col3 = document.createElement('td'); col3.innerHTML = item['company']; row.appendChild(col3);
var col4 = document.createElement('td'); col4.innerHTML = item['cities']; row.appendChild(col4);
// insert into dom
$('searchResultsBody').appendChild(row);
Wie bereits gesagt, das Befüllen klappt tadellos.
Will ich nun aber alle Zeilen mit folgender JS-Funktion entfernen:
var numElements = $('searchResultsBody').childNodes.length;
if (numElements) {
for (i = 0; i < numElements; i++ ) {
var child = $('searchResultsBody').childNodes[i];
if (child.nodeName == 'TR') {
$('searchResultsBody').removeChild(child);
}
}
}
Er entfernt seltsamerweise nur ein paar Elemente (kann ich nicht nachvollzuziehen nach welchem Schema) und mein Firebug/Firefox spuckt dann folgenden Fehler aus:
child has no properties
dropSearchResults()job_search.js (line 75)
onclick(click clientX=0, clientY=0)search (line 1)
[Break on this error] if (child.nodeName == 'TR') {
Leider arbeite ich mich derzeit in die JS/AJAX-Thematik ein und deshalb weiß ich einfach nicht weiter - alle Varianten, die ich ausprobiert habe sind gescheitert :(
Vielen Dank für Eure Hilfe!
Alex
Hallo,
Probier mal, die ganze Tabelle per Javascript zu erstellen. Könnte sein, das es Probleme gibt, weil ein table-tag ohne tr's und td's übrigbleibt. Könnte auch an prototype liegen. Vielleicht mal ohne das $() testen. Hier eine Funktion, die ich für sowas immer verwende und darunter die Tabelle.
// Zuerst die Definition von DOM
if ( typeof(org) == "undefined" ) org = {};
if ( typeof(org.fw) == "undefined" ) org.fw = {};
if ( typeof(org.fw.util) == "undefined" ) org.fw.util = {};
/*
@author nils lindemann <nilsAtfreieweltDotorg>
@param no
@returns object myDOM
@example var dom = org.fw.util.DOM();
*/
org.fw.util.DOM = function()
{
var r, i, t; // r = returnValue, i = counter, t = temp Variable
var self = this;
return {
/*
@param String elementName
Array attributes ([string attributeName, string attributeValue]*) optional
Object childNode optional
@returns Object DOMNode
@example myNode = dom.elem("div", ["class", "myClass"], dom.elem("p", null, "Hallo Welt!"));
*/
elem : function() {
r = document.createElement(arguments[0] ? arguments[0] : "div");
if (arguments[1] && (arguments[1] != null)) {
for(i = 0; i < arguments[1].length; i += 2) {
//t setzen
t = document.createAttribute(arguments[1][i]);
t.nodeValue = arguments[1][i+1];
r.setAttributeNode(t);
}
}
if (arguments[2] && (arguments[2] != null)) {
for (var i = 2; i < arguments.length; i++){
// t setzen
if (typeof(arguments[i]) == "string")
t = document.createTextNode(arguments[i]);
else
t = arguments[i];
r.appendChild(t);
}
}
return r;
},
/*
@param [object DOMNode]*
@returns object DOMDocumentFragment
@example myFragment = dom.frag(dom.elem(), dom.elem("p", null, "Hallo Welt!"), dom.elem());
*/
frag : function() {
r = document.createDocumentFragment();
if (arguments.length > 0) {
for(i = 0; i < arguments.length; i++) {
r.appendChild( typeof(arguments[i]) == "string" ? document.createTextNode(arguments[i]) : arguments[i]);
}
}
return r;
},
get : function() {
r = document.getElementsByTagName(arguments[0]);
return r[0];
},
text : function() {
r = document.createTextNode(arguments[0]);
return r;
}
};
};
// DOM Objekt erzeugen
dom = org.fw.util.DOM();
// Jetzt deine Tabelle
$('parentElementOfSearchResultsTable').appendChild(
dom.elem(
"table", ["class", "dynamische-tabelle"], dom.elem(
"tr", null, dom.frag(
dom.elem("td", null, item['date']),
dom.elem("td", null, item['title']),
dom.elem("td", null, item['company']),
dom.elem("td", null, item['cities'])
)
)
)
);
Gruß, Nils
Hallo Alexander
Er entfernt seltsamerweise nur ein paar Elemente (kann ich nicht nachvollzuziehen nach welchem Schema) ...
Überlege mal genau, was dein Script macht!
Du entfernst das erste TR-Element, dann von den verblieben TR-Elementen das zweite (also eigentlich das dritte), dann von den verbliebenen das dritte (also eigentlich das fünfte) ...
Entweder du entfernst so lange das erste TR-Element, wie welche vorhanden sind, oder du gehst die Schleife von hinten nach vorn durch.
Allerdings frage ich mich warum es unbedingt so kompliziert über childNodes, child.nodeName und removeChild() gelöst werden muss, wenn dafür doch direkt deleteRow() zur Verfügung steht.
Auf Wiederlesen
Detlef
Hallo Detlef,
vielen Dank für Deine Antwort!
Deine Erläuterungen machen mir den Knackpunkt auch klar!
Konnte aber dank Deines Hinweis das Ganze"entwirren" und noch viel schneller lösen!
Allerdings frage ich mich warum es unbedingt so kompliziert über childNodes, child.nodeName und removeChild() gelöst werden muss, wenn dafür doch direkt deleteRow() zur Verfügung steht.
Meine Lösung sieht entsprechend so aus:
var numElements = $('searchResultsBody').childNodes.length;
while (numElements > 0) {
$('searchResultsBody').deleteRow(numElements-1);
numElements--;
}
Gruß
Alex
Hallo Alexander
Meine Lösung sieht entsprechend so aus:
var numElements = $('searchResultsBody').childNodes.length;
while (numElements > 0) {
$('searchResultsBody').deleteRow(numElements-1);
numElements--;
}
Warum so kompliziert? ;)
~~~javascript
for (var i = $('searchResultsBody').rows.length; i > 0; i--) {
$('searchResultsBody').deleteRow(i-1);
}
Das Befüllen der Tabelle hätte ich wahrscheinlich auch nicht mittels createElement(), und appendChild() realisiert sondern mittels insertCell().
Ich frage mich darüberhinaus, ob es wirklich effektiv ist, alle Tabellenzeilen zu löschen, um sie dann wieder neu einzufügen, oder ob es sich anbieten würde, nur die Inhalte auszutauschen.
Auf Wiederlesen
Detlef
Hallo,
Korrekt! Viel richtiger und auch viel eleganter als meine Antwort :-)
Gruß, Nils