JavaScript HTML li Elemente in einer for Schleife erstellen

Andreasb.

Lt. Junior Grade
Registriert
Jan. 2011
Beiträge
271
Hallo,
ich möchte in einer for Schleife in JavaScript <li></li> Elemente erstellen und diese mit verschiedenen Inhalten darstellen.
Für das Design der Liste benutzte ich JQuery Mobile.

Das Problem ist einmal das ich die Variable i als id für die Listenelemente nehmen möchte, aber i immer den gleichen Wert hat. Das andere Problem ist, dass die ListItems nicht das richtige Design haben, das von JQuery Mobile vorgegeben ist.

So sieht der JavaScript Code aus:
Code:
$("document").ready(function(){                          
      var anzahl;
      var ausgeben;
                        
      var zaehlen = $.ajax({  
               type: "POST", 
               url: "Liste",  
               dataType: "json",
               data: {abfrage: "zaehlen"}
               });
                  zaehlen.done(function(data){
                  $("div#meldung").text("Anzahl:" + data.anzahl).show();
                  anzahl = data.anzahl;
                  for (var i = 1; i < anzahl; i++){
                         ausgeben = $.ajax({  
                            type: "POST", 
                            url: "Liste",  
                            dataType: "json",
                            data: {abfrage: "ausgeben", personalnummer: i}
                         });
                         ausgeben.done(function(data){
                                
                          var neuesLi = document.createElement("li");
                          var neuesA = document.createElement("a");
                          neuesA.setAttribute("href","#" + i + ".html")
                          neuesLi.id=i;
                          neuesA.innerHTML = data.vorname;
                          $("#" + i).append(neuesA);
                          neuesLi.setAttribute("data-theme", "c");   
                          $("#liste").append(neuesLi); 

                     });
               } 

     }); 
});

Ich bekomme als Ergebnis ein li mit der id 7 (höchster Wert für i) in dem alle Vornamen aufgelistet sind. Die Links unter a sind nur Beispiele.
 
Mahlzeit,

Ich vermute, dass es an folgendem liegt:
"ausgeben" ist ganz oben einmal definiert und wird quasi für jeden Ajax-Request überschrieben.
D.h. hier wird scheinbar am Ende nur der letzte Request bearbeitet.
Hier wäre es meiner Meinung nach besser, für jeden Ajax-Request eine eigene Variable zu verwenden.
(ggf. in Zeile 15: var ausgeben = ...)

Für i gilt mehr oder weniger das gleiche.
Du gehts durch alle "i"s und führst Ajax-Requests aus.
Die Ajax-Request werden ihrem Namen entsprechend asynchron ausgeführt.
D.h. erst wird i hoch gezählt und quasi-parallel (sprich: nacheinander ;-)) werden Ajax-Responses verarbeitet.
Hier würde ich dir Vorschlagen, jeden Ajax-Request in eine Funktion auszulagern:

Code:
for(var i=0;i<anzahl;i++) {
	doAjax(i);
}
...

function doAjax(i) {
	var ausgaben = $.ajax
	...
}

Gruß

UPDATE:
Ich nehme an, du willst die Daten in ihrer "richtigen Reihenfolge" laden?
Ajax-Responses können durch die "Asynchronität" in unterschiedlicher Reihenfolge erfolgen.
D.h. wenn du Request 1-10 gleichzeitig losschickst, kann es passieren, dass erst Response 2, dann 5, dann 7, dann 1 usw. (also wild durcheinander) eintreffen.
Daher bzgl. der Reihenfolge gesondert behandeln!

Besser wäre hier z.B. die Requests zu bündeln und die Daten von 1-anzahl in einem Request zu laden und nicht in "anzahl" verschiedenen.

Außerdem:
Zeile 26: das ID-Attribut darf (eigentlich) nicht mit einer Zahl beginnen. (Buchstaben davor und du bleibst Standard-konform)
 
Zuletzt bearbeitet:
Mit diesem Code wird nichts mehr ausgeben:

