[jQuery] Filter Liste mit chained select?

Schwer zu erklären...
Ich hab mal was geschrieben...
Ich hoffe die Kommentare helfen dir weiter.

Es gibt natürlich mehrere Möglichkeiten soetwas zu schreiben.
Hier wäre mein Ansatz.

Noch kurz zur ID-Vergebung:
Die ids der Kategorien haben 7 Ziffern:
Die 1. für die Ebene: 1010000
Die 2. - 7. für die eigene bzw. unterID: 1010000 <--- erste Ebene
Die letzte Ziffer, die nicht 0 ist, ist immer die eigene ID
Anderes Beispiel: 3010201 <--- 3 steht für dritte Ebene
01 dass die erste Oberkategorie die ID 01 besitzt,
02, dass die zweite Oberkategorie die ID 02 besitzt und die letzten zwei Ziffern
01, ist die eigene ID

Bei den Dokumenten sind die Ziffern nach dem : die eigene ID
Die Ziffern davor sagen aus, welcher Kategorie sie unterliegen.
Das d steht einfach statt der Zahl der Ebene für dokumente... ist ja egal.
kann man auch anderes draus machen.


Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Script</title>
		<style type="text/css">
			html {
				background-color: #F1F1F1;
			}
			.boxWrapper {
				margin-left: auto;
				margin-right: auto;
				width: 600px;
				height: 200px;
				background-color: yellow;
			}
			.boxWrapper ul {
				padding: 0;
				margin: 0;
				width: 200px;
				height: 200px;
				background-color: #FFF;
				list-style: none;
				overflow-y: scroll;
			}
			.boxWrapper li {
				padding-left: 4px;
			}
			.boxWrapper li:hover {
				cursor: pointer;
				background-color: #FFFF00;
			}
			.active {
				background-color: #FFFF00;
			}
			.boxLeft {
				float: left;
			}
			.boxRight {
				float: left;
			}
			.boxMiddle {
				float: left;
			}
			.contentWrapper {
				margin-left: auto;
				margin-right: auto;
				width: 800px;
				border: solid 1px black;
			}
			.productWrapper {
				background-color:white;
				margin:10px;
				height:150px;
				font-size:16pt;
			}
			.productWrapper h1{
				font-size:14pt;
			}
			.productWrapper h2{
				margin:0 0 0 4px;
				font-size:10pt;
			}
			.productWrapper h3{
				margin:0 0 0 4px;
				font-size:12pt;
			}			
			.productLeft {
				float:left;
			}
			.productPic{
				background-image:url(http://www.cornelsen.de/fm/1485/klassendienst_3129085_thumb.jpg);
				width:100px;
				height:100px;
			}
			.productCont{
				padding:5px 0 0 120px;
				}			
		</style>
		<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
		<script>
			var besser = {
				"boxTitle" : {
					"Arbeit mit der Klasse" : {
						"id" : 1010000,
					},
					"Arbeit mit den Schülern" : {
						"id" : 1020000,
					},
					"Arbeit mit den Eltern" : {
						"id" : 1030000,
					},
					"Disziplin/Regeln" : {
						"id" : 2010100,
					},
					"Organisation" : {
						"id" : 2010200,
					},
					"Probleme/Konflikte" : {
						"id" : 2010300,
					},
					"Fördern" : {
						"id" : 2020100,
					},
					"Motivation" : {
						"id" : 2020200,
					},
					"Einzelanschreiben" : {
						"id" : 2030100,
					},
					"Elternabend" : {
						"id" : 2030200,
					},
					"Rundbriefe" : {
						"id" : 2030300,
					},
					"Sprechstunde" : {
						"id" : 2030400,
					},
					"Klassenbuch" : {
						"id" : 3010201,
					},
					"Mediation" : {
						"id" : 3010202,
					},
					"Schulschläger" : {
						"id" : 3020101,
					},
					"Kochhilfe" : {
						"id" : 3020202,
					},
					"Babysitter" : {
						"id" : 3030201,
					},
					"Vater muss arbeiten" : {
						"id" : 3030202,
					}					
				},
				"documente" : {
					"d030400:0001" : {
						"title" : "Vorbereitung eines Elterngesprächs",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d030400:0002" : {
						"title" : "Notenübersicht für einen Schüler",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d030100:0001" : {
						"title" : "Telefongespräch (Elternbrief)",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d020100:0001" : {
						"title" : "Übersicht zu Förderbereichen",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d010201:0001" : {
						"title" : "Klassendienst",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d010201:0002" : {
						"title" : "Wochenplanung",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					},
					"d010202:0001" : {
						"title" : "Übersicht zu Verhaltensauffälligkeiten",
						"kat" : "Arbeitsblätter",
						"inhalt" : "blaa blabla blablalbalbaaa",
						"preis" : "0,80",
					}
				}
			}

			var boxApp = {
				//Hier wird das Objekt in dem die Daten abgespeichert werden initialisiert
				boxData : false,

				//Die Function init() - wie sie schon sagt - initiiert das Programmchen
				init : function() {
					//Nun werden die Daten in das Objekt boxData gespeichert
					boxApp.boxData = besser;
					//Beim ersten Aufruf muss die erste Ebene befüllt werden
					//dies geschieht mit der Funktion getSubData OHNE Parameter die übergeben werden
					boxApp.getSubData();
				},

				//In der Funktion count() wird die Anzhal der Documente gezählt,
				//die unter der Rubrik mit der jeweiligen ID fallen
				count : function(id) {
					//Counter wird standart auf 0 gesetzt
					var counter = 0;
					//Da der Übergebene Parameter id Typ des Integers ist,
					//mit Anhängen von "" zum String umgewandelt
					var str = id + "";
					//Initialisieren und Befüllen der Quellebene
					//die Funktion substr geht nur mit einem String,
					//daher eine Zeile weiter oben die Umwandlung in String
					//Die Ebene wird benötigt um die Anzahl der Zahlen aus der ID festzustellen
					//Die erste Ziffer einer ID sagt an in welcher Ebene sich die Kategorie befindet
					var ebene = str.substr(0, 1);
					//Initialisieren der Variable search, die für den Abgleich benötigt wird,
					//ob ein Dokument auch zu der gefragten Kategorie fällt
					var search;
					//Bei Ebene 1 werden die ziffern 2-3, Ebene 2 die Ziffer 2-5
					//und Ebene 3 die Ziffer 2-7 der jeweiligen ID zum Abgleich benötigt
					search = str.substr(1, 2 * parseInt(ebene));
					//Alle Dokumente befinden sich in boxApp.boxData['documente'],
					//von daher wird jedes Dokument aufgerufen um die ID abgleichen zu können
					$.each(boxApp.boxData['documente'], function(id, val) {
						//aus der Variable id, die von dem Dokument kommt, werden die 2. bis max. 7 Ziffer abgeschnitten
						var temp = id.substr(1, search.length);
						//falls die benötigten Ziffer der id des dokumentes mit der id der quell-Kategorie
						//übereinstimmt, wird die variable counter um 1 erhöht.
						if (temp == search)
							counter++;
					});
					//Nachdem alle Dokumente abgeglichen wurden, geben wir hier die Anzahl der
					//Treffer zurück
					return counter;
				},
				//setEvents() setzt die benötigten click Events
				setEvents : function() {
					//Hier soll es reingehen, wenn in der Box ein li angeklickt wird
					$(".boxWrapper li").click(function() {
						//Falls auf einer Kategorie gedrückt wurde, die schon gedrückt war
						if ($(this).hasClass("active"))
							//Bricht darafhin die Aktion ab, da die Daten ja schon geladen sind
							return false;
						//Hier wird herausgefunden, aus welcher der drei Boxen geklickt wurde
						var parentClass = $(this).parent().attr("class");
						//Falls es in dieser Box schon eine aktive Kategorie gibt,
						if ($("." + parentClass + " li").hasClass("active"))
							//wird dieser die Klasse active abgenommen
							$("." + parentClass + " li").removeClass("active");
						//Hier wird dem geklickten li die Klasse active zugewiesen
						$(this).addClass("active");
						//Hier wird der Name der Kategorie ausgelesen auf die geklickt wurde
						var name = $(this).text();
						//Dadurch, dass die Anzahl der Dokumente hinter den Namen steht,
						//müssen wir heruasfinden, an welcher Stelle dies anfängt
						var end = $(this).text().indexOf("(");
						//Hier wird die Anzahl z.B. (3) vom Namen entfernt
						var name = name.substring(0, parseInt(end - 1))
						//Hier werden die nächsten Unterkategorien der geklickten Kategorie geladen
						//Übergeben wird der Name der geklickten Kategorie
						boxApp.getSubData(name);
					});
				},
				//in getSubData() werden die Unterkategorien geladen. Der Parameter name steht für den
				//Namen der geklickten Kategorie
				getSubData : function(name) {
					//initialisieren der Zielebene
					var ebene;
					//Die id wird für den Abgleich benötigt aber dazu Unten mehr
					var id;
					//Falls kein Parameter übergeben wird, handelt es sich um die Initialisierung des
					//Programmchens
					if (name === undefined) {
						//Deshalb muss die Ebene statisch auf 1 gesetzt werden.
						ebene = 1;
						//Die ID muss 0 sein, da es sich um die Initialisierung des Programmes handelt
						//und somit alles Kategorien der Ebene 1 geladen werden müssen
						id = 0;
					} else {
						//Falls ein Parameter übergeben wurde, wird die jeweilige ID des
						//dazugehörigen Namens der Kategorie ausgelesen
						id = boxApp.boxData['boxTitle'][name]["id"] + "";
						//Hier die ebene aus der geklickt wurde aus der ID genommen
						ebene = id.substr(0, 1);
						//Hier werden die benötigten Ziffern aus der ID für den Abgleich geholt
						//Wieder Ebene 2 = Ziffer 2-5 und ebene 3 = Ziffer 2-7
						id = id.substr(1, 2 * parseInt(ebene));
						//Da wir die Quellebene nicht mehr brauchen, wird sie zur Zielebene gemacht.
						//Und es ist logisch, dass wenn man in die erste Ebene klickt, die zweite will.
						//oder von der 2ten in die 3te... also ebene eins höher!
						//parseInt() benutze ich übrigens, da wir die ebene aus einem String haben
						//und wenn wir damit rechnen wollen, müssen wir sie wieder als Typ integer umwandeln
						ebene = parseInt(ebene) + 1;
						//Wenn die Zielebene die zweite ist, soll der Inhalt der mittigen und der rechten Box
						//gelöscht werden
						if (ebene == 2)
							$(".boxMiddle li,.boxRight li").remove();
						//Falls die Zielebene die dritte ist, soll natürlich nur der Inhalt der rechten gelöscht werden
						else if (ebene == 3)
							$(".boxRight li").remove();
					}
					//Hier wird der Klassenname festgelegt, in welcher Box die Daten gespeichert werden
					var target;
					if (ebene == 1)
						target = ".boxLeft"
					else if (ebene == 2)
						target = ".boxMiddle";
					else
						target = ".boxRight";
					//Jetzt wird jede Kategorie durchsucht und mit der ID überprüft, ob sie eine Unterkategorie
					//der geklickten Kategorie ist
					$.each(boxApp.boxData["boxTitle"], function(key, val) {
						//Hier wird die ID der gerade aufgerufenen Kategorie ausgelesen
						//und gleich mit + "" ein string aus dem integer gemacht
						var str = val["id"] + "";
						//Hier lesen wir gleich aus, in welcher Ebene sich die aktuell
						//geholte Kategorie befindet. Die erste Ziffer der ID sagt an in welcher Ebene sich was befindet
						var oEb = str.substr(0, 1);
						//Hier werden wieder Ziffer 2. bis max. 7 ausgelesen um heurauszufinden
						//ob die geholte Kategorie sich unterhalb der geklickten Kategorie befindet.
						var oId = str.substr(1, (parseInt(ebene) - 1) * 2);
						//Falls die Ebene (Ziffer 1 der ID) und die ID`s der geklickten und der geholten Kategorie übereinstimmen
						//(Ziffer 2-7 (Kommt auf die Tiefe der Ebene an)),
						if (oEb == ebene && oId == id) {
							//wird hie ein string erstellt, der den HTML-Code des li beinhaltet, den Namen der neuen Kategorien hat
							//und die Anzahl der Dokumente der Unterkategorie in Klammer dahinter geschrieben bekommt
							var str = "<li>" + key + " (" + boxApp.count(val["id"]) + ")</li>";
							//Hier wird nun das li bzw. die Variable str in die richtige Box,
							//deren Klassenname in targed steht, eingefügt
							$(target).append(str);
						}
					});
					//Sobald die li in die box geladen wurden, muss auch wieder der Eventhandler fürs klicken
					//aktualisiert werden, sonst kennt er nicht die neu hinzugefügten Elemente
					//Bzw. beim initialisieren überhaupt mal aktiviert werden ;)
					boxApp.setEvents();
					//Hier ist die Function, die die Dokumente ausgiebt
					boxApp.getDocuments(name);
				},
				//Gibt die Dokumente der jeweils gedrückten Kategorie aus...
				//Bzw. alle beim Initialisieren
				getDocuments : function(name) {
					//Nur bei der Initialisierung wird kein name mit übergeben
					//daher werden auch ertsmal ALLE dokumente unten angezeigt
					if (name === undefined) {
						//Hier ist nur mal schnell die Ansicht der Dokumente oder was dann auch immer
						//reingeladen wird... muss dann ja eh dementsprechent genau angepasst werden.
						$.each(boxApp.boxData['documente'], function(key, val) {
							var str="<div class=\"" + key + " productWrapper\">";
							str+="<div class=\"productLeft\">";
							str+="<div class=\"productPic\"></div>";
							str+="<h2>"+ val["kat"] +"</h2>";
							str+="<h3>"+ val["preis"] +" Euronen</h3>";	
							str+="</div><div class=\"productCont\">";
							str+="<h1>"+ val["title"] +"</h1>";
							str+=val["inhalt"]+"</div></div>";				
							$(".contentWrapper").append(str);
						});
					} else {
						//Sobalt eine Kategorie gedrückt wurde, werden alle Dokumente gelöscht...
						$(".contentWrapper").html("");
						//Hier kommt der Code der nötig ist, um Dokumente von gedrückten Kategorien
						//einblenden zu lassen. Bei Fragen, jederzeit fragen! ;)
					}
				}
			}

			jQuery(document).ready(function() {
                                //Hier wird das Programmchen gestartet...
				boxApp.init();
			});

		</script>
	</head>
	<body>
		<div class="boxWrapper">
			<ul class="boxLeft"></ul>
			<ul class="boxMiddle"></ul>
			<ul class="boxRight"></ul>
		</div>
		<div class="contentWrapper"></div>
		<br>
	</body>
</html>
 
Ich sollte vielleicht noch erwähnen, dass die Dokumente NUR am Anfang alle angezeigt werden.
Sobalt man eine Kategorie auswählt, werden Sie gelöscht und es werden keine neuen geladen.

Jetzt hab ich soweit schon alles geschrieben, den Rest kann man ja wohl selber machen. ;)
Bin aber für Fragen gerne zu haben.

