2011-11-08 22 views
0

非表示のフィールドに複数の値を追加しようとしています。うまくいきましたが、値を複数回入力すると、非表示フィールドに追加される値が一意であり、追加されないようにしたいと考えています。JS内のテキストボックスに複数の値を動的に追加する際に値の重複を避けるにはどうすればよいですか?

interestedinは値が選択されている選択ボックスの名前で、interestは選択ボックスでオプションを選択するときに値がカンマ区切りの値として追加される非表示フィールドのIDです。

同じオプションを2回選択すると、隠しフィールドに2回追加されています。私は、選択された2つの値を使って隠しフィールドに値を追加することは望ましくありません。

選択ボックスの値を(名前は=「interestedin」)を選択しながら、機能クリッカーが呼び出され、値は、隠しフィールド(ID =「関心」)

function clicker(){ 
      var itemsobj=document.getElementsByName("interestedin[]"); 
      str=''; 
      //alert(itemsobj[0].value); 
      //alert('test'); 
      count=0; 
      var arr = new Array(); 
    for(var i=0;i<itemsobj.length;i++) 
     { 
      count += 1; 
      str +=itemsobj[i].value+','; 
      //alert(str); 
      arr[i] = itemsobj[i].value; 
       } 
      var length=str.length; 
      var strr=str.substring(0,length-1); 
      document.getElementById('interest').value = strr; 
      //alert(strr); 


      setProductPrice(arr,count); 
     } 

答えて

1

オブジェクトのプロパティを調べることは、JavaScriptエンジンが最適化するものであるため、これまでに値を見たことがあるかどうかをフラグホルダとしてオブジェクトを使用したいと思います。これとは対照的に、この情報を配列に保持すると、何も見つからないArray#indexOfへの呼び出しは、それ以上のエントリを追加するにつれて遅くなり、遅くなります。

function clicker() { 
    var itemsobj = document.getElementsByName("interestedin[]"); 
     seen = {}, 
     value, 
     i, 
     arr = []; 

    for (i = 0; i < itemsobj.length; i++) 
    { 
     value = itemsobj[i].value; 
     if (!seen[value]) // Works because if we haven't, `seen[value]` is `undefined` which is falsy 
     { 
      seen[value] = true; 
      arr.push(value); 
     } 
    } 

    document.getElementById('interest').value = arr.join(","); 
    setProductPrice(arr, arr.length); 
} 

これは、それぞれの値がarrに1回だけ記載されていることを前提としています。文字列の連結ではなくArray#joinの使用に注意してください。そして、今度は各値をarrに一度だけ入れているので、countはまったく必要ありません。

0

たびに追加されます新しい項目が追加され、それをあなたのクリッカー関数外の配列にも追加します。

この方法では、アレイにアイテムが存在するかどうかを確認してから、再度追加しようとすることができます。

UPDATE

Here's a quick demo

var usedItems = []; 

var possibleItems = ["one","two","two","three"] 

for(var i=0; i < possibleItems.length; i++) 
{ 
    // If the item is not in the array 
    if(usedItems.indexOf(possibleItems[i]) == -1) 
    { 
     usedItems.push(possibleItems[i]); 
    } 
} 

alert(usedItems.length); // Should return 3 since item "two" is possible twice. 
+0

配列ではなく、オブジェクトを使用し、値をキーとして使用します。 'if(!obj [value]){obj [value] = true;/* ...値を加えて... * /} ' –

+0

ああ、いい点T.J.ありがとう:) –

0

それを行うには、いくつかの方法があります。文字列メソッド.indexOf()を使用して、値がすでにstr変数に入っているかどうかを確認できます。また、参照を容易にするために、既に追加された値を格納するためにオブジェクトを使用することもできます。しかし、すでに配列の値を設定している場合は、.indexOf()という配列をチェックすることもできます(IEの古いバージョンはarray.indexOf()をサポートしていませんが、MDNに実装されていますあなたのプロジェクトに含める)。

あなたの機能は多少片付けすることができます。

  • あなたはvarですべての変数を宣言する必要がありますか(あなたが故意にそれをやっている場合を除き)、彼らはグローバルになるでしょう。
  • forループが終了すると、countiの変数は同じ値になりますので、両方とも必要ではありません(JavaScriptはブロックスコープを持たないため、iには関数内のどこでもアクセスできますforループ内で)。両方を一度だけ使用されているので、あなたがlengthまたはstrr変数を必要としない
  • :あなたはdocument.getElementById('interest').value = str.substr(0,str.length-1);あるいは... = str.slice(0,-1);
  • を言うことができるあなたはstr変数を必要としないのいずれか、あなたは、配列や缶にアイテムを追加しているので、アレイから直接コンマで区切られた文字列を.join()で作成します。

ので:

// if you don't want to use array.indexOf() due to lack of support in IE<9 
// just remove the if statement that uses it and uncomment the three 
// lines that use "items" 

function clicker(){ 
    var itemsobj = document.getElementsByName("interestedin[]"), 
     arr = [], 
     // items = {}, 
     val, 
     i; 

    for(i=0; i<itemsobj.length; i++) 
    { 
     val = itemsobj[i].value; 

     // if (!items[val]) { 
     if (-1 === arr.indexOf(val)) { 
     // items[val] = true; 
     arr.push(val); 
     } 
    } 

    document.getElementById('interest').value = arr.join(","); 

    setProductPrice(arr,arr.length); 
} 

あなたのsetProductPrice()機能が何をするのか表示されませんが、なぜあなたはアレイと、本質的に、配列の長さであるパラメータの両方に渡していますか?この関数は、長さ自体を配列のプロパティとして取得できます。いずれにせよ、私はまだ私のコードでそれを渡します。

関連する問題