Bala
Bala

Reputation: 3638

How to avoid duplication of values while adding multiple values to a textbox dynamically in JS?

I am trying to add multiple values to a hidden field. It's working fine, but I want the values which are getting added in the hidden field to be unique and not to get added if a value is entered more than once.

interestedin is the name of the selectbox where the values are selected and interest is the id of the hiddenfield where the values are getting added as comma separated values while selecting options in the selectbox.

if a same option is selected twice, it's getting added in the hidden field twice. I don't want any values to get added in the hidden fields though its selected twice.

the function clicker is called while selecting the values in the select box(name="interestedin") and the values will be added in the hidden field (id="interest")

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

Upvotes: 0

Views: 349

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1075895

I'd use an object as a flags holder for whether you've seen a value before, since looking up properties in objects is something JavaScript engines optimize for. In contrast, if you hold this information in an array, calls to Array#indexOf that don't find anything get slower and slower as you add more entries to it.

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

That assumes you also want each value listed in arr only once. Note the use of Array#join rather than string concatenation. And since we're now only putting each value in arr once, we don't need count at all.

Upvotes: 1

nnnnnn
nnnnnn

Reputation: 150080

There're several ways to do it. You could use the string method .indexOf() to check if the value is already in your str variable. Or use an object to store the values that have already been added, for ease of lookups. But given that you are already building an array with the values in you can check the array also with .indexOf() (noting that older versions of IE don't support array.indexOf(), but there's an implementation of it at MDN that you can easily include in your project).

Your function can be tidied up somewhat:

  • You should declare all variables with var or they'll be global (unless you're doing that on purpose).
  • When the for loop ends your count and i variables will have the same value as each other so you don't need both (note that JavaScript doesn't have block scope so i can be accessed anywhere within the function and not just in the for loop).
  • You don't need the length or strr variables since both are used just once: you could say document.getElementById('interest').value = str.substr(0,str.length-1); or even ... = str.slice(0,-1);
  • You don't need the str variable either since you're adding items to the array and can create a comma-separated string directly from the array with .join().

So:

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

You don't show what your setProductPrice() function does, but why are you passing in both an array and a parameter that is essentially the array's length? The function can get the length itself as a property of the array. In any case I still pass it in in my code above.

Upvotes: 0

Jamie Dixon
Jamie Dixon

Reputation: 54021

Each time a new item is added I would also add it to an array outside of your clicker function.

This way you can check for the existence of the item in the array before attempting to add it again.

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.

Upvotes: 0

Related Questions