2010-10-23 22 views
5

Estoy trabajando en un proyecto en el que tengo un formulario que tendrá múltiples entradas 'seleccionar', todas con el mismo conjunto de opciones. Me gustaría usar jquery para deshabilitar/ocultar una opción en el resto de las entradas 'seleccionar', si ya se ha seleccionado.Prevenir selecciones múltiples del mismo valor

Por ejemplo:

<select id="1"> 
    <option value="volvo">Volvo</option> 
    <option value="saab">Saab</option> 
    <option value="mercedes">Mercedes</option> 
</select> 

<select id="2"> 
    <option value="volvo">Volvo</option> 
    <option value="saab">Saab</option> 
    <option value="mercedes">Mercedes</option> 
</select> 

El usuario elige 'Volvo' en la primera selección. Me gustaría eliminarlo de la segunda selección.

Cualquier información sería muy apreciada.

+0

¿Qué respuesta finalmente usó por favor? – netadictos

+0

@netadictos - Tuyo terminó trabajando de la mejor manera, pero todavía no era exactamente lo que estaba buscando. Decidí usar Jquery UI para hacer valores de formulario que se puedan arrastrar. Gracias por su ayuda :) – Batfan

+0

Jquery UI es siempre una forma muy moderna de hacer las cosas, me gusta. Al menos creo que es la solución a la pregunta tal como se describe ;-) – netadictos

Respuesta

5

continuacion código para continuar seleccionando y deshabilitando todas las veces que queramos.

Lo primero es habilitar cada opción, y luego mirar los valores seleccionados, y deshabilitar las opciones que coinciden con los valores seleccionados.

Estos 2 pasos son cruciales porque si selecciona de nuevo, los valores desactivados de antes continuarían deshabilitados.

NUEVA VERSIÓN

La forma más elegante, donde utilizamos un mapa() (in stackoverflow there is a good explanation about this method) y las funciones de jQuery filtro() para hacer el trabajo. Menos líneas, y creo que el mismo rendimiento o mejor.

http://www.jsfiddle.net/dactivo/keDDr/

$("select").change(function() 
{ 

     $("select option").attr("disabled",""); //enable everything 

    //collect the values from selected; 
    var arr = $.map 
    (
     $("select option:selected"), function(n) 
     { 
       return n.value; 
      } 
    ); 

    //disable elements 
    $("select option").filter(function() 
    { 

     return $.inArray($(this).val(),arr)>-1; //if value is in the array of selected values 
    }).attr("disabled","disabled"); 

}); 

NUEVA VERSIÓN

He editado mi respuesta, esta es mi versión final:

http://www.jsfiddle.net/dactivo/kNbWc/

$("select").change(function() 
        { 

     $("select option").attr("disabled",""); //enable everything 
     DisableOptions(); //disable selected values 

        }); 


function DisableOptions() 
{ 
    var arr=[]; 
     $("select option:selected").each(function() 
       { 
        arr.push($(this).val()); 
       }); 

    $("select option").filter(function() 
     { 

       return $.inArray($(this).val(),arr)>-1; 
    }).attr("disabled","disabled"); 

} 

OLD VERSION

http://www.jsfiddle.net/AyxL3/

$("select").change(function() 
        { 

     $("select option").attr("disabled",""); //enable everything 
     DisableOptions(); //disable selected values 

        }); 


function DisableOptions() 
{ 

    $("select option").filter(function() 
     { 
       var bSuccess=false; //will be our flag to know it coincides with selected value 
       var selectedEl=$(this); 
       $("select option:selected").each(function() 
       { 

        if($(this).val()==selectedEl.val()) 
        { 
         bSuccess=true; //it coincides we will return true; 
         return false; // this serves to break the each loop 
        }    

       }); 
       return bSuccess; 
    }).attr("disabled","disabled"); 

} 
+1

He editado mi respuesta – netadictos

+0

En la 'nueva versión', cuando selecciono una opción en la primera, inhabilito 2 en la segunda. En la 'más nueva' no deshabilita ninguna de ellas. – Batfan

+0

@Baffan - Lo siento , Me olvido de uno ")". Deberia de funcionar. – netadictos

3

Para ocultar ellos, utilizar el siguiente enfoque (desde IE error impide el uso de CSS propiedad "pantalla" a "ninguno" en una opción):

-Store la lista original de opciones en una matriz

-Tener una función para construir el selecto #x de una matriz, deslizándose previamente seleccionado artículos

-Asignar un controlador onchange para todas selecciona qué recorre todos selecciona posteriores y llama a esta función.

var option_value_order = {'volvo', 'saab', 'mercedes'}; 
var option_display_strings = new Array(); 
option_display_strings['volvo'] = 'Volvo'; 
//... 