Hier mal der Link für die Live-Show:

http://jsbin.com/ikopin/1/edit

Gruß!
 
wow danke! Zur Not werde ich das nehmen aber ich versuchs auch mal selbst :)

Zwischenzeitlich hatte ich auch einen Lösungsansatz und wollte diesen weiterführen.
Ich frage mich nun, wie ich die einzelnen Knoten in meiner json file ansprechen kann.

Ich habe folgende JSON:
Code:
{
  "Arbeit mit der Klasse": {
    "id": 100000,
    "DisziplinRegeln": {
      "id": 101000
    },
    "Organisation": {
      "id": 102000,
      "Klassenbuch": {
        "id": 102010
      }
    },
    "Probleme/Konflikte": {
      "id": 103000,
      "Mediation": {
        "id": 103010
      }
    }
  },
  "Arbeit mit Schülern": {
    "id": 200000,
    "Fördern": {
      "id": 201000
    },
    "Motivation": {
      "id": 202000
    }
  },
  "Arbeit mit Eltern": {
    "id": 300000,
    "Einzelanschreiben": {
      "id": 301000
    },
    "Elternabend": {
      "id": 302000
    },
    "Rundbriefe": {
      "id": 303000
    },
    "Sprechstunde": {
      "id": 304000
    }
  }
}

