2009-09-06 10 views
5

Desidero consentire all'utente di fare clic su un punto iniziale, quindi fare clic su un punto finale e essere in grado di manipolare vari elementi del modulo tra i due punti selezionati.Come dovrei attraversare elementi tra due elementi noti nella dom usando jquery?

La pagina è una tabella con numerose righe e ogni riga contiene le informazioni pertinenti per manipolare/salvare una risposta alla domanda in quella riga. Ogni riga ha un input nascosto per il valore, nonché i pulsanti di opzione Sì/No, principalmente per utenti non esperti. La cella TD con la domanda consente all'utente di fare clic o di alternare tra Sì, No, Vuoto. Quindi in pratica ho lasciato i pulsanti di opzione sulla pagina per mostrare Sì/No e utilizzare un campo nascosto per memorizzare un valore di (1,0, -1)

Questo è quello che uso per impostare la risposta quando la cella della domanda è cliccato.

$(".question").bind("click dblclick", function(e) { 

     var newClassName = "AnswerUnknown"; 

     var hiddenAnswerId = $(this).attr('id').replace("question", "answer"); 

     var answer = parseInt($("#" + hiddenAnswerId).val()); 

     var newValue; 

     switch (answer) { 
      case -1: 
       newClassName = "AnswerCorrect"; 
       newValue = 1; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', 'checked'); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', ''); 
       break; 
      case 1: 
       newClassName = "AnswerWrong"; 
       newValue = 0; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', ''); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', 'checked'); 
       break; 
      default: 
       newClassName = "AnswerEmpty"; 
       newValue = -1; 
       $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', ''); 
       $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', ''); 
     } 
     $("#" + hiddenAnswerId).val(newValue); 
     $(this).removeClass().addClass(newClassName); 
    }); 

Ora voglio permettere all'utente di fare clic su un punto di partenza e che hanno risposta popolare tutti alla seguente domanda giù ovunque hanno cliccato sul secondo punto. Potrebbe essere 10 domande di distanza, o 20 domande, è una variabile sconosciuta. Potrebbe esserci una pagina con 130 domande e 20 domande di seguito potrebbero essere "Sì". Come indicato sopra ogni riga ha una cella "Domanda" e la cella prima è la cella dell'oggetto.

So come impostare l'elemento iniziale e l'elemento finale in base a un selettore/funzione jQuery associato a un evento click/dblclick elencato di seguito.

Quello di cui non sono sicuro è come attraversare la dom o selezionare tutti gli elementi che devo manipolare tra i due punti selezionati nella pagina.

var StartItem; 
    var EndItem; 

    $(".item").bind("click dblclick", function(e) { 

     var StartClassName = "AnswerUnknown"; 
     var EndClassName = "AnswerUnknown"; 
     var StartAnswerId; 
     var EndAnswerId; 
     var StartAnswer; 

     if (StartItem === undefined) { 
      StartItem = this; 
      StartAnswerId = $(this).attr('id').replace("item", "rs"); 
      StartAnswer = parseInt($("#" + StartAnswerId).val()); 
     } 
     else { 
      if (EndItem === undefined) { 
       EndItem = this; 
       EndAnswerId = $(this).attr('id').replace("item", "rs"); 
       EndAnswer = parseInt($("#" + EndAnswerId).val()); 
      } 
     } 


     if (StartItem == this) { 
      $(this).removeClass().addClass(StartClassName); 
     } 

     if (EndItem == this) { 
      $(this).removeClass().addClass(EndClassName); 
     } 
    }); 

risposta

2

Il modo migliore con cui IMHO deve fare qualcosa di seguito. È possibile eseguire il looping sulla raccolta di elementi con il nome di classe "item" e quando si trova l'elemento di avvio è possibile iniziare a eseguire l'elaborazione descritta. Dato che hai "questo" puoi prendere quell'id e fare quello che stavi facendo nella tua domanda.

 var counter = 0; 

    // This will loop over each element with classname "item", so make sure you take that into account 
      $('.item').each(function(i) { 
     // function returns this, but you can see what index your on with 'i' 
       if (this == StartItem) { 
        // You can start processing rows 
        counter = 1; 
       } 
       else { 
        if (counter > 0) { 
         // Process rows/items after the first item above 
         counter = counter + 1; 
        } 
       } 
       if (this == EndItem) { 
        counter = 0 
        // Finish up processing if any 
        //Break out of each; 
       } 

      }); 
+0

Sono stato in grado di utilizzarlo per fare ciò di cui avevo bisogno. – Breadtruck

