2010-10-13 11 views
7

Per un po 'di background, ho più caselle di controllo, ciascuna con un "punteggio" diverso. Quando la casella di controllo è cambiata, ho bisogno di calcolare il punteggio. Ho pensato che qualcosa del genere avrebbe funzionato, ma non sembra che l'evento .change sia associato correttamente.Jquery: modifica vincolante a più checkbox

$(document).ready(function() { 
    bindSomeCheckboxes(); 
}); 

function bindSomeCheckboxes() { 
    var score=0; 
    var checkboxes = { 
     "id_1" : 3, 
     "id_2" : 1, 
     "id_3" : 2, 
     "id_4" : 5 
    }; 

    $.each(checkboxes, function(key, value) { 
     $("#"+key).change(function(key,value) { 
      if ($("#"+key).is(':checked')) { 
       //add this ids value to score 
      } else { 
       //subtract value from score 
      } 
     }); 
    }); 
} 

So che sta eseguendo il looping attraverso l'array correttamente, ma un avviso in .change non viene mai visto.

+0

dovrebbe essere ': checked' invece di': clicked', si veda la mia risposta per maggiori informazioni. – BrunoLM

+0

Sembra che a tutte le risposte manchi il fatto che ogni ID abbia un "punteggio" unico. Ecco perché ho la mappatura di id -> punteggio. Ho fatto clic su -> controllato la correzione sopra e modificato i commenti per mostrare quello che sto cercando di realizzare. Devo ammettere che potrei andare in giro tutto sbagliato. ;) –

+0

Ho aggiunto una risposta che mantiene la struttura di base con cui si stava lavorando. Penso che stavi cercando di fare riferimento a 'chiave' all'interno del gestore pensando che avrebbe avuto l'ID. Il problema è che hai dato al tuo gestore il proprio parametro 'key', che in realtà si riferisce all'oggetto' event'. Rimuovi (o rinomina) quello e avresti il ​​'key'. Ma non ne hai bisogno, perché hai un riferimento diretto all'ID che ti serve perché "this" fa riferimento a quello che ha ricevuto l'evento, quindi "this.id" è l'ID di quello. – user113716

risposta

4

Se si voleva davvero prendere quel approccio di utilizzare gli ID, mi piacerebbe fare un Array separata delle ID, e fare un .join() per creare la selettore.

Alcune cose da notare:

  • Invece di .is(':clicked') o .is(':checked'), utilizzare this.checked. Molto più efficiente.
  • I gestori di eventi in jQuery hanno un parametro che fa riferimento allo event. Hai 2 per key,value. Questo sta rendendo key nel gestore riferimento a tale oggetto event anziché key da $.each().
  • All'interno di un gestore, this si riferisce a quello su cui è stato fatto clic.
  • Poiché si dispone del riferimento this all'elemento, non è necessario il riferimento a key nello $.each().Puoi semplicemente fare this.id.

function bindSomeCheckboxes() { 
    var score=0; 
    var checkboxes = { 
     "id_1" : 3, 
     "id_2" : 1, 
     "id_3" : 2, 
     "id_4" : 5 
    }; 

    var arrayOfIds = []; // to store array of ids 

    $.each(checkboxes,function(key, val) { // populate array with ids 
     arrayOfIds.push(key); 
    }); 

     // create a selector of the IDs 
    $("#" + arrayOfIds.join(',#')).change(function() { 
      // alert the score 
     alert(checkboxes[ this.id ]); 
     if (this.checked) { 
      //do something when it is checked 
     } else { 
      //do something else 
     } 
    }); 
} 
+0

Grazie. una spiegazione del mio fraintendimento di ciò che stava accadendo e una possibile soluzione: +1 :) –

+0

@Magic - Prego, fammi sapere se hai qualche domanda: o) – user113716

+0

Eh dopo tutto questo mi sono appena reso conto che questo non funziona in parte perché il div che contiene queste checkbox non è disponibile su $ (document) .ready ... Bei tempi di debugging delle cose sbagliate. –

0

uso try 'legano' e ': checked'

$.each(checkboxes, function(key, value) { 
    $(this).bind('change', function() { 
     if ($(this).is(':checked')) { 
     //do something when it is checked 
     } else { 
     //do something else 
     } 
    }); 
}); 
+0

In jQuery $ (this) .change (... è una scorciatoia per $ (this) .bind ("cambia", ... – Fenton

2

Suggerirei ottenere le caselle di controllo in modo più naturale ...

$("input[type='checkbox']").change(function() { 
    alert("Event is bound"); 
}); 

Se si desidera limitare quali caselle di controllo per usa, potresti aggiungere una classe, anche se se puoi evitare di aggiungere classi non necessarie, il tuo html sarà più pulito.

7

Si consiglia di aggiungere un contenitore e selezionare tutte le caselle di controllo contemporaneamente.

E per quanto riguarda la tua domanda, la firma dell'evento è errata, la corretta è function(e){}. Inoltre, devi controllare se l'elemento è selezionato e non cliccato.

$("#chk").change(function(e){ 
    if ($(this).is(":checked")) 
     alert("checked"); 
    else 
     alert("not checked"); 
}); 

Per facilitare, utilizzare un contenitore

HTML di esempio

<div id="checks"> 
    <input type="checkbox" id="chk1" /> 
    <input type="checkbox" id="chk2" /> 
    <input type="checkbox" id="chk3" /> 
    <input type="checkbox" id="chk4" /> 
</div> 

E per i punteggi, preferisco impostare i dati sugli elementi, ad esempio:

$("#chk1").data("Score", 3); 
$("#chk2").data("Score", 1); 
$("#chk3").data("Score", 2); 
$("#chk4").data("Score", 5); 

$("#checks :checkbox").change(function(e){ 
    if ($(this).is(":checked")) 
     alert("checked Score: " + $(this).data("Score")); 
    else 
     alert("not checked Score: " + $(this).data("Score")); 
}); 
+0

Mi piace anche questo approccio.Grazie per qualcosa di diverso. –

Problemi correlati