2009-09-06 6 views
5

私は、開始点をクリックして終了点をクリックし、選択された2点の間の様々なフォーム要素を操作できるようにします。jqueryを使用してdom内の2つの既知の要素の間で要素をトラバースする方法はありますか?

ページは多数の行を含むテーブルであり、各行にはその行の質問に対する回答を操作/保存するための関連情報が含まれています。各行には値の隠れた入力と、主に熟練していないユーザーのためのはい/いいえラジオボタンがあります。この質問のTDセルは、ユーザが「はい」、「いいえ」、「空」の間でクリックまたはトグルすることを可能にする。だから基本的には、ページにラジオボタンを残して、はい/いいえを表示し、隠しフィールドを使用して(1,0、-1)の値を格納します。

これは、質問セルをクリックします。

$(".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); 
    }); 

は今、私は、彼らが2番目の項目をクリックしたどこまですべて、次の質問を移入開始点をクリックして、その答えを持っているユーザーをできるようにしたいです。離れて10の質問、または20の質問、それは未知の変数です。 130の質問があるページがあり、20の質問が「はい」の場合があります。上記のように、各行には「質問」セルがあり、その前のセルはアイテムセルです。

私は、以下にリストされているクリック/ dblclickイベントにバインドされたjqueryセレクタ/関数に基づいて、開始要素と終了要素を設定する方法を知っています。

私がよく分からないことは、DOMをトラバースする方法、またはページ上の2つの選択されたポイントの間で操作する必要があるすべての要素を選択することです。

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); 
     } 
    }); 

答えて

2

IMHOは以下のようにするのが最も良い方法です。クラス名 "item"を持つ要素のコレクションをループすることができます。開始要素を見つけると、記述した処理を開始できます。あなたは「これ」を持っているので、あなたはあなたの質問であなたがしていたことを行うことができます。クリック機能。

 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

これを利用して私が必要なことをすることができました。 – Breadtruck

0

開始要素に開始クラスを追加し、終了要素に終了クラスを追加するのが最も簡単な方法です。次に、開始点と終了点の間で要素をトラバースするときに、開始クラス名または終了クラス名をチェックし、適切なアクションを実行/防止できます。

EDIT:このプラグインのような

何かがそれを行います。このプラグインでは、範囲の境界を定義する両方の要素が同じ親を持ち、同じ要素型(nodeName)であるとみなします。独自の開始および終了クラス名を使用することも、単にデフォルトの 'start'および '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); 

ここでWorking Demoだそう

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

、あなたは次のように使用することができます。コードを表示する場合は、/をURL末尾に追加します。私は、startClass、endClass、および要素タイプのパラメータに基づいてjQueryオブジェクトを返すユーティリティを作成することを考えていましたが、それはあなたが必要とするものに対して過度のものになります。

EDIT 2:

あなたのコメントを踏まえて、私は

  1. それを通してあなたを話すことができるあなたのケースで、私は、テキストの入力であると考えている問題の要素を含むjQueryオブジェクトを取得します親が親要素である$('parent > input:text')のようになります(入力を渡す:プラグインがインデックスに依存するため、親要素の外側のページに他のテキスト入力があると、テキスト自体は正しく動作しません)。あなたは(のような.rangeSelector({ start: "myStartClass", end: "myEndClass"})、または単にあなたが任意のオブジェクトに渡す必要はありません、その場合にはデフォルトstartendを使用したい場合は、オプションで渡すことができます

  2. は異なる開始と終了のクラス名とrangeSelectorに反対します。 (無オプションオブジェクトが定義されていない場合、または全く性質を持つオブジェクト)

  3. 設定変数はオプションで渡されたオブジェクトの特性を有する(オブジェクトのプロパティとして定義される)デフォルトをマージする。

  4. jQueryオブジェクトで扱っている要素の型を計算し、 name変数。これは、jQueryオブジェクトの最初の要素のnodeName文字列を配列に分割し、配列内の最後の文字列項目の値に名前を割り当てることによって行われます。

  5. startおよびendのクラス名でマークされた項目の開始および終了インデックスを計算します。この場合のインデックスは、その親内の要素の0から始まる位置を参照します。

  6. は、jQueryオブジェクトの開始点と終了点(両端を含む)の間の要素だけをjQueryオブジェクトとして返します(これにより、さらにjQueryコマンドをチェーンすることができます)。これはslice()コマンドを使用します。これはjQueryオブジェクトでArray.slice()と同じように機能します。

+0

どのような方法でトラバースするのですか?私のコード内に開始要素と終了要素を設定しているためです。 – Breadtruck

+0

@Russ:私はマットのコードを使って私がする必要のあるものをハックしましたが、私はあなたのことを再訪します。 – Breadtruck

0

の質問は少し古いですが、ここで私は私のプロジェクトのために使用ソリューションです:

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); 

使用

$('body').between($('#someid'), $('#someid2')).each(function() { 
    // Do what you want. 
}); 
関連する問題