Code:
$("document").ready(function(){                          
                        var anzahl;
                        
                        var zaehlen = $.ajax({  
                            type: "POST", 
                            url: "Liste",  
                            dataType: "json",
                            data: {abfrage: "zaehlen"}
                            });
                            zaehlen.done(function(data){
                                $("div#meldung").text("Anzahl:" + data.anzahl).show();
                                anzahl = data.anzahl;
                            for (var i = 1; i < anzahl; i++){
                                doAjax(i);

                                }
                                
                              function doAjax(i){
                               var ausgeben = $.ajax({  
                                    type: "POST", 
                                    url: "Liste",  
                                    dataType: "json",
                                    data: {abfrage: "ausgeben", personalnummer: i}
                                });
                            ausgeben.done(function(data){
                                
                            
                            var neuesLi = document.createElement("li");
                            var neuesA = document.createElement("a");
                            neuesA.setAttribute("href","#" + i + ".html")
                            neuesLi.id="mitarbeiter" + i;
                            neuesA.innerHTML = data.vorname;
                            $("#" + "mitarbeiter" + i).append(neuesA);
                            neuesLi.setAttribute("data-theme", "c");   
                            $("#liste").append(neuesLi); 


                            });
                                }
                                
                            }); 

                         });

Ist es vielleicht einfacher wenn ich den HTML Code als String von dem Java Servlet an die JavaScript Seite schicke?
 
Code:
$("document").ready(function(){
	var anzahl;
	var zaehlen = $.ajax({
		type: "POST",
		url: "Liste",
		dataType: "json",
		data: {abfrage: "zaehlen"}
		});
		zaehlen.done(function(data){
			$("div#meldung").text("Anzahl:" + data.anzahl).show();
			anzahl = data.anzahl;
			for (var i = 1; i < anzahl; i++){
				doAjax(i);
			}
		});
	});
});
	
function doAjax(i){
	var ausgeben = $.ajax({
		type: "POST",
		url: "Liste",
		dataType: "json",
		data: {abfrage: "ausgeben", personalnummer: i}
	});
	ausgeben.done(function(data){
		var neuesLi = document.createElement("li");
		var neuesA = document.createElement("a");
		neuesA.setAttribute("href","#" + i + ".html")
		neuesLi.id="mitarbeiter" + i;
		neuesA.innerHTML = data.vorname;
		$("#" + "mitarbeiter" + i).append(neuesA);
		neuesLi.setAttribute("data-theme", "c");
		$("#liste").append(neuesLi);
	});
}

so in der Art.

Ob es "einfacher ist" kann ich nicht beurteilen.
Musst du halt abwägen.
Entweder "schlankes JSON" und "viel Javascript-Logik"
oder
"voluminöses HTML" und "wenig Javascript-Logik"
 
Hier liegt eindeutig noch ein großes Software-Design-Problem vor:

1. AJAX-Requests sind teuer. D.h.: So wenig wie möglich und so viel wie nötig machen.

2. (eher ein Schönheitsfehler): Du benutzt POST um Daten abzufragen. GET, POST, etc. wurden geschaffen, damit man das ganze logisch gliedern kann. Siehe: http://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-Request-Methoden
Kurzform: Mit GET fordert man Daten an und mit POST schickt man Daten. D.h. du solltest GET benutzen ;)

3. Die Antworten auf deine AJAX-Requests kommen in beliebiger Reihenfolge an. Beispiel:
anzahl = 5. Dann schickst du quasi-parallel 5 AJAX-Requests ab. Dabei kann(!) es passieren, dass du die Antworten in dieser Reihenfolge erhältst: 4,5,2,1,3. Aber vielleicht spielt das keine entscheidende Rolle.