// Assume each of the selects' ID value is "select_1", "select_2" instead of "1", "2" 
function redraw(selectNum) { 
    var selectId = "select_" + selectNum; 
    var s = document.getElementById(selectId); 
    s.options.length = 0; // empty out 
    var next = 0; 
    for (var i = 0; i < option_value_order.length; i++) { 
     var skip = 0; 
     for (var select_index = 0; select_index < selectNum; select_index++) { 
      if (document.getElementById("select_"+select_index).selected == i) 
       skip = 1; 
      if (skip == 0) { 
       var o = option_value_order[i]; 
       s.options[next] = o; 
       // Don't recall how to set value different from option display, 
       // using option_display_strings[o] 
       next++; 
      } 
     } 
    } 
} 

var total_selects = 2; 

function change_later_selects(s) { 
    var select_num = find_number(s.id); "this returns number 2 for "select_2" - homework 
    for (var i = select_num + 1; i <= total_selects; i++) { 
     redraw(i); 
    } 
} 

Y a continuación, el código HTML

<select id="select_2" onchange="change_later_selects(this);"> 
    <option value="volvo">Volvo</option> 
    <option value="saab">Saab</option> 
    <option value="mercedes">Mercedes</option> 
</select> 
+0

Voy a dar una oportunidad más tarde – Batfan

+1

¿Es ese JavaScript VANILLA en respuesta a una pregunta jQuery ?! +1 señor. –

+1

¿Pero por qué no mover ese evento 'onchange' al JS también? –

1

que podría hacer algo como

var curSelected = $('#1 option:selected').val(); 
$('#2 option[value="'+curSelected+'"]').remove() 

(por supuesto se puede utilizar directamente $(this) si va a añadir el cambio en las opciones de sí mismo a través el controlador change)

Por supuesto que esto no funcionará al revés :)

En ese caso, le sugiero que para construir sus opciones directamente con JavaScript para que tenga el programa completo de la que eliminar los elementos cuando sea necesario, antes de la sustitución hacia distintas select

2

es un ejemplo de trabajo aquí:

http://jsfiddle.net/aNxBy/

con sus datos, usted tiene que hacer esto:

$(document).ready(function() { 
    $('select').change(function() { 
     $('option[value=' + $(this).val() + ']').attr('disabled', 'disabled'); 
    }); 
}); 

Tenga en cuenta, sin embargo, que esto no hará que deshabilite la desactivación después de haberla cambiado a otro valor. No agregué esto aquí porque no especificó exactamente lo que necesitaba hacer después de deshabilitó la opción ... realmente podría ser una serie de escenarios posibles.

Una cosa que podría hacer es recorrer todos los elementos relevantes select cuando se dispare el evento de cambio, encontrar los valores de todas las opciones seleccionadas y deshabilitarlas cuando corresponda.

+0

¿Cómo voy a deshabilitar el 'deshabilitar'?Di si el usuario cambió de opinión sobre el valor que seleccionaron? – Batfan

+0

@Batfan de esta manera: http://api.jquery.com/removeAttr/ – treeface

+0

¿Cómo podría agregar eso al código? No soy un jquery pro y sigo teniendo problemas para descubrir exactamente cómo el código actual aplica el atributo 'disabled' – Batfan

1

Eche un vistazo a this.Es:

  1. obtiene el ID de la lista desplegable que acaba de cambiar
  2. bucles a través de todas las listas de selección
  3. eliminar el elemento que acaba de seleccionar de todas las otras listas
+0

Recibo un error 404 en ese enlace :( – Batfan

+0

lo siento, agregué un par de caracteres adicionales. –

+0

fijo esto no restablecerá las opciones seleccionadas anteriormente si selecciona una vez más. Desaparece, no deshabilita – netadictos

1
$(document).ready(function() { 
    $('#1').change(function() { 
     $('option.hidden').removeClass('hidden') 
     $('#2 option[value=' + $(this).val() + ']').addClass('hidden'); 
    }); 
    $('#2').change(function() { 
     $('option.hidden').removeClass('hidden') 
     $('#1 option[value=' + $(this).val() + ']').addClass('hidden'); 
    }); 
});

Asegúrate de que tienes en css

.hidden {display:none}

+0

esto no restablecerá las opciones seleccionadas anteriormente si selecciona una vez más. – netadictos

1

Esta cuestión fue el resultado google superior para la búsqueda de una respuesta a esta, por lo Publicaré una respuesta actualizada aquí. Esto es casi exactamente lo mismo que la respuesta de Netadictos, pero funciona para deshabilitar y reactivar los valores de selección y usa prop en lugar de attr. Trabajo verificado en Chrome 52.

$("select").change(function() 
    { 
     $("select option").prop("disabled",""); //enable everything 

     //collect the values from selected; 
     var arr = $.map 
     (
      $("select option:selected"), function(n) 
      { 
       return n.value; 
      } 
     ); 

     //disable elements 
     $("select option").filter(function() 
     { 
      return $.inArray($(this).val(),arr)>-1; //if value is in the array of selected values 
     }).prop("disabled","disabled"); 

     //re-enable elements 
     $("select option").filter(function() 
     { 
      return $.inArray($(this).val(),arr)==-1; //if value is not in the array of selected values 
     }).prop("disabled",""); 
    }).trigger("change"); // Trigger the change function on page load. Useful if select values are pre-selected. 
Cuestiones relacionadas