Avatar of APD Toronto
APD Toronto
Flag for Canada asked on

javaScript to Transfer Items Between Listboxes

HI Experts,

I am hoping if someone can point me in the right direction with how to start the JavaScript for the HTML below.

As you will see that between the two listboxes I have 10 locations A through J, with unique IDs for each location. In real application this will be from a database with over 100 locations, so the unique ID cannot be in order to match the alphabetical sequence.

What I am trying to do is when the user select location D (value 2) and clicks "Add", JavaScript will remove this from the right listbox and add it to the left listbox, between Location C and E (in alphabetical order), while still maintaining the IDs : 5 for C, 2 for D, and 8 for E.

My ultimate goal is, when submitted, I will use PHP to read all locations in the left listbox and add all values to a linked MySQL table that will represents the users preferred locations.

My HTML is :
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<style>
   
    #left{
        float: left;
        margin-left: 50px;
    }  
    
    .assoc_buttons{
        margin-left: 20px;
        width: 8em;
        margin-right: 20px;
        vertical-align: middle;
    }
    #right{
        clear: both;
      
        
    }
</style>

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
      
    <form id="frm" name="frm">
        
        <select name="left" id="left" size="7">
            <option value="5">Location C</option>
            <option value="8">Location E</option>
        </select>
        
        <input type="button" class="assoc_buttons" name="btn_add" value="< Add" onclick="add();"><br>
        <input type="button" class="assoc_buttons" name="btn_add_all" value="<< Add All" onclick="add_all();"><br>
        <input type="button" class="assoc_buttons" name="btn_del" value="Delete >" onclick="del();"><br>
        <input type="button" class="assoc_buttons" name="btn_del_all" value="Delete All >>" onclick="del_all();">

        <select name="right" id="right" size="7">
            <option value="4">Location A</option>
            <option value="6">Location B</option>
            <option value="2">Location D</option>
            <option value="10">Location F</option>
            <option value="1">Location G</option>
            <option value="9">Location H</option>
            <option value="7">Location I</option>
            <option value="3">Location J</option>
            
        </select>
        
    </form>
    </body>
</html>
 

Open in new window


Thank you,
JavaScriptHTMLPHP

Avatar of undefined
Last Comment
Member_2_248744

8/22/2022 - Mon
Dave Baldwin

<style> goes in the <head> section.  Where you have it, it may be ignored.  Some browsers may not like your comment above the <head> section either.
Scott Fell

Check this out the multiselect.js. I have this in production on some projects and I think it does what you need http://loudev.com/.  It allows you to select items and "move them" to the other side so they are no longer selectable.    It works very nicely.  You simply code an select and use the jquery plug in to do the rest.
APD Toronto

ASKER
Dave, this is just a prototype.

Is the javascript for this that hard?
Your help has saved me hundreds of hours of internet surfing.
fblack61
Dave Baldwin

I don't know about that but invalid code makes it difficult to tell.  I am inclined not to help you with the rest of it if you want to use invalid code as a basis.  Too much chance of troubleshooting the wrong errors.
APD Toronto

ASKER
Here is the fixed version :). I also started the javascript for add();

<!DOCTYPE html>

<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <style>
            #left{
                float: left;
                margin-left: 50px;
            }  

            .assoc_buttons{
                margin-left: 20px;
                width: 8em;
                margin-right: 20px;
                vertical-align: middle;
            }
            #right{
                clear: both;
                vertical-align: middle;   
            }
        </style>

    </head>
    <body>
      
    <form id="frm" name="frm">
        
        <select name="left" id="left" size="7">
            <option value="5">Location C</option>
            <option value="8">Location E</option>
        </select>
        
        <input type="button" class="assoc_buttons" name="btn_add" value="< Add" onclick="add();"><br>
        <input type="button" class="assoc_buttons" name="btn_add_all" value="<< Add All" onclick="add_all();"><br>
        <input type="button" class="assoc_buttons" name="btn_del" value="Delete >" onclick="del();"><br>
        <input type="button" class="assoc_buttons" name="btn_del_all" value="Delete All >>" onclick="del_all();">

        <select name="right" id="right" size="7">
            <option value="4">Location A</option>
            <option value="6">Location B</option>
            <option value="2">Location D</option>
            <option value="10">Location F</option>
            <option value="1">Location G</option>
            <option value="9">Location H</option>
            <option value="7">Location I</option>
            <option value="3">Location J</option>
            
        </select>
        
    </form>
    