Um noch mal auf Punkt 1. zurück zu kommen: Wenn ich mir den Code anschaue, dann weiß ich sofort, dass du auf jeden Fall x AJAX Requests schickt, wenn dein Server dir vorher sagt, dass es x Einträge in der Liste gibt.
Also lässt sich das ganze extrem vereinfachen: Du schickst genau einen AJAX-Request ab und der liefert dir direkt ALLE Einträge in einem Array (im JSON Format). Damit löst du auch gleichzeitig das Problem von Punkt 3.
Du erhältst also ein Array (das auf dem Server beliebig vorsortiert werden kann) und dann iterierst du darüber und gibst die Liste aus.
 
@DHundt ich bekomme mit der Funktion irgendwie keine Ausgabe mehr.

Das mit dem Array habe ich schonmal ausprobiert, aber das Problem war, dass ich das Java Array nicht in einem JavaScript Array speichern konnte.
Kann man auch ein Array mit Objekten wie "Mitarbeiter" senden oder sollte man die Attribute der Mitarbeiter erstmal in ein String Array speichern und dann an JavaScript senden?
 
Zuletzt bearbeitet:
Denk nicht so kompliziert. In Java gibt's für jedes Problem eine simple Lösung. Meist heißt sie: Bibliothek suchen, runterladen, einbinden, benutzen ;)

Um beliebige Java Objekte in JSON zu übersetzen, solltest du dir mal Gson und/oder Jackson anschauen.
 
Mahlzeit,

So sollte der ursprüngliche Code funzen:
Code:
jQuery(document).ready(function(){
	$.ajax({
		type: "GET",
		url: "Liste",
		dataType: "json",
		data: {abfrage: "zaehlen"}
	}).done(function(data){
		$("div#meldung").text("Anzahl:" + data.anzahl).show();
		var anzahl = data.anzahl;
		for (var i = 1; i < anzahl; i++){
			doAjax(i);
		}
	});
});

function doAjax(i){
	$.ajax({
		type: "POST",
		url: "Liste2",
		dataType: "json",
		data: {abfrage: "ausgeben", personalnummer: i}
	}).done(function(data){
		var neuesA = $("<a>");
		neuesA.attr("href","#" + i + ".html");
		neuesA.html(data.vorname);
		
		var neuesLi = $("<li>");
		neuesLi.attr('id', "mitarbeiter" + i);
		neuesLi.append(neuesA);
		neuesLi.attr("data-theme", "c");
		$("#liste").append(neuesLi);
	});
}

Gruß
 
Irgendwie kann ich mit dem Array in JavaScript nichts anfangen. Wenn ich data ausgebe wird [object Object],... ausgegeben und Firebug zeigt auch, dass die richtigen Daten übertragen werden. Aber wie kann ich die Objekte aus dem Array in JavaScript benutzten?
 
Firebug zeigt dir sicherlich sowas oder? ->

Code:
[
  {"vorname":"Hans"},
  {"vorname":"Dieter"}
]

oder so:
Code:
{
  "inhalt":[
    {"vorname":"Hans"},
    {"vorname":"Dieter"}
  ]
]

In jedem Fall kannst du das wie ein normales JavaScript Object benutzen, z.B. so (wenn ich mich recht entsinne) ^^:
Code:
// Für den oberen Fall:
alert(data[0].name);
alert(data[1].name);

// Für den unteren Fall:
alert(data.inhalt[0].name);
alert(data.inhalt[1].name);


EDIT: Wenn es wirklich als JSON String ankommt, dann so:
Code:
data = '[{"vorname":"Hans"},{"vorname":"Dieter"}]';

var array = JSON.parse(data);

alert(array[0].name);
alert(array[1].name);
 
Zuletzt bearbeitet:
Code:
var data = [{
 name: "James Bond",
 trinkt: function(){
  return this.name + "trinkt gerne Martini!";
 }
},  
{
 name: "Weißbier Waldi",
 trinkt: function(){
  return this.name + "trinkt gerne Weizen!";
 }
}];
Zugriff:

Code:
data[0].name; // Ausgabe: James Bond
data[0].trinkt(); // Ausgabe: James Bond trinkt gerne Martini

