Filterung eines mehrdimensionalen Arrays
Enrico
- javascript
Hallo,
mein Problem mit der strukturierten Ausgabe eines mehrdimensionalen Arrays
in Tabellenrofm (Thread 'Anzeige "undefined" bei Tabellenerstellung')
konnte gelöst werden, hier nochmals vielen Dank an Kai und Hork im Work,
nun ist aber ein neues Problem aufgetreten:
Ich habe es bislang leider nicht geschafft, das Array Film, das alle wichtigen
Filminfos enthält, zu filtern.
Die Funktion, die die Filterung vornehmen soll, lautet folgendermassen:
function Anzeige_filtern(Film,Kriterium)
{
var Temp = new Array();
var Zaehler = 0;
for (var i = 0; i < Inhalt.length; i++)
{
if(Film[i].Titel.substring(0,1)==Kriterium)
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
Zaehler += 1;
}
Tabelle_ausgeben("Details",Temp);
}
Ich habe die Zeile "Temp[Zaehler]=..." hier der besseren Leserlichkeit umgebrochen.
Diese Funktion wird über Links in der folgenden Art und Weise aufgerufen:
<a href="javascript:Anzeige_filtern(Film,'A')">
<a href="javascript:Anzeige_filtern(Film,'B')">
<a href="javascript:Anzeige_filtern(Film,'C')">
...usw...
Der Vollständigkeit halber noch einmal ein Beispiel, wie ich das
Array "Film" aufgebaut habe:
var Film = new Array();
Film[0]={DVD_Nr:..., Titel:"DIE SIEGER", Inhalt:"...", Genre:"...", FSK:...};
Film[1]={DVD_Nr:..., Titel:"DIE SIEGER", Inhalt:"...", Genre:"...", FSK:...};
...usw...
Was habe ich falsch gemacht ?
As allways: Dankesehr für Eure Hilfe :-)
Gruß,
Enrico
Hallo!
...
for (var i = 0; i < Inhalt.length; i++)
{
if(Film[i].Titel.substring(0,1)==Kriterium)
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};Zaehler += 1;
}Tabelle_ausgeben("Details",Temp);
...
Hab länger nichts mehr mit JS gemacht aber wenn ich mich nicht irre, dann geht man mit assoziativen Arrays so um:
...
Temp[Zaehler] = {"DVD_Nr" => Film[i]["DVD_Nr"], "Titel" => Film[i]["Titel"], ...};
...
Ein kurzer Blick in den SELFHTML JS Bereich hilft dir garantiert weiter. Alternativ kannst du auch BigBrother (Google) o.ä. fragen.
--
Lg,
Snafu
Hellihello
Hallo!
...
for (var i = 0; i < Inhalt.length; i++)
{
if(Film[i].Titel.substring(0,1)==Kriterium)
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};Zaehler += 1;
}Tabelle_ausgeben("Details",Temp);
...
Hab länger nichts mehr mit JS gemacht aber wenn ich mich nicht irre, dann geht man mit assoziativen Arrays so um:
...
Temp[Zaehler] = {"DVD_Nr" => Film[i]["DVD_Nr"], "Titel" => Film[i]["Titel"], ...};
» ...
Das ist PHP. o.g. ist JSON (javascript object notation).
Dank und Gruß,
frankx
Das ist PHP. o.g. ist JSON (javascript object notation).
Ich sollte wohl lieber bald Schlafen gehen :)
gruss frankx,
...
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
...... o.g. ist JSON (javascript object notation).
ich muss mal den kruemelkacker spielen. es ist eben doch wichtig,
klarheit in begriffe zu bringen, um eine einheitliche diskussions-
grundlage zu schaffen.
bei obigem handelt es sich nicht um JSON im crockfordschen sinne.
obiges ist die schlichte vom anbeginn der sprache anwendbare
literalnoation von objekten.
JSON (JavaScript Object Notation) beschreibt ein schema zur
literalnotation einer klar definierten untermenge von objekten
des sprachkerns, in dem deutlich die grenzen gegenueber der
nativen literalnotation aufgezeigt werden.
so long - peterS. - pseliger@gmx.net
Hellihello peter,
...
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
...... o.g. ist JSON (javascript object notation).
ich muss mal den kruemelkacker spielen. es ist eben doch wichtig,
klarheit in begriffe zu bringen, um eine einheitliche diskussions-
grundlage zu schaffen.bei obigem handelt es sich nicht um JSON im crockfordschen sinne.
obiges ist die schlichte vom anbeginn der sprache anwendbare
literalnoation von objekten.JSON (JavaScript Object Notation) beschreibt ein schema zur
literalnotation einer klar definierten untermenge von objekten
des sprachkerns, in dem deutlich die grenzen gegenueber der
nativen literalnotation aufgezeigt werden.
meci!
Dank und Gruß,
frankx
echo $begrüßung;
Ich habe es bislang leider nicht geschafft, das Array Film, das alle wichtigen
Filminfos enthält, zu filtern.
Liegt möglicherweise daran, dass du die Arbeitsweise deines Script nicht mittels Kontrollausgaben überprüfst.
function Anzeige_filtern(Film,Kriterium)
{
var Temp = new Array();
var Zaehler = 0;for (var i = 0; i < Inhalt.length; i++)
{
if(Film[i].Titel.substring(0,1)==Kriterium)
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};Zaehler += 1;
}
Wofür verwendest du Zaehler, wenn du dessen Inhalt doch gleichzeitig mit i hochzählst und dann auch i nehmen könntest? Willst du nicht vielleicht nur dann hochzählen, wenn die Bedingung passt? Passt überhaupt deine Bedingung? Hast du dir das Ergebnis von Film[i].Titel.substring(0,1) und den Wert in Kriterium mal ausgeben lassen und selbst vergleichen?
echo "$verabschiedung $name";
Hallo,
Was habe ich falsch gemacht ?
Du hast vergessen zu erwähnen, was dein Problem ist: "Funzt nicht" ist keine Problembeschreibung, heißt es in der Hilfe für Fragende.
Also:
usw.
Gruß, Don P
Hallo Don P,
die Filterung funktioniert nicht, das Array "Film" wird zumindest per Definition richtig eingelesen, die Ausgabe in Tabbelform funktioniert auch, da sämtliche Spalten des Arrays "Film" nach Aufrufen der Seite korrekt angezeigt werden.
Die Variable "Zaehler" habe ich integriert, damit das Array "Temp" hochgezählt wird, die for-Schleife mit "i" durchläuft das Array "Film". Die Anweisung "Film[i].Titel.substring(0,1)" stimmt, somit liegt das Problem - nach dem Ausschlussprinzip - in der Definition des neuen Arrays "Temp", was mich aber wundert, da ich die gleiche Struktur verwendet habe wie für die Definition des Arrays "Film".
Gruß,
Enrico
Grütze .. äh ... Grüße!
Die Variable "Zaehler" habe ich integriert, damit das Array "Temp" hochgezählt wird, die for-Schleife mit "i" durchläuft das Array "Film". Die Anweisung "Film[i].Titel.substring(0,1)" stimmt, somit liegt das Problem - nach dem Ausschlussprinzip - in der Definition des neuen Arrays "Temp", was mich aber wundert, da ich die gleiche Struktur verwendet habe wie für die Definition des Arrays "Film".
Setze vor der Zeile Zaehler += 1;
doch einfach mal eine Kontrolle:
alert(Temp[Zaehler].DVD_Nr + "\n" + Temp[Zaehler].Titel + "\n" + .. usw. )
und schau welche Werte nun wirklich geschrieben wurden. Sind es die, die du erwartet hast?
Cü
Kai
Hallo Kai,
die Fehlerkonsole FireBug gibt folgende Meldung aus:
Temp[Zaehler] has no properties
Anzeige_filtern([Object DVD_Nr=1 Titel=DIE SIEGER, Object DVD_Nr=2 Titel=DOMINO, Object DVD_Nr=3 Titel=GONE, 281 more...], "O")FUNKTIONEN.js (line 40)
[Break on this error] alert(Temp[Zaehler].DVD_Nr + "\n" + Temp[Zaehler].Titel + "\n" + Temp[Zaehle...
Schwierig, schwierig...
Kann damit nichts anfangen... :-(
Gruß,
Enrico
Hallo,
Verzichte auf die Variable "Zähler" und schreibe das Array so:
Temp[Temp.length]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
Und setze um Himmels Willen nach if() immer ein Klammerpaar {} um den oder die dann auszuführenden Befehle.
Gruß, Don P
Hallo Don P,
ich habe das Array "Zaehler" umgestellt, die FireBug-Fehlerkonsole bringt keine Fehlermeldung, aber es tut sich auch nichts mehr, d.h. das Array "Temp" wird nicht (korrekt) an die Funktion Tabelle_ausgeben übergeben:
function Tabelle_ausgeben(tbody,Inhalt)
{
if (!tbody)
{
alert ("tbody nicht gefunden");
return;
}
var tr, td;
tbody = document.getElementById(tbody);
for (var i = 0; i < Inhalt.length; i++)
{
tr = tbody.insertRow(tbody.rows.length);
td = tr.insertCell(tr.cells.length);
td.innerHTML = Inhalt[i].DVD_Nr;
td = tr.insertCell(tr.cells.length);
td.setAttribute("style","white-space:nowrap;");
td.innerHTML = Inhalt[i].Titel;
td = tr.insertCell(tr.cells.length);
td.innerHTML = Inhalt[i].Inhalt;
td = tr.insertCell(tr.cells.length);
td.setAttribute("style","white-space:nowrap;");
td.innerHTML = Inhalt[i].Genre;
td = tr.insertCell(tr.cells.length);
td.innerHTML = Inhalt[i].FSK;
}
}
Ich flipp noch aus... *grrrr*
Gruß,
Enrico
Hallo,
ich habe das Array "Zaehler" umgestellt,
Dann zeig' jetzt mal den Code deiner ganzen for-Schleife.
die FireBug-Fehlerkonsole bringt keine Fehlermeldung,
Das war zu erwarten. Weil das Array jetzt keine Lücken mehr hat.
aber es tut sich auch nichts mehr, d.h. das Array "Temp" wird nicht (korrekt) an die Funktion Tabelle_ausgeben übergeben
Das glaube ich nicht. Woher weißt du das?
Ich glaube eher, dass deine Funktion Tabelle_ausgeben() fehlerhaft arbeitet. Aber mit den DOM-Methoden kenne ich mich nicht aus. Das weiß vielleicht jemand anders.
function Tabelle_ausgeben(tbody,Inhalt)
{
if (!tbody)
{
alert ("tbody nicht gefunden");
return;
}
Du fragst hier, ob die Zeichenkette "Details" (in der übergebenen Variablen tbody) leer ist oder nicht. Ist das erwünscht?
var tr, td;
tbody = document.getElementById(tbody);
Jetzt suchst du ein DOM-Element mit der id "Details" (in der übergebenen Variablen tbody). Existiert das wirklich?
ab hier weiß ich auch nicht weiter (mangels Kenntnis der DOM-Methoden).
Gruß, Don P
Wenn ich die Tabelle jetzt über die Spaltenüberschriften sortiere, dann habe ich die entsprechenden Filme doppelt in der Tabelle.
Wenn ich beispielsweise alle Filme mit dem Anfangsbuchstaben "A" filtern möchte, dann habe ich hinterher alle Filme mit dem Anfangsbuchstaben "A" doppelt in der Tabelle.
Dies bedeutet zum einen, dass die Filter-Funktion funktioniert, zum anderen aber auch, dass ich die Funktion "Tabelle_ausgeben" so erweitern muss, dass die ursprüngliche Ansicht vor Ausgabe des neuen Arrays gelöscht werden muss.
Gruß,
Enrico
Hallo,
Dies bedeutet zum einen, dass die Filter-Funktion funktioniert, zum anderen aber auch, dass ich die Funktion "Tabelle_ausgeben" so erweitern muss, dass die ursprüngliche Ansicht vor Ausgabe des neuen Arrays gelöscht werden muss.
Klar, wenn die Tabelle bereits Einträge enthält, müssen die natürlich zuerst weg. Du benutzt ja bis jetzt immer nur insertRow(), was ständig neue Einträge erzeugt.
Gruß, Don P
Hallo,
die Filterung funktioniert nicht
Woran erkennst du das?
Anders gefragt: Was erwartest du vom Temp-Array und was steht statt desssen drin?
Die Tabelle hat alle Spalten, schön. Aber *was* stimmt nicht mit den Reihen? Sind sie alle leer? Sind sie teilweise leer? enthalten sie falsche Daten? So ist es wirklich mühsam, dir zu helfen, Mensch.
Eines solltest du jedenfalls klar stellen, dein Code:
if(Film[i].Titel.substring(0,1)==Kriterium)
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
Zaehler += 1;
bedeute dasselbe wie:
if(Film[i].Titel.substring(0,1)==Kriterium){
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
}
Zaehler += 1;
Somit entstehen Lücken im Array "Temp", nämlich immer dann, wenn die if-Bedingung nicht zutrifft.
Wenn du das nicht willst, schreibe:
if(Film[i].Titel.substring(0,1)==Kriterium){
Temp[Zaehler]={DVD_Nr:Film[i].DVD_Nr,
Titel:Film[i].Titel,
Inhalt:Film[i].Inhalt,
Genre:Film[i].Genre,
FSK:Film[i].FSK};
Zaehler += 1;
}
dedlfix hat dich doch schon darauf hingewiesen.
Um solche Fehlerquellen auszuschließen, sollte man immer die Klammern if(...){...} notieren.
Die Variable "Zaehler" habe ich integriert, damit das Array "Temp" hochgezählt wird, die for-Schleife mit "i" durchläuft das Array "Film".
Ja, und bei jedem Durchlauf wird auch "Zähler" um 1 erhöht, so dass du gar keine separate Variable "Zähler" brauchst, weil ihr Wert immer identisch mit dem von "i" ist, siehe dedlfix' Antwort.
Gruß, Don P
Grütze .. äh ... Grüße!
Ja, und bei jedem Durchlauf wird auch "Zähler" um 1 erhöht, so dass du gar keine separate Variable "Zähler" brauchst, weil ihr Wert immer identisch mit dem von "i" ist, siehe dedlfix' Antwort.
Das ist für mich aber unlogisch. Es soll ein neues Array 'Temp' erzeugt werden, das nur eine Teilmenge der ursprünglichen Daten enthält, nämlich die, die dem Kriterium entsprechen.
Also darf nur dann in das neue Array geschrieben werden, wenn die Bedingung zutrifft und auch nur dann darf der count für dieses neue Array erhöht werden. Also braucht er sehr wohl eine separate Varriable, oder bin ich jetzt völlig blöd?
Cü
Kai
Hallo,
Also darf nur dann in das neue Array geschrieben werden, wenn die Bedingung zutrifft und auch nur dann darf der count für dieses neue Array erhöht werden.
Sollte man meinen. Sein Code macht das aber nicht, sondern erhöht die Zähler-Variable immer, völlig unabhängig von der Bedingung. Weil dem so ist, könnte er sie auch gleich ganz weglassen und i dafür benutzen. Oder aber, wenn er diese Verhalten nicht will, muss er wie beschrieben seinen Code entsprechend ändern, damit es so rauskommt, wie du es verstehst, und wie es wahrscheinlich auch sein soll.
Also braucht er sehr wohl eine separate Varriable, oder bin ich jetzt völlig blöd?
Bist du nicht. Aber statt der separaten Variablen kann auch ein Temp.push(...) herhalten oder eben ein Temp[Temp.length]=...;
Gruß, Don P
Grütze .. äh ... Grüße!
Also darf nur dann in das neue Array geschrieben werden, wenn die Bedingung zutrifft und auch nur dann darf der count für dieses neue Array erhöht werden.
Sollte man meinen. Sein Code macht das aber nicht, sondern erhöht die Zähler-Variable immer, völlig unabhängig von der Bedingung. Weil dem so ist, könnte er sie auch gleich ganz weglassen und i dafür benutzen. Oder aber, wenn er diese Verhalten nicht will, muss er wie beschrieben seinen Code entsprechend ändern, damit es so rauskommt, wie du es verstehst, und wie es wahrscheinlich auch sein soll.
Ja ich weiß. Aber Enrico scheint ja nicht das große Javascript-Ass zu sein (bin ja selber noch viele hundert Lichtjahre davon entfernt) und wenn er diese Vorschläge einfach so umgeändert hätte, evtl. noch ohne Backup, dann wäre er da gar nicht mehr mit zurechtgekommen. Insofern sollte nicht nur der Ist-Code betrachtet werden, sondern auch die wahrscheinliche Intention. Und irgendwie erscheint mir nur diese Variante sinnvoll.
Bist du nicht. Aber statt der separaten Variablen kann auch ein Temp.push(...) herhalten oder eben ein Temp[Temp.length]=...;
Klar, ist wesentlich eleganter, wenn die Variable ansonsten nicht benötigt wird. Aber den entsprechenden Beitrag hatte ich erst später gelesen ;)
Cü
Kai
Hallo,
wenn er diese Vorschläge einfach so umgeändert hätte, evtl. noch ohne Backup, dann wäre er da gar nicht mehr mit zurechtgekommen.
Ich denke schon, dass er vor dem Erstzen seiner "Zähler"-Variable durch sein "i" schnell gemerkt hätte, dass das nicht zu dem führen kann, was er will, falls er es denn wirklich so will, wie wir vermuten.
Es wurde ja lediglich vorgeschlagen, sein if()... und die Variable "Temp" einmal kritisch unter die Lupe zu nehmen. Der einzige Fehler war letztlich, dass er keinen Block {} nach if() gesetzt hatte. dedlfix und ich haben ihm hier halt einen Wink mit dem Zaunpfahl gegeben.
Gruß, Don P
Hallo,
Es wurde ja lediglich vorgeschlagen, sein if() und die Variable "Temp" einmal kritisch unter die Lupe zu nehmen.
Äh shit, ich meinte natürlich sein if() und die Variable "Zähler".
Viel Spass noch, ich muss jetzt weg...
CU, Don P
Dir auf jeden Fall vielen lieben Dank für Deine Hilfestellungen :-)
Gruß,
Enrico
Enrico scheint ja nicht das große Javascript-Ass zu sein
Da haste recht, hätte mir das viel, viel, viel einfacher vorgestellt, aber so schnell kann man sich täuschen... :-)
Sodalla, habe jetzt versucht, die Tabelle jedesmal beim Aufrufen der Funktion "Tabelle_ausgeben" neu aufbauen zu lassen und ratet mal... Genau, es klappt nicht...
function Tabelle_ausgeben(tbody,Inhalt)
{
var obj;
var table;
var tr;
var td;
var Text;
obj = document.getElementById(tbody);
for (var i = 0; i < Inhalt.length; i++)
{
tr = document.createElement("tr");
td = document.createElement("td");
text = document.createTextNode(Inhalt[i].DVD_Nr);
table.appendChild(tr);
tr.appendChild(td);
td.appendChild(text);
td = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
text = document.createTextNode(Inhalt[i].Titel);
td.appendChild(text);
td = document.createElement("td");
text = document.createTextNode(Inhalt[i].Inhalt);
td.appendChild(text);
td = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
text = document.createTextNode(Inhalt[i].Genre);
td.appendChild(text);
td = document.createElement("td");
text = document.createTextNode(Inhalt[i].FSK);
td.appendChild(text);
}
obj.appendChild(table);
}
Enrico
Ich habe den Code zur Neuerzeugung der Tabelle entsprechend abgeändert:
function Tabelle_ausgeben(Inhalt)
{
var Tabellenbereich;
var Zeile;
var Zelle;
var Text;
Tabellenbereich = document.getElementById("tbody");
document.getElementById('Datenbank').appendChild(Tabellenbereich);
for (var i = 0; i < Inhalt.length; i++)
{
Zeile = document.createElement("tr");
Zeile.id = "Zeile" + i;
Tabellenbereich.appendChild(Zeile);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].DVD_Nr);
Zelle.appendChild(inhalt);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Titel);
Zelle.appendChild(inhalt);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Inhalt);
Zelle.appendChild(inhalt);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Genre);
Zelle.appendChild(inhalt);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].FSK);
Zelle.appendChild(inhalt);
document.getElementById("Zeile" + i).appendChild(Zelle);
}
}
Das zugrundeliegende HTML-Gerüst sieht wie folgt aus:
<table id="Datenbank">
<tr>
<th>DVD-Nr.</th>
<th>Titel</th>
<th>Inhalt</th>
<th>Genre</th>
<th>FSK</th>
</tr>
<tbody></tbody>
</table>
Leider wird mir jetzt aber nichts mehr ausgegeben.
Wo liegt/liegen der/die Fehler ?
Ich vermute, dass es an der Anweisung
Gruß,
Enrico
Grütze .. äh ... Grüße!
Ich habe den Code zur Neuerzeugung der Tabelle entsprechend abgeändert:
Ja, aber warum? Diese Funktion hatte doch mit dem normalen, ungefilterten Array
schon funktioniert, oder? Dann braucht da auch nichts geändert werden, läuft ja. Alles was du machen mußt, ist das gefilterte Array Temp so anzupassen, daß die Daten im gleichen Format vorliegen. Und ich nehme an, daß es daran gescheitert ist, eben weil wie schon bemerkt wurde, der Zähler an der falschen Stelle hochgezählt wurde.
Cü
Kai
Hallo Kai,
ich muß die Funktion ja von "insert..." etc. auf "append..." umstellen, weil ich die gefilterten Einträge sonst doppelt habe und nicht _nur_ die gefilterten Einträge aus dem Array "Temp".
Und leider funktioniert die Tabellenerzeugung nun nicht mehr.
Gruß,
Enrico
Mir ist gerade selber ein Fehler, aber leider nicht _der_ Fehler aufgefallen:
Natürlich muss es "Zelle.appendChild(Text);" und nicht "Zelle.appendChild(inhalt);" heissen.
Aber leider wird mir trotzdem keine Tabelle angezeigt.
Enrico
Grütze .. äh ... Grüße!
Hallo Kai,
ich muß die Funktion ja von "insert..." etc. auf "append..." umstellen, weil ich die gefilterten Einträge sonst doppelt habe und nicht _nur_ die gefilterten Einträge aus dem Array "Temp".
Hmm .. wie ich das sehe, suchst du das Element tbody und hängst daran alles mit appendChild an. Klar, wenn vorher schon etwas im tbody war, bleibt das so stehen und die neuen Einträge kommen hinzu und du hast doppelte. Ich würde das Problem etwas anders angehen und hätte den neuen tbody komplett (also incl tbody-Element) erzeugt und dann in der Tabelle mit replaceChild komplett ersetzt.
Oder du entfernst in einer Schleife erst mal alle alten Kindelemente von tbody und fügst dann die neuen wieder ein. Beiders würde aber das Script in dem Zustand benötigen, als du noch eine Tabelle mit doppelten Einträgen hattest.
Zu deinem aktuellen Problem kann ich nur sagen, daß eventuell die Zeile document.getElementById(tbody) etwas damit zu tun haben könnte, denn wenn du im HTML-Gerüst nur <tbody></tbody> stehen hast, klappt das natürlich so nicht. Entweder du suchst per getElementsByTagName , was aber dann etwas unschön ist, falls jetzt oder später mal weitere Tabellen auftauchen, oder du suchst gibst dem tbody eine id. <tbody id="mein_tbody"></tbody> und dann kannst du darauf mit getElementByID("mein_tbody") drauf zugreifen.
Cü
Kai
Kai, Danke für Deine Engelsgeduld, ich bin mit meinem "Latein" am Ende, ich versteh jetzt gar nüschd mehr...
daß eventuell die Zeile document.getElementById(tbody) etwas damit zu tun haben könnte
Ich habe jetzt folgende Struktur:
<table class="Ausgabe" id="Datenbank">
<tr>
<th>DVD-Nr.</th>
<th>Titel</th>
<th>Inhalt</th>
<th>Genre</th>
<th>FSK</th>
</tr>
<tbody id="Container"></tbody>
</table>
Die Definition über class dient nur der Aufbereitung über css-Formate.
Die Tabelle wird über folgende Anweisung initialisiert:
<body onload="Tabelle_ausgeben(Film);">
Den tbody-Bereich habe ich jetzt "Container" benannt und wird in der Funktion "Tabelle_ausgeben" wie folgt referenziert:
Tabellenbereich = document.getElementById("Container");
Die Funktion noch einmal komplett:
function Tabelle_ausgeben(Inhalt)
{
var Tabellenbereich;
var Zeile;
var Zelle;
var Text;
Tabellenbereich = document.getElementById("Container");
document.getElementById("Datenbank").appendChild(Tabellenbereich);
for (var i = 0; i < Inhalt.length; i++)
{
Zeile = document.createElement("tr");
Zeile.id = "Zeile" + i;
Tabellenbereich.appendChild(Zeile);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].DVD_Nr);
Zelle.appendChild(Text);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Titel);
Zelle.appendChild(Text);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Inhalt);
Zelle.appendChild(Text);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].Genre);
Zelle.appendChild(Text);
document.getElementById("Zeile" + i).appendChild(Zelle);
Zelle = document.createElement("td");
Zelle.id = "Zelle" + i;
Text = document.createTextNode(Inhalt[i].FSK);
Zelle.appendChild(Text);
document.getElementById("Zeile" + i).appendChild(Zelle);
}
}
Ich erhalte jetzt nur folgende Anzeige:
+------+-----+------+-----+---+
|DVD-Nr|Titel|Inhalt|Genre|FSK|
+------+-----+------+-----+---+
|1 | | | | |
+------+-----+------+-----+---+
Ich weiß echt nicht mehr weiter... Es ist frustrierend, wenn sich ein ansich einfach anhörendes Projekt zu solch einem "Problem-Monster" wandelt.
Ich hatte es mir sehr einfach vorgestellt:
Filmdaten über ein mehrdimensionales Array einlesen und ausgeben, Links anklicken, Array erstellt ein neues Array mit den zu selektierenden Filmen und gibt dieses Array wieder in einer Tabelle aus, schwupps und fertig...
Plöd, plöd, plöd... *lach*
Enrico
Grütze .. äh ... Grüße!
Tabellenbereich = document.getElementById("Container");
document.getElementById("Datenbank").appendChild(Tabellenbereich);
Hier hängst du das in der ersten Zeile ermittelte tbody-element mit der ID Container an das table-Element mit der ID Datenbank an, also genau das, was du im HTML eh schon so definiert hast. Die zweite Zeile hat daher _so_ keinen Sinn. ABER .. da du die Tabelle jedesmal nur mit den Ergebnissen des neuen Kriteriums bestücken willst, brauchen wir vielleicht sowas ähnliches doch noch. Dazu weiter unten mehr.
In der Schleife sehe ich mehrfach die Zeile
Zelle.id = "Zelle" + i;
Das geht nicht, da eine ID einmalig sein muß!
Ich würde das, wenn du die ganzen IDs _überhaupt_ brauchst (ich wüßte jetzt nicht wozu eigentlich?) folgendermaßen machen:
Zelle.id = "Zelle" + i + "1";
Zelle.id = "Zelle" + i + "2";
Zelle.id = "Zelle" + i + "3";
Zelle.id = "Zelle" + i + "4";
Zelle.id = "Zelle" + i + "5";
Damit hast du dann:
Zelle01 Zelle 02 Zelle03 Zelle04 Zelle05
Zelle11 Zelle 12 Zelle13 Zelle14 Zelle15
Zelle21 Zelle 22 Zelle23 Zelle24 Zelle25
usw.
Zeile = document.createElement("tr");
...
document.getElementById("Zeile" + i).appendChild(Zelle);
document.getElementById ist hier unnötig, genau diese Referenz hast du schon in der Variablen "Zeile" weiter oben stehen.
Zeile.appendChild(Zelle)
Zelle = document.createElement("td");
td.setAttribute("style","white-space:nowrap;");
Äh ... du meinst hier sicher "Zelle" , den die Variable "td" ist nicht definiert.
Außerdem weg mit setAttribute, kann zu Problemen im IE führen..
Zelle.style.whiteSpace = "nowrap".
Regel: Bindestriche von css-eigenschaften entfallen und der erste Buchstabe des folgenden Wortes wird groß geschrieben. Zu Risiken und Nebenwirkungen konsultieren sie ihre SelfHTML-Dokumentation in Bereich Objektreferenz style
Ansonsten siehst du ja, daß du einige Programm-Zeilen immer wieder schreiben mußt
und nur der Text-Node sich ändert, dazu bietet sich eine zweite Schleife geradezu an. Aber das klären wir, wenn meine Kopfschmerzen mal nicht so stark sind ;)
Außerdem fehlt noch die "Löschung" der eventuell vorhandenen alten Tabelleninhalten.
Da du ja mit appendChild arbeitest, würde zur Zeit die Tabelle immer wieder erweitert
werde, ohne daß die alten Filme verschwinden.
Ich schlage folgendes vor:
Erzeuge einen tbody:
var Tabellenbereich = document.createElement("tbody");
Tabellenbereich.id = "Container"
und dann kommt der ganze Rest der Erzeugung mit der for-Schleife
und _hinter_ der For-schleife, also zwischen den beiden Klammern "}"
ersetzt du den gesamten tbody mit replaceChild (und hier kommen wir auch wieder auf die weiter oben gemachte Bemerkung zurück:
document.getElementById("Datenbank").replaceChild(Tabellenbereich, document.getElementByID("Container"));
Ich weiß echt nicht mehr weiter... Es ist frustrierend, wenn sich ein ansich einfach anhörendes Projekt zu solch einem "Problem-Monster" wandelt.
Ich kenne das ganz genau, hatte das vor sehr kurzer zeit auch. Aber genau aus diesem Grunde habe ich dir auch bisher keine fertige Lösung hingezaubert auch wenns mir jedes Mal in den Fingern juckt, damit du die Sache auch nachvollziehst, testest und eben diese Fehler auch machst. Denn beim nächsten Mal machst du sie dann üblicherweise nicht mehr.
Ich hatte es mir sehr einfach vorgestellt:
Die Sachen, die einfach aussehen, entwickeln sich oft zu kleinen Monstern ;)
Zu meinem ganzen Beitrag kann ich nur sagen, er wurde unter leicht eingeschränkten Voraussetzungen geschrieben (mein Kopfschmerz halt) und daher kann es leicht passiert sein, daß mir ein Flüchtigkeits- oder Denkfehler unterlaufen ist. Also nicht unbedingt davon ausgehen, daß mein Code 100% ist.
Cü
Kai
Grütze .. äh ... Grüße!
Irgend ein Depp schrieb:
Erzeuge einen tbody:
var Tabellenbereich = document.createElement("tbody");
Tabellenbereich.id = "Container"
Wobei ich gerade nicht weiß, ob das so funktioniert (diese ID existiert ja schon)
Eventuell die ID erst _nach_ dem Austauschen mit replaceChild setzen?
Oder: komplett auf die ID verzichten und mit document.getElementById("Datenbank").getElementsByTagName("tbody") (so oder einzeln) arbeiten?
Cü
Kai
Hallo Kai,
ich hoffe, Deine Kopfschmerzen sind mittlerweile Schnee von "heute morgen", warst ja ganz schön lange auf...
Sodalla, habe jetzt einen anderen Ansatz versucht, der - direkt in die Datei geschrieben - zumindest schon
mal die Filmdatenbank korrekt ausgibt, aber über Aufruf in einer eingebundenen js-Datei nichts mehr ausgibt.
function Tabelle_ausgeben(Inhalt)
{
var Tabelle = document.createElement("TABLE");
var Tabellenkopf = document.createElement("THEAD");
var Tabellenkoerper = document.createElement("TBODY");
var Zeile, Zelle;
var i, j;
var Spaltenbeschriftung = new Array();
Spaltenbeschriftung[0] = "DVD-Nr.";
Spaltenbeschriftung[1] = "Titel";
Spaltenbeschriftung[2] = "Inhalt";
Spaltenbeschriftung[3] = "Genre";
Spaltenbeschriftung[4] = "FSK";
Tabelle.appendChild(Tabellenkopf);
Tabelle.appendChild(Tabellenkoerper);
Zeile = document.createElement("TR");
Tabellenkopf.appendChild(Zeile);
Tabellenkopf.setAttribute("bgColor","lightskyblue");
for (i=0; i<Spaltenbeschriftung.length; i++)
{
Zelle = document.createElement("TH");
Zelle.innerHTML = Spaltenbeschriftung[i];
Zeile.appendChild(Zelle);
}
for (i=0; i<Inhalt.length; i++)
{
Zeile = document.createElement("TR");
Tabellenkoerper.appendChild(Zeile);
for (j=0; j<Inhalt[i].length; j++)
{
Zelle = document.createElement("TD");
if ((j == 1)) || (j == 3))
Zelle.style.whiteSpace = "nowrap"
Zelle.innerHTML = Inhalt[i][j];
Zeile.appendChild(Zelle);
}
}
Container.appendChild(Tabelle);
}
Hier das html-Konstrukt:
<html>
<head>
<script type="text/javascript" src="BIBLIOTHEKEN/JAVASCRIPT/DATENBANK.js"></script>
<script type="text/javascript" src="BIBLIOTHEKEN/JAVASCRIPT/FUNKTIONEN.js"></script>
<link rel="stylesheet" type="text/css" href="BIBLIOTHEKEN/CSS/FORMATE.css">
</head>
<body onload = "Tabelle_ausgeben(Film)";>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
... Navigation mit Links zum Filtern ...
</tr>
</table>
<DIV ID="Container"></DIV>
</body>
</html>
Die Pfadangaben sind korrekt, weil das css-Sheet auch korrekt wiedergegeben wird, also kann es daran nicht liegen.
Hast Du eine Idee, Kai, warum es nicht klappt ?
Gruß,
Enrico
Hab den Fehler gerade gefunden, es liegt an folgender Anweisung:
if ((j == 1)) || (j == 3))
Zelle.style.whiteSpace = "nowrap";
Wenn ich diesen Block auskommentiere, dann klappt - zumindest die Ausgabe, das Filtern habe ich noch nicht getestet.
Aber wieso ?
Versteh ich nicht, dass diese Anweisung die komplette Ausgabe unterbindet.
Enrico
Grütze .. äh ... Grüße!
Hab den Fehler gerade gefunden, es liegt an folgender Anweisung:
if ((j == 1)) || (j == 3))
Zelle.style.whiteSpace = "nowrap";Wenn ich diesen Block auskommentiere, dann klappt - zumindest die Ausgabe, das Filtern habe ich noch nicht getestet.
Aber wieso ?
Nur ein Wort: Zählen.
Cü
Kai
Hallo Kai,
hab's herausgefunden, lag nur daran, dass ich das geschweifte Klammerpaar vergessen hatte. Jetzt klappt's...
Wie kann ich es bewerkstelligen, dass die Spaltenüberschriften, die ich mit nachfolgender Schleife ausgebe...
for (i=0; i<Spaltenbeschriftung.length; i++)
{
Zelle = document.createElement("th");
Zelle.innerHTML = (Spaltenbeschriftung[i]);
Zeile.appendChild(Zelle);
}
...durch nachfolgenden Zusatz ergänzt werden, so dass ich eine Sortierfunktion für die Tabelle einbauen kann?
"onclick=sortNow("+[i]+",true);"
Ich möchte damit erreichen, dass ich die Tabelle per Klick auf die Spaltenüberschriften sortieren kann.
<th onclick="sortNow(0,true);">...</th>
<th onclick="sortNow(1,true);">...</th>
...usw...
Thxle
Gruß,
Enrico
hab's herausgefunden, lag nur daran, dass ich das geschweifte Klammerpaar vergessen hatte. Jetzt klappt's...
Warum schaust du nicht nach den Fehlermeldungen die dir der Browser ausgibt?
Wie kann ich es bewerkstelligen, dass die Spaltenüberschriften, die ich mit nachfolgender Schleife ausgebe...
for (i=0; i<Spaltenbeschriftung.length; i++)
{
Zelle = document.createElement("th");
Zelle.innerHTML = (Spaltenbeschriftung[i]);
Zeile.appendChild(Zelle);
}...durch nachfolgenden Zusatz ergänzt werden, so dass ich eine Sortierfunktion für die Tabelle einbauen kann?
"onclick=sortNow("+[i]+",true);"
Mal abgesehen davon das das falsch ist, kanst du das direkt in den JS code einbauen:
Zelle = document.createElement("th");
Zelle.i
Zelle.onclick = function(e) {
sortNow(this.i, true);
};
Ich möchte damit erreichen, dass ich die Tabelle per Klick auf die Spaltenüberschriften sortieren kann.
Damit habe ich mnich gerade die letzten Tage auseinandergesetzt http://javascript.jstruebig.de/javascript/74/
Struppi.
Sodalla, Ausgabe der Tabelle über DOM funktioniert, die Sortier-Funktion ebenfalls, die Filter-Funktion an sich auch (habe die gefilterten Werte über den "alert"-Befehl ausgeben lassen und die passen), einzig und allein die Anzeige der gefilterten Einträge klappt nicht, d.h. es wird scheinbar keine neue Tabelle generiert.
Auch habe ich es noch nicht geschafft, "appendChild" gegen "replaceChild" auszutauschen, weil hier ja zwei Werte erwartet werden, ich aber nur einen Wert "Container" habe.
Aber ich muß hier ja "replace..." verwenden, da sonst die neue Tabelle wieder nur an die "alte" angehängt werden dürfte.
Hier nochmal die beiden Funktionen:
function Tabelle_ausgeben(Inhalt)
{
var Tabelle = document.createElement("table");
var Tabellenkopf = document.createElement("thead");
var Tabellenkoerper = document.createElement("tbody");
var Zeile, Zelle;
var i, j;
var Spaltenbeschriftung = new Array();
Spaltenbeschriftung[0] = "DVD-Nr.";
Spaltenbeschriftung[1] = "Titel";
Spaltenbeschriftung[2] = "Inhalt";
Spaltenbeschriftung[3] = "Genre";
Spaltenbeschriftung[4] = "FSK";
Tabelle.setAttribute("class", "sortable");
Tabelle.appendChild(Tabellenkopf);
Tabelle.appendChild(Tabellenkoerper);
Zeile = document.createElement("tr");
Tabellenkopf.appendChild(Zeile);
Tabellenkopf.setAttribute("bgColor","lightskyblue");
for (i=0; i<Spaltenbeschriftung.length; i++)
{
Zelle = document.createElement("th");
Zelle.innerHTML = (Spaltenbeschriftung[i]);
Zelle.i
if (i != 2)
{
Zelle.setAttribute("style", "cursor:pointer");
Zelle.onclick = function(e)
{
sortTable(this);
}
}
Zeile.appendChild(Zelle);
}
for (i=0; i<Inhalt.length; i++)
{
Zeile = document.createElement("tr");
Tabellenkoerper.appendChild(Zeile);
for (j=0; j<Inhalt[i].length; j++)
{
Zelle = document.createElement("td");
if ((j==1) || (j == 3))
{
Zelle.style.whiteSpace = "nowrap";
}
Zelle.innerHTML = Inhalt[i][j];
Zeile.appendChild(Zelle);
}
}
document.getElementById("Container").appendChild(Tabelle);
}
function Anzeige_filtern(Film,Kriterium)
{
var Temp = new Array();
for (var i = 0; i < Film.length; i++)
{
if(Film[i][1].substring(0,1)==Kriterium)
{
Temp[Temp.length]=[Film[i][0], Film[i][1], Film[i][2], Film[i][3], Film[i][4]];
}
}
Tabelle_ausgeben(Temp);
}
So kurz vor der Ziellinie noch irgendein Problem, das ist sehr ärgerlich...
Vielen Dank für Eure Hilfe, habt mir so schon riesig geholfen.
Gruß,
Enrico
Die Übergabe des gefilterten bzw. neu erzeugten Arrays "Temp" an die Funktion "Tabelle_ausgeben" klappt (Überprüfung über alert), deshalb ist es für mich umso verwunderlicher, warum dieses Array dann nicht korrekt angezeigt wird.
Enrico
Wenn ich mir den Quelltext über die Firefox-Console anschaue, dann sind auch alle Angaben des durch die Filterung neu erzeugten Arrays übernommen:
<table class="sortable">
<thead bgcolor="lightskyblue"></thead>
<tbody>
<tr>
<td>12</td>
<td style="white-space: nowrap;">ASSASSINS - DIE KILLER</td>
<td>Die Nummer Eins ist ...</td>
<td style="white-space: nowrap;">Action</td>
<td>16</td>
</tr>
... usw ...
Warum wird mir die Tabelle dann nicht angezeigt ?
Ich habe auch schon probiert, eine etwaig vorhandene Tabelle über folgenden Code löschen zu lassen, bevor die neue erzeugt wird:
if (document.getElementById("Datenbank"))
{
var Tabelle = document.getElementById("Datenbank");
table.parentNode.removeChild(Tabelle);
}
Aber diese Anweisung trägt keine Früchte.
Kann es evtl daran liegen, dass die Tabellen innerhalb eines div-Bereiches erzeugt werden ?
<div id="Container"></div>
Enrico
Ich hatte noch vergessen, der Tabelle die ID auch zuzuweisen.
Dies erledige ich jetzt ebenfalls in der Funktion "Tabelle_ausgeben":
Tabelle.setAttribute("id", "Datenbank");
Über den alert-Befehl habe ich nun auch bestätigt bekommen, dass die Tabelle mit der ID "Datenbank" existiert.
Trotzdem wird die vorhandene Ansicht/Tabelle nicht gelöscht und durch
die neue ersetzt.
Enrico
Ich habe jetzt die Lösung des Problems gefunden:
function Tabelle_ausgeben(Inhalt)
{
if (document.getElementById("Datenbank"))
{
var node = document.getElementById("Datenbank")
if (typeof node == 'object')
{
node.parentNode.removeChild(node);
}
}
... ab hier wie gehabt ...
}
Gruß,
Enrico
PS: Das war eine mehr als nur schwere Geburt... :-)
Grütze .. äh ... Grüße!
hab's herausgefunden, lag nur daran, dass ich das geschweifte Klammerpaar vergessen hatte. Jetzt klappt's...
Nein, das war garantiert NICHT der Fehler, auf den ich mich bezogen habe.
Cü
Kai
Grütze .. äh ... Grüße!
Text = document.createTextNode(Inhalt[i].Inhalt);
Mir fällt gerade noch diese Zeile auf. Das könnte evtl. schiefgehen, da du "Inhalt" sowohl für das Array wie auch als Bezeichner im Daten-Objekt benutzt.
Und weil ich gerade eh keine Ruhe finde hier auch gleich die Schleife für die Tabellenzellen:
var Ausgaben = ["DVD_Nr","Titel","Inhalt","Genre","FSK"];
for ( var j = 0 ; j < Ausgaben.length ; j++ ) {
Zelle = document.createElement("td");
Zelle.style.whiteSpace ="nowrap"
Zelle.id = "Zelle" + i + j; //falls nötig
var inh = Inhalt[i];
Text = document.createTextNode(inh[Ausgaben[j]]);
Zelle.appendChild(Text);
Zeile.appendChild(Zelle);
}
"j" müssen wir hier nehmen, weil die Schleife innerhalb der for-Schleife mit "i" liegt.
Kannste ja dann (wenn die Tabellen-Erzeugung grundsätzlich wieder klappt) mal an einer Kopie testen oder den anderen Teil auskommentieren.
Ebenfalls ungetestet und so weiter wie im Vorbeitrag
Cü
Kai