Add -remove an option to dropdown menu

Hello
I am trying to write to a function. Whn I check a checkbox, the items belongs to that checkbox item comes to dropdown menu, and when I uncheck it, it goes away from the dropdpwn. I can add, but cannot remove when I uncheck the checkbox.Here is my code.

var items = [
            "#1001#item1#10.5#10#1#direc1#",
            "#1002#item2#20.5#10#2#direc2#",
            "#1003#item3#20.5#10#3#director3#",
function checkboxChange(ev) {
               var count = items.length;
               var select = document.getElementById('formsec');
               for(var i = 0; i < count; i++){

                      if( ev.value=="1001" &&ev.checked  )
                            
					    {
     				   var item = items[i];
                       var currentitem = item.split('#');
                       if(currentitem[5]=="1" ){
                       var opt = document.createElement('option');
                       opt.value = currentitem[1];
                       opt.innerHTML = currentitem[2];
                       select.appendChild(opt);
					   } 
	 <TD>
                    Choose the item: </br>          
                    <input type="checkbox" id="category1" name="choice" value="1001" onchange="checkboxChange(this)" />Category1<br />
                   <input type="checkbox" id="category2" name="choice" value="1002" onchange="checkboxChange(this)" />Category2<br />
		   <input type="checkbox" id="category3" name="choice" value="1003" onchange="checkboxChange(this)" />Category3<br />
                </TD>

Please post valid code.

This is when things like jQuery selectors become so handy…

Pure Javascript Options:
Option 1:
Stick a dumpster attribute into the option so you can re-index it out again.

opt.setAttribute('wark',currentitem[5])

And then check each option for the presence of (or value of) the ‘wark’ attribute, and removeChild it.

Option 2:
Assign a specific class to the option, getElementsByClassName to find them, and remove all of them. (Hint: child.parentNode.removeChild(child))

Option 3: Catch all the nodes you add, stick them into an array, and when you want to remove them, cycle through the array and follow the removal step for Option 2.

I dont have any class defined. After if how can I say if the value 1001 is not selected, remove the opt from drop down menu?
Thanks

function checkboxChange(ev) {
			 var checkBoxes = document.getElementsByName("choice");	
               var count = items.length;
               var select = document.getElementById('odevsec');
               for(var i = 0; i < count; i++){
                      if( ev.value=="1001" &&ev.checked  )
                            
					    {
     				   var item = items[i];
                       var currentitem = item.split('#');
                       if(currentitem[5]=="1" ){
                       var opt = document.createElement('option');
                       opt.value = currentitem[1];
                       opt.innerHTML = currentitem[2];
                       select.appendChild(opt);
					   }

I can fill the options while checking the checkboxes but cannot remove the options when I uncheck the boxes. Could anyone help me?

https://codepen.io/Seyfi/pen/jzJojO

Well you dont want to remove them where you’ve marked, because that if is for when it IS checked.

Lets clean up that code a bit, remove some of the redundancy. We dont actually care about the ev.value in the IF condition.

function checkboxChange(ev) {
     var checkBoxes = document.getElementsByName("choice"); //Why do we need this?
     var count = items.length;
     var select = document.getElementById('odevsec');
  if(ev.checked) {  //We're adding things!
     for(i = 0; i < count; i++) { //Could also be done with items.forEach...                            
     var item = items[i]; // Wouldnt need that line then.
     var currentitem = item.split('#');
     if(currentitem[5]== ev.value.slice(-1) ){ //I only care about the last digit.
       var opt = document.createElement('option');
       opt.value = currentitem[1];
       opt.innerHTML = currentitem[2];
       opt.dataset.group = currentitem[5]; //Tuck this away for later use...
       select.appendChild(opt);
    }        
} else { //Well if we're not adding things, we're deleting them. Cause there was an event.
    var options = select.children; //Collect all the children.
    for(i = 0; i < options.length; i++) { //Walk through the children.
        if(options[i].dataset.group == ev.value.slice(-1)) { //Remember that thing we tucked away? Time to use it.
          select.removeChild(options[i]); //Nice and simple.
        }
    }
}

Alternatively, we can get a little fancy.

  if(ev.checked) { 
     items.forEach(function(item) {                            
          var currentitem = item.split('#');
          if(currentitem[5]== ev.value.slice(-1) ){
                  var opt = document.createElement('option');
                 opt.value = currentitem[1];
                 opt.innerHTML = currentitem[2];
                 opt.dataset.group = currentitem[5];
                select.appendChild(opt);
         } 
      });
} else {
  document.querySelectorAll('[data-group="'+ev.dataset.group+'"]').forEach(x=>select.removeChild(x));
}

Incidentally, if you’re storing the value as the same number as the thing in position 5, why? I dont understand your data structure.

Hello ;
[5] storing the type of the dvd that is why I am storing it but I might be wrong.

Hello
Thanks for your quick answer. When I run your first recommandation I remove 2 items from each checkbox selected. For example first checkbox is 1,4,7,10 but when I uncheck it 4 and 10 remains, same for checkbox 2 and 3. When ı uncheck box2, 5 and 11 remains, when uncheckbox 3 6 and 12 remains.
Any recommendations will be appreciated.
Your second solution did not work for uncheck case.
Thanks
https://codepen.io/Seyfi/pen/jzJojO

So in your data, the value in position 5 is always the same as the last digit of the thing in position 1

#100 1 #dvd10#10.5#10# 1 #director10#”,

That’s what i based my simplification off of. If this is NOT the case for all items, then we definitely need to store the value of the 5th element.
Also, if the checkboxes are meant to represent the type (thing you keep in position 5), why is their value set to the thing in position 1??? Surely you want position 5’s value there. Then we wouldnt be doing slicing and such.

As far as that block of code failing, it’s because i forgot .children is a live nodelist. Need to kill it into an array to prevent indexing screwups.

    var options = select.children;

=>

    var options = [].slice.call(select.children);

You are such a great person, man, Thanks alot.

For the selected items I need to put a billing area in a textbox.
When the person choose to buy the item, it will be added to text area only if the person clicks to buy button.
I am trying but not working with the following code

document.form4.total.value ="";
 var sum = 0;
 for(i=0; i < items.length; i++) 
     {
  
    var fields = items[i].split(/#/);
          
    var type = fields[1];
      
    var name = fields[2];
          
    var price=fields[3];
           
    textContent += name + " " + price + " ";
  
    sum = sum + parseInt(document.odev4.choice[i].value);
     }
     
       
 var urunListElement = document.getElementById("urun_list");
       
 urunListElement.innerHTML = textContent;
   
 document.listForm.total.value = sum ;
	
 
}

For the selected items(from dropdown menu) I need to put them in a billing area in a textbox.
When the person choose to buy the item, it will be added to text area only if the person clicks to buy button.
In summary, I need to add the items that is clicked by Buy button and show sum ,the total for the customer. Any help will be really appreciated.
Thanks
I am trying but not working with the following code.

Off Topic:

@smobody: when you post code on the forums, you need to format it so it will display correctly. (You will see from the edits that various people have been doing this for you on your earlier posts.)

You can highlight your code, then use the </> button in the editor window, or you can place three backticks ``` (top left key on US/UK keyboards) on a line above your code, and three on a line below your code. I find this approach easier, but unfortunately some European and other keyboards don’t have that character.

only thing i can see wrong with your code is that ‘textContent’ is not pre-defined. You initialized sum to be 0, but didnt set textContent to be “”.

Could you check my code which I send you via email

I dont read/reply to messages on the forum. Post your code and i’ll take a look, or someone else will beat me to it. S’kinda the point of forums…

1 Like

Hello;
I want to choose a movie or more than one movie and add the selected ones to textarea after clickoing Buy button. I can add to the text area one or more movies but can not select seperately,. After I add, I need to get sum of the movies. Anyone can check my code and help me to fix it?
Thanks
https://codepen.io/Seyfi/pen/XEwqLy

So… your code works. Partially.

You wont want to sum AFTER you add, you want to do it WHILE you add. You’re already pulling the data to get at the information (there’s obviously room to improve on the data storage side, btw), so do the summing while you’re doing the adding.

I rewrote your function a little bit while working it out.

function copyDataToTextArea() {
  var selected = document.querySelectorAll('#optionsec option:checked');
  var values = Array.from(selected).map((x) => x.innerHTML);
  var total = 0;
  items.forEach(function(x) { //This could be a lot easier if items was a proper JSON array.
    var item = items.split("#"):
    if(values.contains(item[2])) {
      total += parseInt(item[3]);
      outarray.push(item[2]);
    }
  });
   document.getElementById("copydata").innerHTML = outarray.join("\n");
   document.getElementById("sumfield").innerHTML = sum;
}

I may also have added an ID to your sum field.

If items was a proper JSON array, the code might look something more like:

function copyDataToTextArea() {
   var selected = document.querySelectorAll('#optionsec option:checked');
   var values = Array.from(selected).map((x) => x.innerHTML);
   document.getElementById("copydata").innerHTML = items.filter(x=>values.contains(x.title)).map(x=>x.title).join("\n");
   document.getElementById("sumfield").innerHTML = items.filter(x=>values.contains(x.title)).map(x=>x.price).reduce((a,b) => a+b);
}

But then we’d need to change the rest of the functions too, to accommodate the new structure.

1 Like