Supongamos que queremos crear una de esas maravillosas listas dobles de items que nos permita pasar el objeto seleccionado de una lista a otra y viceversa. Esto no tiene ningún secreto, pero si quisieramos que al volver a pasar un item de la segunda lista a la original lo hiciera en la posición en la que estaba originalmente, la cosa se complica un poco.

Esta es una solución. Quizás no la mejor, pero sirve:

Para esto lo primero que tendremos que tener es 3 controles ListBox; dos para las listas de origen y destino, y uno oculto para guardar estáticamente la lista original.

    <asp:ListBox ID="lstOrigen" runat="server" Width="600px" Height ="150px"></asp:ListBox><br /><br />
    <asp:ListBox ID="lstOculto" runat="server" Width="1px" Height ="1px" style="display:none"></asp:ListBox><br />
    <asp:ListBox ID="lstDestino" runat="server" Width="150px" Height ="150px"></asp:ListBox>

Seguidamente, añadiremos nuestro código javascript maravilloso:

       function Add(){
           var lbOrigen = document.getElementById('lstOrigen');
           if(lbOrigen.options.selectedIndex > -1){
                var lbDestino =  document.getElementById('lstDestino'); //obtenemos el contro listbox
                var selectedText = lbOrigen.options[lbOrigen.options.selectedIndex].text;
                var selectedValue = lbOrigen.options[lbOrigen.options.selectedIndex].value;
                for (var i=0; i < lbDestino.options.length; i++) //buscamos coincidencias
                {
                    if (lbDestino.options[i].value.toLowerCase().match(selectedValue.toLowerCase()))
                    {
                                  return false;
                    }
                }
                  var opt = document.createElement("option");
                  opt.text = selectedText;
                  opt.value = selectedValue;
                  lbDestino.options.add(opt);
                  lbOrigen.options.remove(lbOrigen.options.selectedIndex);
           }
        }
        function Remove(){
           var lbDestino = document.getElementById('lstDestino');
           if(lbDestino.options.selectedIndex > -1){
                var lbOculto =  document.getElementById('lstOculto'); //obtenemos el contro listbox
                var lbOrigen =  document.getElementById('lstDestino'); //obtenemos el contro listbox
                var selectedText = lbDestino.options[lbDestino.options.selectedIndex].text;
                var selectedValue = lbDestino.options[lbDestino.options.selectedIndex].value;
                var found = 0; //flag que nos indica si hemos encontrado el item en el listado de destino
                clearListBox(lbOrigen); //limpiamos la lista de origen
                for (var i=0; i < lbOculto.options.length; i++) //buscamos coincidencias del listado original
                {
                    for (var j=0; j < lbDestino.options.length; j++) //buscamos en el listado de añadidos
                    {
                        if (lbOculto.options[i].value.toLowerCase().match(lbDestino.options[j].value.toLowerCase())) //el item fue movido
                        {
                              found = 1; //hemos encontrado el item
                              if (lbOculto.options[i].value.toLowerCase().match(selectedValue.toLowerCase())){
                                 //si el item esta seleccionado lo añadimos al listado de origen
                                 lbOrigen.options.add(crearListItem(selectedText,selectedValue));
                                 break;
                              }
                        }
                    }
                       if (found == 0){ //si no se ha encontrado significa que no está en la lista de destino y debemos añadirlo
                        lbOrigen.options.add(crearListItem(lbOculto.options[i].text,lbOculto.options[i].value));
                       }else{
                         found = 0; //reiniciamos el flag
                       }
 
 
                }
                  lbDestino.options.remove(lbDestino.options.selectedIndex);
           }
        }
 
        function crearListItem(text, value){
                  var opt = document.createElement("option");
                  opt.text = text;
                  opt.value = value;
                  return opt;
        }
        function clearListBox(lb){
            for (var i=lb.options.length-1; i>=0; i--){
                lb.options[i] = null;
            }
            lb.selectedIndex = -1;
        }

Bueno, la función “Add” añadirá el item seleccionado de la lista original a la lista de destino. Para ello comprobamos si hay algun item seleccionado y si este no se encuentra ya en la lista destino, lo añadimos y lo eliminamos del origen.

La función remove es más complicada. Inicialmente limpiará la lista de origen (donde queremos devolver el item a su posición original) y la volvera a reconstruir item por item.

Para ello recorrera la lista oculta(donde tenemos el listado completo de items originales) y buscara coincidencias en la lista de destino. Si no existe coincidencias significa que dicho item no se movió, por lo que lo recuperamos en la lista de origen. Si lo encuentra significa que dicho item lo hemos movido anteriormente, por lo que tenemos que comprobar si es el item que queremos devolver a su posición inicial (esta seleccionado). De ser así, lo añadiremos igualmente a la lista de origen, recuperando asi el item en la posición original (recordad que todo este proceso se realiza en función a la lista oculta), si no está seleccionado, lo obviamos ya que dicho item permanecerá en la lista de destino.

Finalmente eliminamos el item que hemos movido de la lista destino.

Las dos últimas funciones sirven para borrar todos los items de un ListBox y para crear un ListItem con un value y text determinados.

Un saludo