2016-05-03 15 views
1

JSFiddle here.JQuery `length` Eigenschaft funktioniert nicht richtig. Warum?

In der folgenden SSCCE, in der click Listener für button#remove, gibt es eine alert("numberOfRows:" + numberOfRows); //check***************** Anweisung. Die Aussage vor der Berechnung numberOfRows. Diese Nummer immer scheint 0 zu sein. Die Frage ist darum.

Bitte diesen Code ausführen. Klicken Sie einmal oder mehrmals auf die Schaltfläche Add TextField. Jeder Klick fügt die orange umrandete Tabelle hinzu. Klicken Sie dann auf die Schaltfläche Remove TextField, und Sie erhalten die alert. Das Problem ist, dass immer numberOfRows0 angezeigt wird, egal wie viele Zeilen tatsächlich da sind.

Die Frage ist, warum? Wie behebe ich das?

$(document).on("click", "button.remove", function() { 
 
    event.preventDefault(); 
 

 
    var currentRow = $(this).parent().parent().parent().parent().parent().parent(); 
 
    currentRow.remove(); 
 

 

 
    //update numberOfRows variable 
 
    var parentTable = $(this).parent().parent().parent().parent().parent().parent().parent().parent(); 
 

 
    var numberOfRows = parentTable.children('tbody').children('tr').length; 
 

 
    /*****************************************/ 
 
    /*****************************************/ 
 
    /*****************************************/ 
 
    alert("numberOfRows:" + numberOfRows); //check***************** 
 
    /*****************************************/ 
 
    /*****************************************/ 
 
    /*****************************************/ 
 

 

 
    if (!(numberOfRows > 1)) { 
 
    $(".remove").hide(); 
 
    } 
 
}); 
 

 

 

 

 

 

 

 

 

 

 
$(document).on("click", "button.add", function() { 
 
    event.preventDefault(); 
 

 
    var parentTable = $(this).parent().parent().parent().parent().parent().parent().parent().parent(); 
 
    var lastTableRow = parentTable.children('tbody').children('tr:last'); 
 

 
    //Adding the new row 
 
    parentTable.children('tbody').append(lastTableRow.clone()); 
 

 
    //Reset lastRow variable 
 
    lastTableRow = parentTable.children('tbody').children('tr:last'); 
 
    //Reset the fields 
 
    lastTableRow.find('table tbody tr td input').each(function() { 
 
    $(this).val(''); 
 
    }); 
 

 

 
    //update numberOfRows variable 
 
    var numberOfRows = parentTable.children('tbody').children('tr').length; 
 
    alert("numberOfRows:" + numberOfRows); //check 
 

 

 
    if (!(numberOfRows > 1)) { 
 
    $(".remove").hide(); 
 
    } else { 
 
    $(".remove").show(); 
 
    } 
 

 
});
#outer-table { 
 
    padding: 20px; 
 
    border: 3px solid pink; 
 
} 
 
#inner-table { 
 
    border: 3px solid orange; 
 
} 
 
.remove { 
 
    display: none; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<table id="outer-table"> 
 
    <tbody> 
 
    <tr> 
 
     <td> 
 

 

 
     <table id="inner-table"> 
 
      <tbody> 
 
      <tr> 
 
       <td> 
 
       <p style="display:inline-block">Enter first complain:</p> 
 
       <input type="text" /> 
 
       </td> 
 
      </tr> 
 
      </tbody> 
 

 
      <tfoot> 
 
      <tr> 
 
       <td> 
 
       <button class="add" id="add">Add Textfield</button> 
 
       <button class="remove" id="remove">Remove Textfield</button> 
 
       </td> 
 
      </tr> 
 
      </tfoot> 
 
     </table> 
 

 

 

 
     </td> 
 
    </tr> 
 
    </tbody> 
 

 

 

 
    <tfoot> 
 
    <tr> 
 
     <td>Table Footer</td> 
 
    </tr> 
 
    </tfoot> 
 

 
</table>

+4

Was auch immer das eigentliche Problem hier sein könnte - es _must_ ein besserer Weg zu dem bestimmten Elemente zu durchqueren bis als '$ (this) .parent() parent() parent() parent() parent().... .parent(). parent(). parent() ' – CBroe

+6

Jedes Mal, wenn Sie sich finden, tun' .parent(). parent(). parent(). par ..... 'usw. Sie tun etwas falsch – adeneo

+1

ändern Reihenfolge: Definieren Sie ParentTable, bevor Sie die aktuelle Zeile löschen. – NineBerry

Antwort

1

So etwas ist, was es

$('.outer-table').on("click", ".add", function(event) { 
 
    event.preventDefault(); 
 

 
    var row = $(this).closest('.inner-table').closest('tr'), 
 
     rows = row.closest('tbody').children('tr').length + 1; 
 

 
    row.after(row.clone()); 
 

 
    alert("numberOfRows:" + rows); 
 

 
    $(".remove").toggle(rows > 1); 
 
}); 
 

 
$('.outer-table').on("click", ".remove", function(event) { 
 
    event.preventDefault(); 
 

 
    var row = $(this).closest('.inner-table').closest('tr'), 
 
     rows = row.closest('tbody').children('tr').length - 1; 
 

 
    row.remove(); 
 

 
    alert("numberOfRows:" + rows); 
 

 
    if (rows < 2) $(".remove").hide(); 
 
});
.outer-table { 
 
    padding: 20px; 
 
    border: 3px solid pink; 
 
} 
 

 
.inner-table { 
 
    border: 3px solid orange; 
 
} 
 

 
.remove { 
 
    display: none; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table class="outer-table"> 
 
    <tbody> 
 
     <tr> 
 
      <td> 
 
       <table class="inner-table"> 
 
        <tbody> 
 
         <tr> 
 
          <td> 
 
           <p style="display:inline-block">Enter first complaint :</p> 
 
           <input type="text" /> 
 
          </td> 
 
         </tr> 
 
        </tbody> 
 
        <tfoot> 
 
         <tr> 
 
          <td> 
 
           <button class="add">Add Textfield</button> 
 
           <button class="remove">Remove Textfield</button> 
 
          </td> 
 
         </tr> 
 
        </tfoot> 
 
       </table> 
 
      </td> 
 
     </tr> 
 
    </tbody> 
 
    <tfoot> 
 
     <tr> 
 
      <td>Table Footer</td> 
 
     </tr> 
 
    </tfoot> 
 
</table>

2

Zuerst aussehen sollte, verwenden Sie .closest("table") die übergeordnete Tabelle zu erhalten.
Und .closest("tr") für die Zeile.

Wenn Sie Muss wirklich haben Tabellen verschachtelt, dann können Sie immer noch .closest("table").parents("table"); verwenden, aber dies sollte eine schwere rote Fahne.

schließlich der Grund, daran zu arbeiten ist nicht, weil Sie den Kontext der Entfernen klicken Handler zu entfernen (die Schaltfläche) aus dem DOM mit:

currentRow.remove(); 

Und dann sofort das DOM zu navigieren versuchen Baum mit:

var parentTable = $(this).parent()[... snip ... ].parent(); 

jedoch $(this).parent()... nicht mehr existiert, weil Sie es gelöscht haben.

In diesem Szenario .lengthsollte 0 sein, weil Ihre DOM-Navigation nichts zurückgibt.

Wenn Sie die übergeordnete Tabelle zuerst, zu holen und dann die Zeile löschen, sollte es funktionieren.

Verwandte Themen