<script type="text/javascript">

    function add(){
        
        var from = document.getElementById('right');
        var to = document.getElementById('left');
        
        if (from.selectedIndex == -1){
            alert ("No Locations were selected to be added.");
            return false;
        }
        
        var selectedOption = 
        
    }


</script>
          
    </body>  
</html>

Open in new window

Dave Baldwin

Much better.  I'll take a look at that.

Interesting problem.  Solution is not obvious at the moment.  The 'id' is for the 'select' and not the options.  Is there going to be a fixed number of options to move?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
APD Toronto

ASKER
Actually, besides the CSS alignment (other post) this is what I came up so far...

<script type="text/javascript">

    function add(){
        
        var from = document.getElementById('right');
        var to = document.getElementById('left');
        
        if (from.selectedIndex == -1){
            alert ("No Locations were selected to be added.");
            return false;
        }
        
        var i = from.selectedIndex;
        var newVal = from.options[i].value;
        var newText = from.options[i].text;
        
        //Remove from item
        from.options.remove[i];
        
        //Add to item
        to.options[to.options.length] = new Option(newText, newVal);
        
    }


</script>

Open in new window


Add works.
Remove doesnt
Still need to figure out sort in my 'to' list.
Member_2_248744

greeting APD_Toronto, , looked at your code, and did NOT understand your arrangement of the SELECT and the buttons, so I used a <table> to keep the positions no matter what else is on the page.
Please look at my javascript in the code below It does the option "Moving" as you want to do Both on ADD and DELETE

<!DOCTYPE html>
<html><head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.tbl1 {
margin-left: 50px;
border: 1px solid #a33;
}
</style>
<script>
var rSel=false, lSel=false;

function id2obj(elmt1){return document.getElementById(elmt1);}

function moveOne(sel){
var del = rSel;
if (sel) {
  sel = lSel;
  } else {
  sel = rSel;
  del = lSel;
  }
var si = del.selectedIndex; 
if (si == -1){
if (del == rSel) sel = "RIGHT"; else sel = "LEFT";
  alert ("No Locations on "+sel+" were selected to be moved.");
  return;
  }
        
//alert ("selet= "+del.options[si].value+" - "+del.options[si].text);

  var opt = document.createElement('option');
  opt.value = del.options[si].value;
  opt.innerHTML = del.options[si].text;
  sel.appendChild(opt);
	
  del.removeChild(del.options[si]);
}
</script>
</head>
<body>
<form id="frm" name="frm">
<table class="tbl1"><tr><td>     
<select name="left" id="leftSel" size="7">
  <option value="5">Location C</option>
  <option value="8">Location E</option>
</select>
</td><td style="text-align:center;">    
<input type="button" name="btn_add" value="< Add" onclick="moveOne(1)"><br />
<input type="button" name="btn_add_all" value="<< Add All" onclick="add_all();"><br />
<input type="button" name="btn_del" value="Delete >" onclick="moveOne(0);"><br />
<input type="button" name="btn_del_all" value="Delete All >>" onclick="del_all();">
</td><td>
<select name="right" id="rightSel" size="7">
  <option value="4">Location A</option>
  <option value="6">Location B</option>
  <option value="2">Location D</option>
  <option value="10">Location F</option>
  <option value="1">Location G</option>
  <option value="9">Location H</option>
  <option value="7">Location I</option>
  <option value="3">Location J</option>
</select>
</td></tr></table>        
</form>
    
<script>
var rSel = id2obj('rightSel');
var lSel = id2obj('leftSel');
</script>
          
</body>  
</html>

Open in new window


If this is along the lines that you may want you can get all of the selcet options with -
   del.options

 and then for loop through all of them to move each one.

ask questions if you need more info.
Member_2_248744

update, a   moveAll( ) function -
function moveAll(sel){
var del = rSel;
if (sel) {
  sel = lSel;
  } else {
  sel = rSel;
  del = lSel;
  }
  
if (del.options.length < 1) {
  alert ("The Box is Empty, nothing to move.");
  return;
  }

var aryOp = [];
for (var i= del.options.length-1; i > -1 ; --i) {
  var al = aryOp.length;
  aryOp[al] = document.createElement('option');
  aryOp[al].value = del.options[i].value;
  aryOp[al].innerHTML = del.options[i].text;
  del.removeChild(del.options[i]);
  }

for (i= aryOp.length-1; i > -1 ; --i) {
  sel.appendChild(aryOp[i]);
  }
}

Open in new window

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
APD Toronto

ASKER
But, how would you adjust my javascript to remove?
ASKER CERTIFIED SOLUTION
Member_2_248744

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.