Und mein HTML:

Code:
<!DOCTYPE html>
<html>
  <head>
    <style>
			ul, li { margin:0; padding:0; display:block; list-style:none; }
		</style>
  </head>
  
  <body>
     
    <ul id="box1">
      <!-- jquery -->
    </ul>
    
    <hr />
    
    <ul id="box2">
      <!-- jquery -->
    </ul>
    
    <hr />
    
    <ul id="box3">
      <!-- jquery -->
    </ul>
    
    <script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
    <script>
			$(document).ready(function(){ 
				
				// Generate first select
				$.getJSON('data.json',function(data) {            
					var items = [];
					
						$.each(data, function(key, value) {
							items.push('<li id="' + key + '">' + key + '</li>');
						});
						
						var html = items.join('');
						$("#box1").append(html);
				});
				
				// Change events
				$("#box1 li").live("click", function(){
					var id = $(this).attr("id");

					$.getJSON('data.json',function(data) {            
						var items = [];
						
						$.each(data, function(key, value) {
							items.push('<li id="' + value.id + '">' + key + '</li>');
						});
						
						var html = items.join('');
						$("#box2").append(html);
					});
				});
				
				
			});
		</script>
    
  </body>
</html>

Die erste Liste mit den Hauptkategorien füllt sich schonmal.
Die 2 Liste macht noch probleme, weil ich es nicht hinbekomme, die entsprechenden Werte zu selektieren.

