Search code examples
javascriptselectlistbox

Move elements from a listbox to another


I have 2 listboxes and when a button is pressed I need to move an option from one to another.

I did this:

HTML

<table border="1" cellpadding="5">
    <tr>
        <td> Un-Selected <br />
            <select multiple="multiple" id="selectBoxOne" size="5" class="selectListBox">
                <option value="0" id="multiple0">Option 0</option>
                <option value="1" id="multiple1">Option 1</option>
                <option value="2" id="multiple2">Option 2</option>
                <option value="3" id="multiple3">Option 3</option>
                <option value="4" id="multiple4">Option 4</option>
                <option value="5" id="multiple5">Option 5</option>
            </select>
            <br />
            <input type="checkbox" id="selectAllFirst" />Select All or Ctrl+Click
        </td>
        <td>
            <div onclick="move('left');">
                << </div>
                    <div onclick="move('right');"> >></div>
        </td>
        <td> Selected <br />
            <select name="policyCode" multiple="multiple" id="selectBoxSecond" size="5" class="selectListBox"></select>
            <br />
            <input type="checkbox" id="selectAllSecond" />Select All or Ctrl+Click
        </td>
    </tr>
</table>

javascript:

// Declare elements

var selectOptions = Array();
selectOptions[0] = "Option 0";
selectOptions[1] = "Option 1";
selectOptions[2] = "Option 2";
selectOptions[3] = "Option 3";
selectOptions[4] = "Option 4";
selectOptions[5] = "Option 5";

// function to move an element from a box to the other
function move(sens)
{               
    if (sens == "right")
    {
        var selObj = document.getElementById('selectBoxOne');    
        var chkAll = document.getElementById("selectAllFirst")
        var destination = document.getElementById("selectBoxSecond");
    }
    else
    {
        var selObj = document.getElementById('selectBoxSecond');    
        var chkAll = document.getElementById("selectAllSecond")
        var destination = document.getElementById("selectBoxOne");
    }
    var selectedArray = new Array();        
    var i;
    var count = 0;
    if (chkAll.checked == 1)
    {
        for (i = 0; i<selectOptions.length; i++)
        {
            selectedArray[i] = i;
        }
    }
    else
    {            
        for (i=0; i<selObj.options.length; i++) {
            if (selObj.options[i].selected) {
                selectedArray[count] = selObj.options[i].value;
            count++;
            }
        }            
    }
    
    for (i = 0; i < selectedArray.length; i++)
    {
        var optionTag = document.createElement("option");
        id = selectedArray[i];
        optionTag.innerHTML = selectOptions[id];
        optionTag.value = id;
        optionTag.id = "multiple"+id;
        destination.appendChild(optionTag);
        var rmv = document.getElementById("multiple"+id);
        rmv.parentNode.removeChild(rmv);
    }
}

Now: The script works great from moving from left box to the right box. But when I try the other way around it kind of crashes. No error returned but I know for sure is the removal part (if I comment it it works fine... except that it generates duplicates since there is no removal of the moved option).

To be more specific, this 2 lines: var rmv = document.getElementById("multiple"+id); rmv.parentNode.removeChild(rmv);

Since there is no error returned, I don't know how to fix this.


Solution

  • An id has to be unique, or it won't work properly. As you add the new option before removing the original, you get two options with the same id, and you won't find the original option when you want to remove it.

    Just swap these three lines around, so that you remove the option before adding the new one. From this:

    destination.appendChild(optionTag);
    var rmv = document.getElementById("multiple"+id);
    rmv.parentNode.removeChild(rmv);
    

    to this:

    var rmv = document.getElementById("multiple"+id);
    rmv.parentNode.removeChild(rmv);
    destination.appendChild(optionTag);