Jup0: "$(this)." funktioniert nicht in Unterfunktion

Moin zusammen!

Ich habe ein (kleines) Problem(chen)...:

Baue gerade etwas und nutze jquery + js-datatables (https://datatables.net/examples/index).

Das funktioniert gut:

<script>
$(document).ready(function() {

	var table = $('#example').DataTable( {
        "respsonsive": true
    } );	
	
	$('#example tbody').on( 'click', 'img.icon-delete', function (e) {
		 bootbox.confirm("Datensatz #" + e.currentTarget.id + " wirklich loeschen?", function(result){ 
			
		 });
		 
		 table
			.row( $(this).parents('tr') )
			.remove()
			.draw();
    
	} );

... die Wirklich-Löschen-Anzeige erscheint. Leider wird beim onclick auf das IMAGE sofort der Eintrag in der Table gelöscht - egal was man auswählt.

Nun denke ich mir: Kopiere den Abschnitt des Entrag entfernens einfach in den Function-Teil der bootbox.confirm().-Funktion,... leider funktioniert das entfernen des Tabelleneintrag dann nicht mehr :-( Vermute, dasss die "$(this)"-Funktion dann in der "unter"-Funktion falsch "referenziert"? (???)

Kann mir jemand helfen bitte?!?!

Mein Code (so wie er sein sollte jedoch nicht funktioniert):

<script>
$(document).ready(function() {
	var table = $('#example').DataTable( {
        "respsonsive": true
    } );	

	$('#example tbody').on( 'click', 'img.icon-delete', function (e) {
		 bootbox.confirm("Datensatz #" + e.currentTarget.id + " wirklich loeschen?", function(result){ 

			if(result) {
				  table
					.row( $(this).parents('tr') )
					.remove()
					.draw();
			}		
							
		 }); 
	} );

1000 Dank vorab!!!

  1. Ich glaube ich hab's:

    <script>
    $(document).ready(function() {
    	var table = $('#example').DataTable( {
            "respsonsive": true
        } );	
    	$('#example tbody').on( 'click', 'img.icon-delete', function (e) {
    		 that = $(this);
    		 bootbox.confirm("Datensatz #" + e.currentTarget.id + " wirklich loeschen?", function(result){ 
    			if(result) {
    				  table
    					.row( that.parents('tr') )
    					.remove()
    					.draw();
    			}									
    		 }); 
    	} );
    

    😀

    1. Hallo Jup0,

      willkommen in der Welt der this-Kontexte von JavaScript. Eine Funktion, die "einfach so" aufgerufen wird, hat ein undefiniertes this. Es kann das window-Objekt sein, aber auch null.

      Eine Callback-Funktion wie die für bootbox.confirm kann vom Aufrufer ein spezielles this gesetzt bekommen. JavaScript hat dafür spezielle Methoden (apply und call). jQuery ruft seine Callbacks immer so auf, dass this auf das Objekt zeigt, dass von jQuery gerade bearbeitet wird.

      Grundsätzlich sollte man davon ausgehen, dass this einen Scope-Wechsel nicht übersteht (jeder Funktionsaufruf ändert den Scope). Lösungen für das Problem sind:

      1. this als Parameter übergeben
      2. this in einer Variablen ablegen, deren Scope für die innere Funktion sichtbar ist. Diese Variable that zu nennen ist manchmal die einzige Lösung, besser ist aber immer ein sprechender Name. In deinem Falle wäre $clickedIcon nicht schlecht. Das Dollar vorneweg um anzuzeigen dass dies ein wrapped set von jQuery ist, und clickedIcon, naja, weil's das ist.
      3. mit Hilfe der bind-Methode eine Wrapper-Funktion erzeugen, die für ein definiertes this sorgt.

      Rolf

      --
      sumpsi - posui - clusi
        1. this als Parameter übergeben
        2. this in einer Variablen ablegen, deren Scope für die innere Funktion sichtbar ist. Diese Variable that zu nennen ist manchmal die einzige Lösung, besser ist aber immer ein sprechender Name. In deinem Falle wäre $clickedIcon nicht schlecht. Das Dollar vorneweg um anzuzeigen dass dies ein wrapped set von jQuery ist, und clickedIcon, naja, weil's das ist.
        3. mit Hilfe der bind-Methode eine Wrapper-Funktion erzeugen, die für ein definiertes this sorgt.

        4. Auf this verzichten und stattdessen e.target verwenden.

        1. @@1unitedpower

          4. Auf this verzichten und stattdessen e.target verwenden.

          5. e in event umbenennen.

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. @@Jup0

    Das funktioniert gut:

    	$('#example tbody').on( 'click', 'img.icon-delete', function (e) {
    

    Nicht gut, sondern nicht. Das funktioniert nicht. imgs kann man nicht clicken. (Einige Nutzer können das; aber eben nicht „man“.)

    Verwende das für Aktionen vorgesehene Element, das auch per Tastatur clickbar ist: button.

    <button class="button-delete">
    	<img src="" alt="löschen"/>
    </button>
    

    Das funktioniert – mit entsprechendem Alternativtext (der auch noch enthalten könnte, was denn da gelöscht wird).

    background-color, border und padding des Buttons lassen sich bei Bedarf mit CSS entfernen.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. he @Gunnar Bittersmann

      Nicht gut, sondern nicht. Das funktioniert nicht. imgs kann man nicht clicken. (Einige Nutzer können das; aber eben nicht „man“.)

      Mit der Maus kann man überall klicken, dafür wurde sie entwickelt! Und die rechte Maustaste erzeugt sogar ein Kontextmenü.

      Verwende das für Aktionen vorgesehene Element, das auch per Tastatur clickbar ist: button.

      Nun, die Tastatur ist das wichtigste Eingabegerät. Aber nicht das Einzige. Und ja:, es gibt den tabindex

      MfG

      1. @@pl

        Mit der Maus kann man überall klicken, dafür wurde sie entwickelt! Und die rechte Maustaste erzeugt sogar ein Kontextmenü.

        Willst du dem Nutzer vorschreiben, welches Eingabegerät sie zu benutzen hat?

        Nun, die Tastatur ist das wichtigste Eingabegerät. Aber nicht das Einzige. Und ja:, es gibt den tabindex

        Das reicht nicht.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. hi @Gunnar Bittersmann ,

          Mit der Maus kann man überall klicken, dafür wurde sie entwickelt! Und die rechte Maustaste erzeugt sogar ein Kontextmenü.

          Willst du dem Nutzer vorschreiben, welches Eingabegerät sie zu benutzen hat?

          Die Frage des Eingabegerätes ist eine Frage der Zweckmäßigkeit!

          MfG

          1. @@pl

            Mit der Maus kann man überall klicken, dafür wurde sie entwickelt! Und die rechte Maustaste erzeugt sogar ein Kontextmenü.

            Willst du dem Nutzer vorschreiben, welches Eingabegerät sie zu benutzen hat?

            Die Frage des Eingabegerätes ist eine Frage der Zweckmäßigkeit!

            Für Nutzer, die eine Maus nur schlecht oder gar nicht bedienen können, ist eine Maus eben nicht zweckmäßig.

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
          2. Hallo Rolf,

            Die Frage des Eingabegerätes ist eine Frage der Zweckmäßigkeit!

            genau, und deshalb haben einige unserer Laborrechner weder Maus noch Tastatur.

            Gruß
            Jürgen

          3. hallo

            Die Frage des Eingabegerätes ist eine Frage der Zweckmäßigkeit!

            Im html ist die Frage des Eingabegerätes definiert dadurch, um welchen Event-Typ es sich handelt, und ob der Element-typ diesen Event-typ überhaupt auslösen lässt.

            Aktivierbare Elemente sind hier klar im Vorteil.

            --
            Neu im Forum! Signaturen kann man ausblenden!
  3. Hallo Jup0,

    Das funktioniert gut:

     		 table
     			.row( $(this).parents('tr') )
     			.remove()
    

    Nein, das ist eine Footgun. Es funktioniert nur dann, wenn keine Tables geschachtelt werden.

    Das ist meistens auch so, aber manchmal hat man ja so Master-Detail Monster, wo eine Tabellenzelle eine Unter-Table enthält. Und dann ist parents('tr') der Killer, weil es alle tr vom Icon bis zum Root des DOM löscht. Richtig ist hier .closest('tr').

    Rolf

    --
    sumpsi - posui - clusi