• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[GELÖST] Event registrieren in einer Schleife - zum Anfang der Methode springen?

kleimscheim

New member
Ich bin JS und jQuery Anfänger und steh grad auf dem Schlauch. Ich möchte auf einen Button ein click-Event registrieren. Im Event will ich, dass eigentlich wieder aus der DB geladen und die Tabelle neu gefüllt wird (siehe Quellcode). Vielleicht bringen mich die anonymen Methoden durcheinander bzw weiß ich nicht so recht wie das aufgebaut werden muss. Notfalls ginge auch die Tabellenzeile zu löschen aber das scheint nicht zu gehen.

PHP:
$(document).ready(function()
{
	$.getJSON("getpersons.php", function(data)
	{
		var items = [];
		var id = 0;
		
		$.each(data, function(key, val)
		{
			var appendstring = 
					"<tr id='tr-"+id+"'><td id='name-"+id+"'>" + val.name 
					+ "<td id='email-"+id+"'>" + val.email 
					+ "<td><button id='delete-"+id+"'></button>"
					+"</tr>";
			
			$("#tablePerson").append(appendstring);
			
			$("#delete-"+id).button({ text:false, icons:{primary:'ui-icon ui-icon-trash'}});
			
			$("#delete-"+id).click(function(){
				$.post("deletekunde.php", {name: val.name, email: val.email})
				.done(function(data){
					if(data != 0)
						alert(data);
						
					// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	
					// Funktioniert nicht: $("#tr-"+id).remove();  --> (?)
					// Am liebsten würde ich noch mal sauber aus der DB lesen und ausgeben
					// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					
				});
			});

			id++;
    [.......]

Achso ja - warum das .remove() nicht geht ist mir klar geworden. Es hat die id des letzten Tabelleneintrags +1. Hab mir daher die Id jetzt aus den aufrufendem Element geholt. Das klappt. Bleibt nur das Designproblem (?), wenn ich noch einen DB Zugriff machen wollte.
 
Zuletzt bearbeitet von einem Moderator:
Der Teil, der nicht funktioniert, sollte korrekt geschrieben sein - bspw. so:

Code:
$("#delete-"+id).click(function(){
	$.post("deletekunde.php", {name: val.name, email: val.email}, function(data){
		if(data != 0) alert(data);
	});
});

".done" kenne ich gar nicht als "callback"-Abwicklung ... aber hier hätte wohl jeder Debugger eh Alarm gemacht. ;)

Auch wundert mich, dass Du "deletekunde" die Information aus "#delete-"+id nicht mitgibst - bspw. in Form von $(this).attr("id") (damit auch der Server mitbekommt, wo Du geklickst hast - Name und E-Mail finde ich nicht eindeutig genug.

Das dürfte erstmal langen ... ;)
 
Der Teil, der nicht funktioniert, sollte korrekt geschrieben sein
ich sehe jetz bei ihm keinen fehler, wo soll der sein?

sein problem verstehe ich auch nicht, wenn er einen datensatz löschen will, muss er anschließend nur die zeile entfernen.
ist das entfernen der zeile das problem, oder warum soll die tabelle wieder neu aufgebaut werden?
wenn die tabelle neu aufgebaut werden soll, muss man sie löschen und dann wieder den json request, wieder anstoßen.
 
Schreibt man es hintereinander, steht da das (kenne ich nicht - habe es daher als Fehler eingestuft)

Code:
$.post("deletekunde.php", {name: val.name, email: val.email}).done(function(data){})

... daher steht da, dass ich ".done" nicht kenne. ;)


Na, oops ... den gibbet ... sorry, mislead!
 
Zuletzt bearbeitet:
Tja ich hätte mir meinen Beitrag noch mal durchlesen sollen. Also dass nur auf Name und Mail geprüft wird ist gewollt. Das Projekt dient nur zu Übungszecken und in der DB ist keine ID vorhanden. Das mit .done geht zumindest. Ich dachte das ist für den Zweck gedacht.

Also mein Gedanke war, dass ich immer wieder aus der DB lade, damit es kein Verwirrspiel mit den Element id´s gibt. Es sind noch weitere Buttons mit drin, die ich für das Beispiel weggelassen habe (edit, show, new). Und das wird schon einigermaßen kompliziert, da alles über ein Dialog Popup läuft um die Daten anzupassen. Und dann ist da auch noch die Reihenfolge. Bei new kann ich die Tabellenzeile eigentlich nur hinten ran klatschen, was dann nicht die Reihenfolge der DB Abfrage entspricht. Deshalb mein Wunsch immer wieder alles frisch aus der DB zu holen. Wenn ich das so machen würde, scheint es mir nur so, als würde das nicht gehen, da ich dann ja in der Methode (ich nenne sich mal) builtTableRow wieder builtTableRow aufrufen müsste. Aber ich glaub ich hab da einen Denkfehler bezüglich Events ..

Im Moment habe ich es jetzt so gemacht mit dem Löschen (und dem Anzeigen, Editieren und neue hinzufügen), dass ich nur die Tabelle verändere. Mein einziges Problem ist dabei im Moment, dass mein Dialog Popup von einem der 4 Buttons aufgerufen wird aber ich nicht weiß wie ich im Dialog auf die id des aufrufenden Elements komme. Sind vielleicht basics aber ich hab einfach nichts dazu gefunden. Ich muss ja dann entscheiden welche Tabellenzeile verändert werden soll, und brauch die id des Buttons, um die id der Tabellenzelle zu haben.
 
da ich dann ja in der Methode (ich nenne sich mal) builtTableRow wieder builtTableRow aufrufen müsste.
kein problem, rekursive aufrufe gehen auch in js. hier ist es allerdings nichtmal eine rekursion, da du builtTableRow ja im eventhandler aufrufst und nicht in builtTableRow.

Mein einziges Problem ist dabei im Moment, dass mein Dialog Popup von einem der 4 Buttons aufgerufen wird aber ich nicht weiß wie ich im Dialog auf die id des aufrufenden Elements komme.
wenn du von einem eventhandler wie $("#delete-"+id).click( sprichst, kannst du im eventhandler (closure) einfach darauf zugreifen.
 
kein problem, rekursive aufrufe gehen auch in js. hier ist es allerdings nichtmal eine rekursion, da du builtTableRow ja im eventhandler aufrufst und nicht in builtTableRow.

Alles klar. Ich werde das mal dann noch zusätzlich so umbauen.

wenn du von einem eventhandler wie $("#delete-"+id).click( sprichst, kannst du im eventhandler (closure) einfach darauf zugreifen.

Also der Button (mit der benötigten Id) ruft den jQuery Dialog auf. Und im Dialog müsste ich auf den Button zugreifen. Zwischen Button und dem this Zugriff darauf, liegt also der Dialog. Der open-Dialog Methode kann ich keine weiteren Parameter mitgeben.

PHP:
$("#dialogs").dialog(
	{
		modal:true,
		autoOpen:false,
		buttons: 
		[
			{
				text: "Ok",
				click: function() {
					var nameInsert = $("#name").val();
					var emailInsert = $("#email").val();
					if(typActionGlobal == "add")
					{
						$.post( "intokunde.php", { email: emailInsert, name: nameInsert });	
						doTableRow("add", idGlobal, nameInsert, emailInsert, null);
						idGlobal++;
					}
					else if(typActionGlobal == "edit")
					{
                        var id = // ZUGRIFF AUF DIE ID DES DEN DIALOG AUFRUFENDEN BUTTONS
						doTableRow("edit", id, nameInsert, emailInsert, null);
					}
                    $( this ).dialog( "close" );
				}
			},
[...]

Muss man das mit einem Flag lösen?
 
Was ich brauche ist die Id des Buttons, der diesen Dialog geöffnet hat.
ach, du suchst nicht die id aus $("#delete-"+id), sondern die des buttons, dessen clickhandler den dialog öffnet?
dann in etwa so
Code:
$(<<button>>).click(function(event)
{
  ...
  $("#dialogs").dialog({
     ...
     ..., function()
     {
        alert(event.currentTarget.id);
     }
  });
});
 
Temporär in eine Hilfsvariable im globalen Namensraum von JavaScript ablegen, um Zugriff von "überall" zu gewährleisten ... aber es geht mit Sicherheit auch eleganter. ;)


EDIT: Ok ... deutlich eleganter! Der Hinweis bei jQ direkt: If you are using jQuery.proxy or another form of scope manipulation, this will be equal to whatever context you have provided, not event.currentTarget!
 
Zuletzt bearbeitet:
ok, gerade gesehen, dein $("#delete-"+id) wird in einer schleife hochgezählt, dann würde auch dort das nicht einfach verwendet werden können, sondern nochmal zwischengespeichert werden müssen

Code:
$(document).ready(function()
{
    $.getJSON("getpersons.php", function(data)
    {
        var items = [];
        var id = 0;
        
        $.each(data, function(key, val)
        {
            ...
                        
            $("#delete-"+id).click((function(id)
            {
              return function()
              {
                ...
                $("#dialogs").dialog({
                  ...
                  ..., function()
                  {
                    alert(id);
                  }
                });
              };
            })(id));
 
Danke für eure Hilfe.

So wie ich das sehe, kann man vom Dialog aus keine Rückschlüsse mehr ziehen, von welchem Element der Aufruf des Dialogs kam - egal was man nimmt. Es sei den man definiert den Dialog da wo die aufrufenden Buttons definiert werden.

Also ich habe es jetzt so gelöst, dass ich dem Dialog (im Html definiert) noch ein verstecktes span hinzufüge, in das ich dann die Id speichere. Im Endeffekt scheint das recht sauber, weil ich ja die anderen Daten auf gleiche Weise übergebe.
 
So wie ich das sehe, kann man vom Dialog aus keine Rückschlüsse mehr ziehen, von welchem Element der Aufruf des Dialogs kam - egal was man nimmt. Es sei den man definiert den Dialog da wo die aufrufenden Buttons definiert werden.

ich glaube verstanden zu haben, was dein problem ist

Code:
<html>
  <head>
    <title></title>
    <link href="jquery-ui.css" rel="stylesheet">
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="jquery-ui.js"></script>
    <script type="text/javascript">
      $(document).ready(function()
      {
        $("#data").dialog({
          autoOpen: false,
          resizable: false,
          height: 140,
          modal: true,
          buttons: {
            "test": function()
            {
              alert($(this).data("btn").innerHTML);
              $(this).dialog("close");
            },
            Cancel: function()
            {
              $(this).dialog("close");
            }
          }
        });
        $("#closure").dialog({
          autoOpen: false,
        });
        $.each(["1", "2", "3"], function(idx, val)
        {
          $("#cont").append("<div>" + val + "</div>");
          $("#cont div:last").button().click(function(event)
          {
            $("#data").data("btn", event.currentTarget).dialog("open");
          });
        });
        $.each(["4", "5", "6"], function(idx, val)
        {
          $("#cont").append("<div>" + val + "</div>");
          $("#cont div:last").button().click(function(event)
          {
            $("#closure").dialog({
              autoOpen: true,
              resizable: false,
              height: 140,
              modal: true,
              buttons: {
                "test": function()
                {
                  alert(event.currentTarget.innerHTML);
                  $(this).dialog("close");
                },
                Cancel: function()
                {
                  $(this).dialog("close");
                }
              }
            });
          });
        });
      });  
    </script>
  </head>
  <body>
    <div id="cont">
    </div>
    <div id="data" title="Dialog">
      <p>Element über data</p>
    </div>
    <div id="closure" title="Dialog">
      <p>Element über closure</p>
    </div>
  </body>
</html>

1-3 außerhalb
4-5 innerhalb definiert
 
Zurück
Oben