Ist meine JSON evtl. falsch aufgebaut?
 
Hey!

Warum auch immer, geht bei mir lokal das laden von Json mit der Funktion
$.getJSON() nicht... von daher kann ich es nicht ausprobieren.

Mit Json bin ich mir nicht sicher bzw. weiß ich nicht ob jQuery etwas besonderes mit
der geladenen Datenstrucktur anstellt.
Aber ich glaub, du kannst deine Json daten genauso wie ein Array/Objekt ansprechen.

Bsp.:
Code:
alert(data["Arbeit mit der Klasse"]["DisziplinRegeln"]["id]);//Würde 101000 ausgeben

Bitte verbessert mich, falls das nicht so ist. Wie gesagt, konnte es nicht ausprobieren
und hab im Mom. kein Nerv dazu mich mit diesen Problem auseinander zu setzen.

Aber so sollte die zweite Box geladen werden, da jQuery unter $.each() mit Arrays arbeitet.
Code:
				// Change events
				$("#box1 li").live("click", function() {
					var id = $(this).attr("id");

					$.getJSON('data.json', function(data) {
						var items = [];

						$.each(data, function(key, value) {
							if (value["id"] == id) {
								$.each(data[key], function(ersteres, zweiteres) {
									if (ersteres != "id")
										items.push('<li id="' + zweiteres[id] + '">' + key + '</li>');
								});
							}
						});

						var html = items.join('');
						$("#box2").append(html);
					});
				})
Dein Problem ist, dass du deine Daten in der Jquery verschachtelt hast, deshalb musst du auf der obersten
Ebene eine Abfrage über die ids machen ob du gerade an der Kategorie angekommen bist,
die angeklickt wurde. Wenn ja, musst du ein weiteres $.each() durchführen lassen,
dass dir die Unterkategorien ausliest... da ist jetzt aber auch die id der Oberkategorie dabei.
Die muss übersprungen werden.

Logischerweise musst du dann für die dritte Box insgesamt 3 $.each() verschachtelt durchlaufen lassen.
Das geht, ist meines Erachtens nach aber umständlich.
Aber vom Prinzip, vergleichst du dann in der ersten $.each nur die erste Ziffer der aktuell geholten
und der geklickten Kategorie, dann in der nächsten $.each(), vergleichst du die 2. und 3. Ziffer
und in der dritten $.each, lässt du dann wieder deine <li>'s erzeugen.

UND speicher deine JsonDaten am Anfang doch einmal in eine 'variable'.
Dann musst du nicht immer wieder die Daten holen, sondern kannst dann bei jedem $.each()
die Variable\das Array\das Objekt benutzen.
Ich weiß selber nicht sicher ob das dann als Objekt oder Array bezeichnet wird.
Ich denke Objekt aber belehrt mich bitte eines Besseren, wenn ich falsch liege.

Desweiteren hab ich das Gefühl, dass du mit Javascript/jQuery noch nicht viel gearbeitet hast,
kann das sein?

Gruß!
 

Neue Beiträge

Zurück