Das ganze dann in eine for Schleife, wenn du mehrere Personen im data Objekt hast.
 
Zuletzt bearbeitet:
Danke. Mit dem Array funktioniert jetzt alles.
Leider funktioniert es noch nicht die ListItems zu erstellen.
Bei dieser Funktion wird gar nichts angezeigt:

Code:
               for (var i = 1; i < mitarbeiter.length; i++){
                                           
                    var neuesLi = document.createElement("li");
                    var neuesA = document.createElement("a");
                    neuesA.setAttribute("href","#" + i + ".html")
                    neuesLi.id="mitarbeiter" + i;
                    neuesA.innerHTML = mitarbeiter[i].vorname;
                    neuesLi.setAttribute("data-theme", "c");
                    $("#" + "mitarbeiter" + i).append(neuesA);
                    $("#liste").append(neuesLi);
                        
                }


Bei dieser wird immerhin die Liste mit den Vornamen erstellt:

Code:
               for (var i = 1; i < mitarbeiter.length; i++){
                    var neuesLi = document.createElement("li");
                    neuesLi.id="mitarbeiter" + i;
                    neuesLi.innerHTML = mitarbeiter[i].vorname;    
                    neuesLi.setAttribute("data-theme", "c");
                    $("#liste").append(neuesLi);                   
                }
 
Du solltest dir auch die Reihenfolge der Dinge anschauen...

1. du erstellst ein li
2. du erstellst ein a

3. du sagst dem li, dass es #mitarbeiterX als id hat

4. du sagt jQuery: füge das a innerhalb vom Element mit id=mitarbeiterX in den DOM Tree ein
5. du fügst das li in den DOM Tree ein.

vielleicht solltest du 4. und 5. tauschen ;)


P.S. 4. funktioniert nicht, weil es (noch) kein Element mit id=mitarbeiterX im DOM gibt.
 
Zuletzt bearbeitet:
Super, Danke!
Zusätzlich musste ich für jQuery noch :
Code:
                    $('#liste').trigger('create');    
                    $('#liste').listview('refresh');

hinzufügen, damit die Liste richtig dargestellt wird.
Hier ist der ganze Code, falls den jemand braucht:

Code:
               for (var i = 1; i < mitarbeiter.length; i++){
                                           
                    var neuesLi = document.createElement("li");
                    var neuesA = document.createElement("a");
                    neuesA.setAttribute("href","#" + i + ".html")
                    neuesLi.id="mitarbeiter" + i;
                    neuesA.innerHTML = mitarbeiter[i].vorname;
                    neuesLi.setAttribute("data-theme", "c");     
                    neuesA.setAttribute("data-transition", "slide");
                    $("#liste").append(neuesLi); 
                    $("#" + "mitarbeiter" + i).append(neuesA);  
                    $('#liste').trigger('create');    
                    $('#liste').listview('refresh');
       
                }
 
Finale Aufgabe: Code Refactoring!
Du erstellst bzw. aktualisierst in jeden Schleifendurchlauf die DOM Elemente, was sehr ineffizient ist, denn DOM Operationen sind sehr langsam.
 
Ist es so besser?
Code:
               for (var i = 0; i < mitarbeiter.length; i++){
                   
                    var neuesLi = document.createElement("li");
                    var neuesA = document.createElement("a");                 
                    neuesLi.setAttribute("data-theme", "c");     
                    neuesA.setAttribute("data-transition", "slide");                                           
                    neuesA.setAttribute("href","#" + i + ".html")
                    neuesLi.id="mitarbeiter" + i;
                    neuesA.innerHTML = mitarbeiter[i].personalnummer + " " + mitarbeiter[i].vorname + " " + mitarbeiter[i].nachname;
                    $("#liste").append(neuesLi); 
                    $("#" + "mitarbeiter" + i).append(neuesA);  
      
                }
                
                    $('#liste').trigger('create');    
                    $('#liste').listview('refresh');

oder kann man noch andere Operationen "einsparen"?
 
Zurück
Oben