0

suona come il modo più semplice sarebbe quella di aggiungere una classe di partenza per l'elemento di partenza e una classe estremità all'elemento finale. Quindi, quando si attraversano gli elementi tra inizio e fine, è possibile verificare il nome della classe iniziale o finale ed eseguire/prevenire azioni appropriate.

EDIT:

Qualcosa di simile a questo plugin lo farà. Il plugin presuppone che entrambi gli elementi che definiscono i limiti dell'intervallo abbiano lo stesso padre e siano dello stesso tipo di elemento (nodeName). È possibile utilizzare i propri nomi di inizio e fine classe, o semplicemente utilizzare l'impostazione predefinita 'start' e 'end'.

(function($) { 

    $.fn.rangeSelector = function(options) { 

    var settings = $.extend({ startClass : 'start', endClass: 'end'},options||{}); 
    var name = this[0].nodeName.split(':'); 
    name = name[name.length -1]; 
    var startIndex = $(name + '.' + settings.startClass).prevAll().length; 
    var endIndex = $(name + '.' + settings.endClass).prevAll().length + 1; 
    return this.slice(startIndex,endIndex); 
    } 

})(jQuery); 

e quindi è possibile utilizzare in questo modo

/* 
* will get all textboxes between textboxes 
* with className start and end, inclusive 
*/ 
$('input:text').rangeSelector(); 

Ecco un Working Demo. Se si desidera visualizzare il codice, aggiungere /modificare alla fine dell'URL. Stavo pensando di scrivere un'utilità per restituire un oggetto jQuery basato su parametri startClass, endClass e tipo di elemento da includere, ma sarebbe eccessivo per ciò che richiedete.

EDIT 2:

Alla luce del vostro commento, posso parlare attraverso di essa

  1. ottenere un oggetto jQuery che contiene gli elementi in questione, che nel tuo caso credo sia input di testo , quindi sarebbe qualcosa come $('parent > input:text') dove genitore è l'elemento genitore (passando in input: il testo di per sé non funzionerà correttamente se hai altri input di testo nella pagina al di fuori dell'elemento genitore poiché il plugin si basa sugli indici).

  2. È possibile passare in un oggetto opzioni per rangeSelector con nomi diversi di inizio e di classe finale, se si vuole (come .rangeSelector({ start: "myStartClass", end: "myEndClass"}), o semplicemente utilizzare il default start e end, nel qual caso non è necessario passare in qualsiasi oggetto.

  3. la variabile impostazioni fonde i valori predefiniti (definite come proprietà di un oggetto) con le proprietà del passato in opzioni oggetto (o un oggetto senza proprietà se nessun oggetto opzione è definito).

  4. calcola il tipo di elementi con cui stiamo trattando nell'oggetto jQuery e memorizzali name variabile. Questo viene fatto dividendo la stringa nodeName del primo elemento nell'oggetto jQuery in una matrice e assegnando il nome al valore dell'ultima stringa nell'array.

  5. Calcolare gli indici di inizio e fine per gli articoli contrassegnati con i nomi delle classi start e end. L'indice in questo caso si riferisce alla posizione a 0 dell'elemento all'interno del suo genitore.

  6. ritorno solo gli elementi dell'oggetto jQuery tra l'indice di inizio e fine (compreso) come un oggetto jQuery (in modo che ulteriori comandi jQuery possono essere concatenati in). Questo utilizza il comando slice(), che funziona allo stesso modo su un oggetto jQuery come fa Array.slice() sugli array.

+0

Così quale metodo dovrei usare per attraversare, so qual è l'eleme nts perché sto impostando l'elemento start e end all'interno del mio codice. – Breadtruck

+0

@Russ: Ho usato il codice di Matt per hackerare quello che dovevo fare, ma rivisiterò le tue cose, perché la tua strada potrebbe essere una soluzione più elegante una volta che ho il tempo di pensarci su! – Breadtruck

0

La questione è un po 'vecchio, ma qui è la soluzione che uso per i miei progetti:

selettore jQuery

(function ($) { 
    $.fn.between = function (elm0, elm1) { 
     var index0 = $(this).index(elm0); 
     var index1 = $(this).index(elm1); 

     if (index0 <= index1) 
      return this.slice(index0, index1 + 1); 
     else 
      return this.slice(index1, index0 + 1); 
    } 
})(jQuery); 

Uso

$('body').between($('#someid'), $('#someid2')).each(function() { 
    // Do what you want. 
}); 
Problemi correlati