2009-09-01 6 views
7

La version courte de ceci est la suivante: Puis-je parcourir uniquement les éléments de l'élément correspondant des sélecteurs avant le each()? Ou existe-t-il un moyen plus simple d'obtenir ce que je veux sans boucle each()?Utilisation de jquery pour obtenir les totaux par ligne et le total général de la table


Je pensais que ce serait beaucoup plus facile, ce qui me fait penser que je suis juste un certain manque principe fondamental de l'élément traversant avec jquery.

Alors, voici le scénario:

J'ai une table (et il convient dans ce cas), où chaque cellule a un texte input. La dernière entrée est en lecture seule et est censée être la somme totale des autres valeurs entrées sur cette ligne. J'ai un script js vraiment désordonné pour trouver à la fois les totaux de chaque ligne et ensuite le total général de chaque ligne.

Voici le HTML de base:

<table> 
<thead> 
<tr><th>Col 1</th><th>Col 2</th><th>Col 3</th><th>Total</th></tr> 
</thead> 
<tbody> 
<tr id="row1"><td><input type="text" /></td><td><input type="text" /></td><td><input type="text" /></td><td class="total"><input type="text" readonly="readonly" /></td></tr> 
<tr id="row2"><td><input type="text" /></td><td><input type="text" /></td><td><input type="text" /></td><td class="total"><input type="text" readonly="readonly" /></td></tr> 
<tr id="row3"><td><input type="text" /></td><td><input type="text" /></td><td><input type="text" /></td><td class="total"><input type="text" readonly="readonly" /></td></tr> 
</tbody> 
</table> 

Le javascript validera que les données saisies est numérique, juste pour être clair.

J'ai donc un écouteur d'événement pour chaque entrée pour onchange qui met à jour le total lorsque l'utilisateur entre des données et passe à la cellule/entrée suivante. Ensuite, j'ai une fonction appelée updateTotal qui utilise actuellement for boucles pour faire une boucle à travers chaque ligne et dans cette boucle, chaque cellule, et enfin définit l'entrée dans la cellule totale de somme.

Note rapide: J'ai inclus le code ci-dessous pour montrer que je ne cherche pas seulement une distribution et que je démontre la logique de base de ce que j'ai en tête. N'hésitez pas à parcourir ou à ignorer cette partie. Cela fonctionne et n'a pas besoin de débogage ou de critique.

C'est ce qui ressemble à:

function updateTotal() { 
    table = document.getElementsByTagName("tbody")[0]; 
    allrows = table.getElementsByTagName("tr"); 
    grandtotal = document.getElementById("grand"); 
    grandtotal.value = ""; 

    for (i = 0; i < allrows.length; i++) { 
     row_cells = allrows[i].getElementsByTagName("input"); 
     row_total = allrows[i].getElementsByTagName("input")[allrows.length - 2]; 
     row_total.value = ""; 

     for (ii = 0; ii < row_cells.length - 1; ii++) { 
      row_total.value = Number(row_total.value) + Number(row_cells[i][ii].value); 
      grandtotal.value = Number(grandtotal.value) + Number(row_cells[i][ii].value); 
     } 
    } 
} 

Maintenant, je suis en train de réécrire ci-dessus avec la syntaxe jquery, mais je suis en train de coincé. Je pensais que la meilleure façon d'aller serait d'utiliser each() boucles le long des lignes de:

function findTotals() { 
$("tbody tr").each(function() { 
    row_total = 0; 
    $($(this) + " td:not(.total) input:text").each(function() { 
     row_total += Number($(this).val()); 
     }); 
    $($(this) + " .total :input:text").val(row_total); 
}); 

} 

Mais en utilisant $(this) ne semble pas fonctionner de la façon dont je pensais. J'ai lu et vu que l'utilisation de $(this) dans chaque boucle pointe vers chaque élément correspondant, ce qui est ce que j'attendais, mais je ne comprends pas comment je peux traverser cet élément dans la fonction each(). Ce qui précède laisse également de côté le bit grand_total, car j'avais encore moins de chance de faire fonctionner la variable grand total. J'ai essayé ce qui suit juste pour obtenir les row_totals:

$($(this).attr("id") + " td:not(.total) input:text").each(function() { 

avec un certain succès, mais a réussi à briser quand j'ai essayé d'ajouter sur elle. Je ne pense pas que j'aurais besoin de chaque rangée pour avoir un identifiant pour faire ce travail, puisque chaque partie devrait pointer vers la rangée que j'ai en tête.


Ainsi, la version courte de c'est: Puis-je utiliser chaque boucle pour parcourir uniquement les éléments dans les matches, et si oui, quelle est la syntaxe correcte? Ou y a-t-il un moyen plus simple d'obtenir ce que je veux sans chaque boucle?

Oh, une dernière pensée ...

Est-il possible d'obtenir la somme numérique (par opposition à une longue chaîne) de tous les éléments correspondants avec jquery? Je ferai des recherches plus moi-même, mais si quelqu'un le sait, cela facilitera beaucoup la tâche.

+0

Pour ceux qui sont sur le point de me brûler pour une question répétée: 1) Je ne trouve aucune documentation sur la méthode sum(), 2) Je voudrais savoir comment parcourir un élément avec une boucle sans avoir besoin un ID ou une classe quelconque. – Anthony

Répondre

16

Vous essayez de définir votre contexte essayer inexactement:

function findTotals() { 
    $("tbody tr").each(function() { 
     row_total = 0; 
     $("td:not(.total) input:text",this).each(function() { 
      row_total += Number($(this).val()); 
     }); 
     $(".total :input:text",this).val(row_total); 
    }); 

} 

Pour plus d'informations sur le contexte de vérifier les jquery docs: http://docs.jquery.com/Core/jQuery#expressioncontext

+0

À droite, concaténer $ (this) + un sélecteur ne fait pas la bonne chose. –

+0

Vous êtes mon héros freekin. Le contexte d'expression était exactement ce dont j'avais besoin et il fonctionne exactement comme j'en ai besoin. – Anthony

0

Il peut y avoir deux paramètres pour un sélecteur. Le second paramètre est le contexte dans lequel la recherche doit se dérouler. Essayez quelque chose comme ceci: $ ('# tableID tbody tr) .each (function() { // maintenant c'est une ligne de table, donc juste rechercher toutes les zones de texte dans cette ligne, éventuellement avec une classe css appelée sum ou par un autre attribut $ ('input [type = text]', this) .each (function() { // sélectionne tous les textbosx dans la rangée // $ (this) .val() obtient la valeur de textbox, etc. }); // maintenant en dehors de cette fonction vous auriez le total // l'ajouter à un champ masqué ou à une variable globale pour obtenir les totaux des lignes, etc. });