Link to home
Start Free TrialLog in
Avatar of APD Toronto
APD TorontoFlag 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,
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

<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.
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.
Avatar of APD Toronto

ASKER

Dave, this is just a prototype.

Is the javascript for this that hard?
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.
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

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?
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.
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.
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

But, how would you adjust my javascript to remove?
ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial