JScript-Code gesucht
Hi, alle!
In einer Tabelle mit x-Zeilen, möchte ich in einer oder in mehreren Zeilen, dass sich beim Öffnen der HTML-Seite die Hintergrundfarbe ändert, wenn der aktulle Monat mit dem in der ersten Spalte befindlichen Datum übereinstimmt. Das Datum kann dabei z.B so 02.03. bzw. so 02.03. - 06.03. dargestellt sein.
Wie kann ich das JScript mäßig lösen?
Danke!
Antwort schreiben
Antwort 1 von Hans55 vom 23.02.2020, 22:32 Options
...gibt es wirklich niemand, der mir helfen kann?
Antwort 2 von mr_x_hacker vom 23.02.2020, 22:49 Options
Hi,
wieviel JS kannst Du denn? Grundsätzlich geht das wie in jeder Programmiersprache :)
Also, etwa folgendermaßen:
- Tabelle besorgen:
var tab = document.getElementById("myTableId");
- Zeilen besorgen:
var rows = tab.getElementsByTagName("tr");
- Mit Schleife alle rows betrachten:
- Innerhalb jeder row die Zellen holen:
var cells = row[ i ].getElementsByTagName("td");
- Mit Schleife alle cells betrachten:
- Enthält die Zelle das aktuelle Datum?* -> Dann setze die Hintergrundfarbe der aktuellen Zeile, z.B. mittels
rows[ j ].style.background-color = "red";
*Das "komplexeste" dürfte wohl die Datumserkennung werden - hierzu kannst Du die Klasse "Date" benutzen, sowie die üblichen Stringfunktionen - siehe auch
Java-Script-ObjekteDu musst Dir halt klar werden, in welchem Format genau das Datum da drin steht, dann fragst Du das Date-Objekt nach dem aktuellen Datum und suchst nach Übereinstimmungen...
Ciao Sascha
Antwort 3 von katy vom 24.02.2020, 09:20 Options
Hallo Hans55,
grundsätzlich möchte ich Sascha in Antwort 1 zustimmen: Das Script müsstest du dir schon selbst schreiben, wir können dir aber gern dabei helfen.
Allerdings mchte ich für seine Tipps Alternativen vorschlagen, da sie ein bisschen umständlich sind und auch Fehlerquellen enthalten.
Statt
Zitat:
var rows = tab.getElementsByTagName("tr");
kannst du das einfachere
var zeile = tab.rows;
nehmen.
(der Variablenname
rows kommt in Konflikt mit dem Objekt rows, das schon vordefiniert ist)
entsprechend die Tabellenzellen statt:
Zitat:
var cells = row[ i ].getElementsByTagName("td");
über
var zelle=zeile[ i ].cells;
(auch
cells gibt es schon und ist daher als Variablenname ungegeignet)
den Inhalt einer Tabellenzelle erhältst du über
var text=zelle[ i ].firstChild.value;
(wenn die Zelle nicht noch weitere HTML-Elemente wie <br> oder <p> enthält)
Die Angabe zur Hintergrundfarbe müsstest du dann ändern über
zeile[j].style.backgroundColor = "red";
(ein Großbuchstabe für den wegfallenden Bindestrich!)
Die aktuelle Monatszahl erhältst du über
var aktMonat=(new Date()).getMonth()+1;
(nicht über die seltsame Klammerung wundern; die +1 kommt, weil JavaScript die Monate von 0-11 zählt)
Einen schönen Sonntag wünscht
katy
Antwort 4 von Hans55 vom 24.02.2020, 09:39 Options
Hi, @ mr_x_hacker
Danke für deine Hilfe.
Meine Javascript-Kenntnisse sind leider bescheiden. Ich weiss gerade mal, wie man es im HTML einbindet.
Ich habe im WEB schon nach einen ähnlichen Script gesucht, was ich hätte anpassen können. Bin aber nicht fündig geworden.
Vielleicht kannst du das mit dem Datum auslesen und vergleichen noch darstellen. Die Angabe in der Tabellenspalte erfolgt., wie in meiner Frage angegeben.
Ich glaube, schwierig wird es im Falle, wenn bei zwei Datumsangaben das Erste z.B. im Monat 01. und das Zweite im Monat 02. liegt. Also z.B. 30.01. - 03.02. die Angabe der Daten über den Monatswechsel erfolgt.
Gruß, Hans
Antwort 5 von mr_x_hacker vom 24.02.2020, 11:22 Options
Hi,
@katy:
Das kommt davon, wenn man das Script nur aus dem Kopf als "Pseudocode" schreibt, ohne es laufen zu lassen :) Mir kam "background-color" auch irgendwie seltsam vor, aber ich dachte, nach "style" kommt immer genau der "CSS-Name" des Attributs...
Dass man auf table.rows und row.cells direkt zugreifen kann, wußte ich bisher allerdings noch nicht - wieder was gelernt :) (eigentlich müsste man das auch im Firebug-DOM-View sehen können, muss ich bei Gelegenheit mal nachschauen...)
@hans:
Zunächst solltest Du wohl unterscheiden, ob in der Zelle genau ein Datum oder ein Bereich steht:
if (text.indexOf("-") > -1) { //text ist der Zelleninhalt, siehe katys Antwort
//Bereich
} else {
//Einzelnes Datum
}
Für einen Bereich würde ich dann die
Date.parse()-Methode verwenden, die wandelt ein Datum in die Anzahl Millisekunden seit 01.01.1970 um.
var minValue = Date.parse(firstPartOfRange);
var maxValue = Date.parse(secondPartOfRange);
var today = (new Date()).getTime();
if (today > minValue && today < maxValue) {
//"heute" ist innerhalb des Bereiches
}
Das ganze ist jetzt wieder weitgehend als Pseudocode zu verstehen, d.h. ich hab es nicht laufen lassen :)
Die "schmutzigen Details" (first/secondPartOfRange) muss Du mittels text.substring() bzw. allgemein mit den
String-Methoden machen.
Tipp: Besorge Dir das Firefox-Plugin
Firebug, damit kann man das erzeugt Script debuggen, d.h. Du kannst Breakpoints setzen wenn etwas nicht funktioniert, und siehst genau Schritt für Schritt was Dein Script tut und was es ggf. falsch macht...
Ciao Sascha
Antwort 6 von mr_x_hacker vom 24.02.2020, 11:36 Options
Nachtrag:
Ich sehe grade, die parse()-Methode ist nicht ganz so komfortabel wie ich es von anderen Date(Format)-Objekten gewohnt bin, deshalb wäre es wohl sinnvoller, das ganze über setDate() und setMonth() zu machen:
var myDateString = "02.03.";
var myDay = myDateString.substring(0,2); //"02"
var myMonth = myDateString.substring(3, 5); //"03"
var myDate = new Date();
myDate.setMonth(myMonth);
myDate.setDate(myDay);
var millis = myDate.getTime(); //der 02.03. in Millisekunden seit 1970
Mit den Millisekunden kannst Du dann rechnen wie oben beschrieben...
Ciao Sascha
Antwort 7 von katy vom 24.02.2020, 13:35 Options
Hi Sascha,
warum versuchst du das so kompliziert zu machen? Die einfache Methode über getMonth() hatte ich doch schon vorgestellt. Die so erhaltene Monatszahl reicht meiner Ansicht nach völlig aus zu einem Vergleich mit einem Datums-String.
Übrigens ist deine Funktion immer schon einen Monat weiter, da in JavaScript der Monat Nr. 3 der April ist.
Die Tücke liegt jetzt darin, diese Datums-String zu analysieren. Dazu kann aber nur Hans55 etwas sagen. Vorher lässt sich gar keine Vergleichsfunktion schreiben.
katy
Antwort 8 von mr_x_hacker vom 24.02.2020, 14:22 Options
Hallo katy,
Du hast Recht - hab jetzt erst gelesen, dass es ja nur um den aktuellen Monat geht... Ich ging die ganze Zeit davon aus, dass der aktuelle Tag hervorgehoben werden soll - und da fand ich es halt praktischer, die "übliche" Methode (=Millisekunden) zum Datumsvergleich zu verwenden, statt "if (tag == x && monat == y)"
So ist es nu natürlich viel einfacher:
- Falls kein Bereich vorliegt: Vergleiche den Monat mit dem aktuellen Monat
- Falls ein Bereich vorliegt: Teile den Bereich und vergleiche aus den beiden Teilen je den Monat mit dem aktuellen Monat... wenn einer davon übereinstimmt, kann die Zeile markiert werden...
Ciao Sascha
Antwort 9 von Hans55 vom 24.02.2020, 14:52 Options
Danke erstmal euch Beiden, dass Ihr euch die Zeit nehmt mir zu helfen.
Nochmal zur Erläuterung meines Vorhabens:
Siehe auch Anwort 4.
Es handelt sich bei der Tabelle, um einen Veranstaltungsplan für ein Jahr , beginnent mit Januar z.B. 05.01. und endet mit Dezember 27.12. Es können sich aber auch von - bis Angaben in den Zellen befinden, wie in Antwort 4 steht. Die Tagesangabe brauchen nicht berücksichtigt werden, nur die Monatsangabe. Abhängig von ihr, soll sich die Hintergrundfarbe für die Tabellenzeile nur für den jeweilig aktuellen Monat ändern.
Antwort 10 von katy vom 24.02.2020, 20:53 Options
Hallo Hans55,
also ich gehe jetzt mal davon aus, dass nur sowas vorkommt:
tt.mm
und
tt.mm - tt.mm
dann kannst du folgendes nutzen für eine Tabelle mit der ID "Tabelle"
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
var zeile = dieTabelle.rows;
for (var i = 0; i<zeile.length; i++) {
var zelle = zeile[ i ].cells;
for (var j = 0; j<zelle.length; j++) {
var text = zelle[j].firstChild.value;
bereich = text.split("-");
for (var a = 0; b<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[j].style.backgroundColor = "red";
}
}
}
(ungetestet)
katy
Antwort 11 von katy vom 24.02.2020, 20:59 Options
hoppla, wo bleibt nur meine Logik. Natürlich interessiert nur die erste Spalte.
Also mache ich's gleich ganz fertig:
function faerbeTabelle() {
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
var zeile = dieTabelle.rows;
for (var i = 0; i<zeile.length; i++) {
var zelle = zeile[ i ].cells;
var text = zelle[0].firstChild.value;
bereich = text.split("-");
for (var a = 0; b<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[j].style.backgroundColor = "red";
}
}
}
window.onload=faerbeTabelle;
wenn du dies in einen javaScript-bereich im head (oder extern) schreibst sollte das gewünschte eintreten.
katy
Antwort 12 von mr_x_hacker vom 24.02.2020, 21:30 Options
Nu will ich auch mal was verbessern *g*
for (var a = 0; b<bereich.length; a++)
ist vermutlich so besser:
for (var a = 0; a<bereich.length; a++)
:)
Ansonsten - schöne Lösung! Wenn ich sie mir so kurz vorgestellt hätte, hätte ich wohl auch lieber gleich den Code geschrieben statt jede Zeile einzeln herzuleiten... aber vermutlich wäre sie bei mir länger geworden... ^^
Ciao Sascha
Antwort 13 von katy vom 25.02.2020, 06:47 Options
Guten Morgen Sascha,
danke für die Korrektur. Leider fällt mir selbst gleich noch ein Fehler auf:
bereich ist als globale Variable deklariert. Außerdem wäre es sinnvoll zu prüfen ob "dieTabelle" überhaupt existiert.
Also nochmal eine Variante ohne diese Flüchtgkeitsfehler:
function faerbeTabelle() {
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
if (dieTabelle && dieTabelle.nodeName=="table") {
var zeile = dieTabelle.rows;
for (var i = 0; i<zeile.length; i++) {
var zelle = zeile[ i ].cells;
var text = zelle[0].firstChild.value;
var bereich = text.split("-");
for (var a = 0; a<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[j].style.backgroundColor = "red";
}
}
}
}
window.onload=faerbeTabelle;
einen schönen Tag wünscht
katy
Antwort 14 von Hans55 vom 25.02.2020, 10:15 Options
Ihr seit super. Danke!
Ich probiere es heute mal aus. Falls es nicht funktionieren sollte melde ich mich wieder.
Gruß, Hans
Antwort 15 von Hans55 vom 25.02.2020, 10:59 Options
Hi,
ich habe den Code aus der letzten Anwort im Head eingebaut. Es tut sich leider nix. Der Tabelle habe ich die id="Tabelle" gegeben. Hab ich evtl. noch was vergessen.
Und so sieht meine Beispiel-Tabelle aus:
19.01. Neujahrskonzert, 17 Uhr
09.02. Feuerwehrfasching, 19 Uhr
29.02. - 03.03. Polit-Comedy-Kabarett, 19 Uhr
21.03. - 23.03. Osterausstellung, 14 - 18 Uhr
Die beiden mittlersten Zeilen müssten eigentlich rot hinterlegt sein.
Antwort 16 von katy vom 25.02.2020, 16:44 Options
Hallo Hans55,
Zitat:
Es tut sich leider nix
ist leider keine sinnvolle Fehlerbeschreibung. Jedenfalls nicht, wenn du Hilfe erwartest.
Ist die Seite online, dann poste hier einen Link. Falls nicht poste den Quellcode, so wie du ihn umgesetzt hast.
Außerdem könntest du mal in die JavaScript- bzw. Fehler-Konsole des Firefox-Browsers schauen (Menü EXTRA) und uns die Fehlermeldungen von dort mitteilen.
katy
Antwort 17 von Hans55 vom 25.02.2020, 21:52 Options
Mit Firefox kann ich nicht dienen. Nutze nur den IE5.5.
Hier der Quellcode:
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>TestTabelle</title>
<meta name="author" content="">
<meta name="generator" content="Ulli Meybohms HTML EDITOR">
<script language="JavaScript">
<!--
function faerbeTabelle() {
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
if (dieTabelle && dieTabelle.nodeName=="table") {
var zeile = dieTabelle.rows;
for (var i = 0; i<zeile.length; i++) {
var zelle = zeile[ i ].cells;
var text = zelle[0].firstChild.value;
var bereich = text.split("-");
for (var a = 0; a<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[j].style.backgroundColor = "red";
}
}
}
}
window.onload = faerbeTabelle;
//-->
</script>
<style type="text/css">
<!--
.ablinks { margin-left:10px; font-size:8pt; }
.bg { background:#FFFFFF; }
-->
</style>
</head>
<body text="#000000" bgcolor="#FFFFFF">
<table id="Tabelle" align="center" width="590" border="0" cellpadding="0" cellspacing="0" style="border-width:1px 1px; border-style:solid; border-color:#F8E0B0;" summary="Infos">
<tr class="bg">
<td height="45" width="130" align="left">
<span class="ablinks"><b>19.01.</b></span></td>
<td align="left" style="font-size:8pt;">Neujahrskonzert, 17 Uhr <font color="#FF0000"></font></td>
</tr>
<tr class="bg">
<td height="20" align="left">
<span class="ablinks"><b>09.02.</b></span></td>
<td align="left" style="font-size:8pt;">Feuerwehrfasching, 19 Uhr</td>
</tr>
<tr class="bg">
<td height="24" align="left">
<span class="ablinks"><b>29.02. - 03.03.</b></span></td>
<td align="left" style="font-size:8pt;">Polit-Comedy-Kabarett, 19 Uhr
</td>
</tr>
<tr class="bg">
<td height="32" align="left">
<span class="ablinks"><b>21.03. - 23.03.</b></span></td>
<td align="left" style="font-size:8pt;">Osterausstellung, 14 - 18 Uhr</td>
</tr>
</table>
</body>
</html>
Antwort 18 von katy vom 26.02.2020, 07:58 Options
Hallo Hans55
ersetze deinen Code durch
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>TestTabelle</title>
<meta name="author" content="">
<meta name="generator" content="Ulli Meybohms HTML EDITOR">
<script type="text/javascript">
function faerbeTabelle() {
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
if (dieTabelle && dieTabelle.nodeName.toLowerCase()=="table") {
var zeile = dieTabelle.rows;
for (var i = 0; i<zeile.length; i++) {
var zelle = zeile[i].cells;
var text = zelle[0].firstChild.data;
var bereich = text.split("-");
for (var a = 0; a<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[i].className = "aktuell";
}
}
}
}
window.onload = faerbeTabelle;
</script>
<style type="text/css">
body {
color:#000;
background-color:#fff;
}
td.ablinks {
padding-left:10px;
font-size:8pt;
font-weight:bold;
}
tr.bg {
background-color:#FFF;
}
tr.aktuell {
background-color:red;
}
</style>
</head>
<body>
<table id="Tabelle" align="center" width="590" border="0" cellpadding="0" cellspacing="0" style="border-width:1px 1px; border-style:solid; border-color:#F8E0B0;" summary="Infos">
<tr class="bg">
<td height="45" width="130" align="left" class="ablinks">19.01.</td>
<td align="left" style="font-size:8pt;">Neujahrskonzert, 17 Uhr <font color="#FF0000"></font></td>
</tr>
<tr class="bg">
<td height="20" align="left" class="ablinks">09.02.</td>
<td align="left" style="font-size:8pt;">Feuerwehrfasching, 19 Uhr</td>
</tr>
<tr class="bg">
<td height="24" align="left" class="ablinks">29.0. - 03.02.</td>
<td align="left" style="font-size:8pt;">Polit-Comedy-Kabarett, 19 Uhr
</td>
</tr>
<tr class="bg">
<td height="32" align="left" class="ablinks">21.03. - 23.03.</td>
<td align="left" style="font-size:8pt;">Osterausstellung, 14 - 18 Uhr</td>
</tr>
</table>
</body>
</html>
und es funktioniert.
Ich hatte aber nun wirklich gefragt, ob in den Zellen was anderes steht außer den Daten. sonst hätte das völlig anders geschrieben werden müssen. Du hättest also die (überflüssigen) <span> und <b> erwähnen sollen. Deren Funktion habe ich im Stylesheet direkt den Zellen gegeben.
Bei der Gelegenheit habe ich noch ein paar Anpassungen des Scripts an deine Seite gemacht. Nun wird der Zeile nicht eine neue Hintergrundfarbe gegeben, sondern die Klasse wird geändert. auf "aktuell". Und was das für Layout-Folgen hat kannst du nun in aller Ruhe im Stylesheet festlegen und brauchst dafür das JavaScript nicht mehr zu ändern.
Wenn du selbst eine Seite erstellst möchte ich dir ans Herz lgen unbedingt zusätzlich mindestens den Firefox und Opera zu installieren. Der Internet-Explorer allein reicht nicht. Die Seite muss in allen 3 Browsern halbwegs gut aussehen und technisch OK sein. Der IE ist selbst viel zu fehlerhaft um als Kriterium für gute Seiten dienen zu können.
katy
Antwort 19 von katy vom 26.02.2020, 08:01 Options
verdammt, warum verschluckt diese Supportnet-Software immer die wichtigsten Indices?
Also nur der Funktions-Teil nochmal:
function faerbeTabelle() {
var aktMonat=(new Date()).getMonth()+1;
var dieTabelle = document.getElementById("Tabelle");
if (dieTabelle && dieTabelle.nodeName.toLowerCase()=="table") {
var zeile = dieTabelle.rows;
for (var j = 0; j<zeile.length; j++) {
var zelle = zeile[j].cells;
var text = zelle[0].firstChild.data;
var bereich = text.split("-");
for (var a = 0; a<bereich.length; a++) {
var daten = bereich[a].split(".");
if (parseInt(daten[1],10) == aktMonat) zeile[j].className = "aktuell";
}
}
}
}
Antwort 20 von Hans55 vom 26.02.2020, 11:03 Options
@Katy
Ich habe alles so übernommen wie in Antwort 18 angegeben.
Ich habe die Indices von Gänzefüßschen in Apostrophe geändert, trotzdem kommt der Fehler "[0] ist Null oder kein Objekt" in der Zeile:
var text = zelle[0].firstChild.data;
Muss in den Zeilen bei tr noch ein id=aktuell angegeben werden?