Ankündigung

Einklappen
Keine Ankündigung bisher.

Jeweils gesamte Zeilen einer Tabelle löschen bis auf letzte Zelle

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Jeweils gesamte Zeilen einer Tabelle löschen bis auf letzte Zelle

    Hallo,

    folgende Situation : ich erstelle dynamisch eine HTML Tabelle, in der jeweils in der letzten Spalte eine Checkbox mit einer ID sitzt.
    (der Einfachheit halber habe ich diese hier simpel dargestellt und wo die Checkboxen sitzen ein X gesetzt).
    Die Checkboxen nutze ich, um die Id´s der zu löschenden Datensätze zu erfassen.

    Per Click Event auf die Checkbox lösche ich jeweils die betroffenen Zeilen erst einmal in der Tabelle per Javascript,
    um anschliessend einen Post Request an meine php Datei zu schicken, um die Daten in meiner Datenbank dann definitiv zu löschen.

    Das Löschen (bzw. Verstecken) der angeklickten Zeilen erledige ich mit "display none".

    Was mich jedoch daran stört ist die Tatsache, dass meine php Datei ja lediglich nur die Id´s mit den zu löschenden Zeilen erhalten muss
    und ich mit meiner bisherigen Methode ja trotzdem alle Daten der gesamten zu löschenden Zeilen übertragen werden.

    Somit ist mein Ziel, per Click auf die Checkboxen alle Daten meiner Tabellenreihe zu löschen und nur die letzte Zelle der Tabellenzeile auszublenden, da ja in der die Checbkox mit der Id sitzt.

    Das habe ich mit folgendem Code erledigt, was auch funktioniert :

    Code:
    document.getElementById("table").addEventListener("click", (e) => {
        myRow = (e.target.closest("tr"));
      myTds = myRow.children;
      console.log(myTds);
    
      for (let i = 0; i < myTds.length +1; i++) {
      myTds[0].remove();
    }
     myTds[0].style.display = "none";
    
    
    })

    HTML-Code:
    <table id="table">
      <tr>
        <th>Bank</th>
        <th>Konto</th>
        <th>Iban</th>
        <th></th>
      </tr>
    <tr>
      <td>Fortis</td>
      <td>Kbc</td>
      <td>Belfius</td>
      <td>X</td>
     </tr>
     <tr>
      <td>Deutsche Bank</td>
      <td>Reiffeisen</td>
      <td>Sparkasse</td>
      <td>X</td>
    </tr>
    
    </table>
    Ich frage mich, ob dies der beste Weg ist und nicht ein bisschen kürzer/effektiver geht und habe dies mit folgender Zeile probiert,
    welche jedoch einen Fehler wirft :

    Code:
    myRow.children:not(:last-child).remove();
    Habe ich nur einen Syntaxfehler in meinem Befehl oder einen Denkfehler, da ich vielleicht wirklich nicht drum rumkomme,
    die gesammte Collection der td´s zu durchlaufen ?

  • #2
    Warum versteckst du denn das gesamte td element, anstatt nur die angeklickte checkbox selbst?

    Die hättest du ja sofort über das e.target identifiziert und müsstest dich um die umgebenden nodes gar nicht kümmern.

    Oder verstehe ich dein Vorhaben falsch?
    Wenn du die ganze zeile Ausblenden möchtest, dann mach das doch auch einfach auf dem tr element anstatt auf jedem einzelnen td.

    Mir ist nicht ganz klar, was hier die checkbox Spalte so besonders macht.

    Kommentar


    • #3
      Ich versuche noch mal mein Anliegen zu erklären :

      Ich habe eine Html Tabelle, die ich dynamisch per fetch Aufruf zusammenstelle.
      In jeder letzten Zelle (also td) einer jeden Tabellenzeile (also tr) habe ich eine Checkbox mit Id der jeweiligen Tabellenzeile, die ich beim einlesen meiner Tabelle jedoch per display none ausblende.

      Ich habe einen Button « edit » mit Click Event, bei Click blende ich diese checkboxen ein (display block). Somit habe ich in jeder letzten Spalte meiner Tabelle eine Checkbox, die nur einen Zweck hat, nämlich die jeweils angeclickte Zeile zu löschen.

      Bisher habe beim anclicken einer jeden Checkbox die komplette Tabellenzeile (also tr) auf display none gesetzt. Wenn ich dann mein Formular in der sich die Tabelle ja befindet abschicke (submit event), dann werden alle Daten der kompletten Tabelle per Post Request zu meiner php geschickt, mit der ich meine Datensätze der Tabelle in der Datenbank aktualisiere.
      Mein php Programm zum löschen der Datensätze in meiner Datenbank braucht aber nur die Id’s der gelöschten Zeilen, die ich vorher per Javascript via Checkboxen in meiner Tabelle angeklickt habe. Ich möchte somit nur, dass die Values der angeklickten (Lösch-) Checkboxen übertragen werden und nicht auch die Values der gesamten auf display none gestellten Zeilen die ja nicht mit übertragen werden müssen, da die Zeilen je eh gelöscht werden.

      Um dies zu erreichen, möchte ich nun mit remove() jede Zeile der Tabelle löschen falls auf die dazu gehörende Checkbox geklickt wurde … BIS auf die letzte Spalte dieser Zeile, da sich ja in der die Checkbox mit der Id befindet … nur dieser Value soll übertragen werden. Also ich möchte dann mit remove() alle td der jeweiligen tr löschen bis auf die letzte td mit der Checkbox. Ich hoffe ich hab mich verständlich machen können, ich habe versucht, diese mit dem geposteten code vereinfacht darzustellen. Der macht auch was ich mir vorgestellt habe, ich frage mich nur, ob es nicht einfacher/kürzer geht.

      Kommentar


      • #4
        Aha... es befinden sich in den übrigen Tabellenzellen auch Eingabefelder / Formularfelder, und deren Inhalte möchtest du nicht mitschicken, falls die Zeile zum löschen markiert wurde.
        Wenn du die Felder mit remove wegwirfst, dann nimmst du aber auch dem Nutzer die Möglichkeit, sich nochmal anders zu entscheiden, und den Haken aus der Checkbox wieder herauszunehmen. Das soll so?

        In dem Fall würde ich tatsächlich die ganze zeile wegwerfen, und die zu löschende ID in einem (neuen) hidden formularfeld unterbringen.
        Dieses formularfeld kann durchaus auch array-charakter haben, was dir dann hinterher die Verarbeitung erleichtert.

        Falls sich ein Nutzer doch noch umentscheiden können soll, müsste man das ohnehin anders machen, denn was du einmal mit remove wegwirfst, ist dann eben auch weg und nicht nur ausgeblendet.

        Kommentar


        • #5
          Zitat von Midget Beitrag anzeigen
          […] die ich beim einlesen meiner Tabelle jedoch per display none ausblende.

          Ich habe einen Button « edit » mit Click Event, bei Click blende ich diese checkboxen ein (display block).
          Schlechte Idee. Verpassen den auszublendenden Elementen eine Klasse und entferne diese - classList hilft dabei. Und: block ist nicht der Standardwert für Checkboxen, das ist inline-block.

          Somit habe ich in jeder letzten Spalte meiner Tabelle eine Checkbox, die nur einen Zweck hat, nämlich die jeweils angeclickte Zeile zu löschen.

          Bisher habe beim anclicken einer jeden Checkbox die komplette Tabellenzeile (also tr) auf display none gesetzt.
          Ganz schlechte Idee. Der Benutzer erwartet nicht dass beim Anklicken einer Checkbox irgendwelche Daten direkt gelöscht werden. Lass das mit dem Ausblenden einfach sein und lass den Benutzer die zu löschenden Datensätze über die dazugehörige Checkbox auswählen. Das Formular mit den ausgewählten Checkboxen schickst du ab und löschst die ausgewählten Datensätze - die Werte nicht ausgewählte Checkboxen werden nicht übertragen!

          Falls du in der Tabelle noch mehr Eingabefelder hast die nicht mitgeschickt werden sollen: setzte das Formular das zum Löschscript gehört außerhalb der Tabelle und sage den Checkboxen per form-Attribut dass sie zu dem Formular außerhalb der Tabelle gehören.

          Um dies zu erreichen, möchte ich nun mit remove() jede Zeile der Tabelle löschen falls auf die dazu gehörende Checkbox geklickt wurde …
          Nein, möchtest du nicht. Aber als Erklärung warum dein Versuch aus #1 nicht funktioniert: du willst mehrere Zellen auswählen und diese entfernen - das geht natürlich nicht mit einem remove()-Aufruf, da müsstest du über die gefundenen Zellen eine Schleife laufen lassen. Achja: bei Fehlermeldungen immer auch die Fehlermeldung posten, hier ist das Problem allerdings offensichtlich: Phantasiecode funktioniert halt nicht …

          Kommentar


          • #6
            es befinden sich in den übrigen Tabellenzellen auch Eingabefelder / Formularfelder, und deren Inhalte möchtest du nicht mitschicken, falls die Zeile zum löschen markiert wurde.
            => genau so ist es. Sorry mit den Inputfeldern in meiner Tabelle hab ich komplett vergessen zu erwähnen.

            Dieses formularfeld kann durchaus auch array-charakter haben,
            => interessante Idee, ich versuch das mal bei mir einzubauen

            Ganz schlechte Idee. Der Benutzer erwartet nicht dass beim Anklicken einer Checkbox irgendwelche Daten direkt gelöscht werden. Lass das mit dem Ausblenden einfach sein und lass den Benutzer die zu löschenden Datensätze über die dazugehörige Checkbox auswählen. Das Formular mit den ausgewählten Checkboxen schickst du ab und löschst die ausgewählten Datensätze - die Werte nicht ausgewählte Checkboxen werden nicht übertragen!
            => genau das passiert. Wie gesagt sorry,ich hab mein gepostetes Beispiel versucht so einfach wie möglich darzustellen. Meine Checkboxen liegen jeweils in der letzten Zelle einer jeden Zeile und sind mit einem Mülleimer-Image verbunden welche klar
            anzeigen, dass gelöscht werden soll.

            Ich hab jetzt mal paar Zeilen aus meinem Quellcode kopiert damit mein Vorgehen (hoffentlich) deutlicher wird.

            du willst mehrere Zellen auswählen und diese entfernen - das geht natürlich nicht mit einem remove()-Aufruf,
            => genau das war meine zentrale Frage die ich nun beantwortet habe : ich muss meine Collection mit den td´s einzeln durchlaufen. Danke

            HTML-Code:
            <style>
            input[type="checkbox"] {
              display: none;
            }
            th {
              text-align: left;
            }
            input {
              border: none;
            }
            </style>
            
            <table id="table" class="hideDeleteIcon">
                            <thead>
                                <tr>
                                    <th data-inputtype="input" data-headername="id_bank">Id</th>
                                    <th data-inputtype="input" data-headername="bank">Bank</th>
                                    <th data-inputtype="input" data-headername="iban">Iban</th>
                                    <th data-inputtype="input" data-headername="account">Konto</th>
                                    <th data-inputtype="input" data-headername="bank_code">Bankcode</th>
                                    <th data-inputtype="input" data-headername="bic">bic</th>
                                    <th data-inputtype="input"></th>
                                </tr>
                            </thead>
                        <tbody id="tbodyBank"><tr data-id="64"><td><input type="text" name="bank[][id_bank]" value="64" readonly="true"></td><td><input type="text" name="bank[][bank]" value="Belfius" readonly="true"></td><td><input type="text" name="bank[][iban]" value="BE0123 456 455 77" readonly="true"></td><td><input type="text" name="bank[][account]" value="BE51125411" readonly="true"></td><td><input type="text" name="bank[][bank_code]" value="TTFY" readonly="true"></td><td><input type="text" name="bank[][bic]" value="GBEDF" readonly="true"></td><td><input type="checkbox" name="deleteBank64" id="deleteBank64" value="64" style="pointer-events: none;">
                                    <label for="deleteBank64"><img src="garbagecan_small.png"></label></td></tr><tr data-id="78"><td><input type="text" name="bank[][id_bank]" value="78" readonly="true"></td><td><input type="text" name="bank[][bank]" value="Fortis" readonly="true"></td><td><input type="text" name="bank[][iban]" value="BE412 412 532 145" readonly="true"></td><td><input type="text" name="bank[][account]" value="BE 412 521" readonly="true"></td><td><input type="text" name="bank[][bank_code]" value="KAKA" readonly="true"></td><td><input type="text" name="bank[][bic]" value="TTJ" readonly="true"></td><td><input type="checkbox" name="deleteBank78" id="deleteBank78" value="78" style="pointer-events: none;">
                                    <label for="deleteBank78"><img src="garbagecan_small.png"></label></td></tr>
            </tbody>
            </table>
            Code:
            document.getElementById("table").addEventListener("click", (e) => {
            if (e.target.tagName === "IMG") {
                myRow = (e.target.closest("tr"));
                  myTds = myRow.children;
                len = myTds.length;
                for (let i = 0; i < len-1; i++) {
                    myTds[0].remove();
                  }
                 myTds[0].style.display = "none";
            }
            
            })

            Kommentar


            • #7
              Midget , keine Ahnung wieso du das so grob machst und auf die komplette Table einen Event setzt.

              - Mache nur auf die Mülleimer-Bildchen einen OnClick-Event mit this. Nutze dazu getElementsByClassName oder wenn möglich getElementsByTagName.
              - Nehme in der function vom this das parent <tr>.
              - Nehme vom <tr> die childrens.
              - Schleife mit: i < (array.length - 1)
              - Bei jedem <td> das child <input> und dort das value auf "" (leer).

              oder
              - remove das parent <tr>.

              PS: das ist auch wieder die alte Leier, das bei onclick der Event als (e) angegeben/übergeben wird, was unnütz und verwirrend ist, weil innerhalb der Funktion sowieso als Variable event vorhanden, sogar in verschachtelten functions. Weniger verwirrend ist die Übergabe von this.

              Kommentar


              • #8
                Zitat von psoido Beitrag anzeigen
                Midget , keine Ahnung wieso du das so grob machst und auf die komplette Table einen Event setzt.
                So etwas nennt sich Event Delegation... Deine geschilderten Ansätze sind nicht effizient.

                Kommentar


                • #9
                  keine Ahnung wieso du das so grob machst und auf die komplette Table einen Event setzt.
                  => Wie Kaminbausatz schon richtig schrieb hat das seinen Grund : sobald ich Datensätze in meiner Tabelle hinzufüge haben die hinzugefügten Lösch-Icons
                  ebenfalls bereits mein Click Event da ich das Event auf den parent, also die Tabelle setze. Bei deinem Vorschlag muss ich bei jeder neu eingefügten Zeile
                  wieder ein separaten Event-Handler setzen.

                  Eine Frage hab ich noch zum Abschluss des Themas :

                  Schlechte Idee. Verpassen den auszublendenden Elementen eine Klasse und entferne diese - classList hilft dabe
                  => welche Vorteil hat es wenn ich meinem bzw meinen Element(en) eine Klasse verpasse die ich setzen und wieder löschen kann anstatt sie auf display none zu setzen
                  und bei Bedarf mit display block (oder inline-block) einzublenden ?

                  Kommentar


                  • #10
                    Zitat von Midget Beitrag anzeigen
                    => welche Vorteil hat es wenn ich meinem bzw meinen Element(en) eine Klasse verpasse die ich setzen und wieder löschen kann anstatt sie auf display none zu setzen
                    und bei Bedarf mit display block (oder inline-block) einzublenden ?
                    Layout-Informationen gehören in den CSS-Code, nicht in den JS-Code - der wiederum ist (u.a.) dafür da den DOM-Baum so zu verändern dass das gewünschte CSS genutzt wird. In dem Fall ist display:none o.ä. allerdings ohnehin falsch, egal ob per CSS oder JS gesetzt: für den Fall gibt es das hidden-Attribut bzw. die gleichnamige Eigenschaft.

                    Zitat von psoido Beitrag anzeigen
                    Nutze dazu getElementsByClassName oder wenn möglich getElementsByTagName.
                    Nein, querySelectorAll() ist da viel sinnvoller/praktischer: zum einen lässt sich damit jegliche Suche nach Elementen erschlagen und zum anderen liefert die Methode eine NodeList auf welche forEach anwendbar ist - mit der HTMLCollection der get*-Methoden geht das nicht.

                    PS: das ist auch wieder die alte Leier, das bei onclick der Event als (e) angegeben/übergeben wird, was unnütz und verwirrend ist, weil innerhalb der Funktion sowieso als Variable event vorhanden, sogar in verschachtelten functions. Weniger verwirrend ist die Übergabe von this.
                    Mir ist nicht so ganz klar, was du damit sagen willst. Dir ist schon klar dass das »(e)« im JS-Code in #1 und #6 eben eine Referenz auf das Event enthält - automatisch ist das nicht in »event« enthalten (wobei e natürlich ein schlechter Name für eine Variable ist, event o.ä. wäre besser). Und was du jetzt mit this meinst, ist mir auch nicht klar …

                    Kommentar


                    • #11
                      Zitat von tk1234 Beitrag anzeigen
                      Mir ist nicht so ganz klar, was du damit sagen willst. Dir ist schon klar dass das »(e)« im JS-Code in #1 und #6 eben eine Referenz auf das Event enthält - automatisch ist das nicht in »event« enthalten (wobei e natürlich ein schlechter Name für eine Variable ist, event o.ä. wäre besser). Und was du jetzt mit this meinst, ist mir auch nicht klar …
                      Siehe hier: https://jsfiddle.net/0v9tL7pn/

                      Kommentar

                      Lädt...
                      X