2009-12-12 31 views
5

Como dice el título, lo que estoy tratando de hacer es tener jQuery añadir una serie de conjuntos de campos adicionales en función del valor seleccionado en un desplegable caja de abajo. Por ejemplo, cuando se carga la página, el menú desplegable tiene un valor predeterminado de 1 y se muestra el conjunto de campos predeterminado. Ahora, si el usuario selecciona un valor diferente en ese menú desplegable, el número de conjuntos de campos se debe ajustar en consecuencia, a través de la clonación (supongo que esta sería la mejor solución). Esto es lo que tengo hasta ahora:Usando jQuery para añadir dinámicamente campos de formulario (o conjuntos de campos) en base a un valor cuadro desplegable

desplegable cuadro de código ...

<select id="itemCount" name="itemCount"> 
<option value="1">1 item</option> 
<option value="2">2 items</option> 
<option value="3">3 items</option> 
<option value="4">4 items</option> 
<option value="5">5 items</option> 
<option value="6">6 items</option> 
</select> 

... el cambio oyente jQuery ...

$(document).ready(function() { 
$("#itemCount").change(function(){ 
    var itemCountVal = jQuery(this).val(); 
    $("#item_dup_1").fieldsManage(itemCountVal); 
}); 
}); 

... y la propia función (en realidad se basa en un plugin de jQuery que pensé que era un buen punto de partida para lo que necesito):

jQuery.fn.fieldsManage = function (number) { 
    var clone, 
    objTemplate = source.clone(true), 
    source = jQuery(this), 
    maxClones = number - 1, 
    clones = []; 

    if (clones.length < maxClones) { 
    while (clones.length < maxClones) { 
     clone = objTemplate.clone(true).insertAfter(clones[clones.length - 1] || source); 
     clones.push(clone); 
    } 
    } 

    if (clones.length > maxClones) { 
    // Fieldsets removal function goes here. 
    } 
} 

El objeto que está siendo c loned es algo así como <fieldset id="item_dup_1"><input><input><input></fieldset>. No creo que sea necesario mostrar el código completo para ello también.

Esto funciona como un amuleto para el primer cambio, pero si el usuario cambia el valor de nuevo, es cuando las cosas van mal, y en lugar de mostrar el número correcto de conjuntos de campo, se muestra más. Parece que se está calculando el número de conjuntos de campo necesarios comenzando desde cero, sin tener en cuenta el hecho de que los conjuntos de campo ya se han agregado, y este es realmente mi problema. También tengo una función (no se muestra aquí solo para mantener la pregunta clara y lo más breve posible) que asigne nuevos ID al conjunto de campos clonado para evitar ID duplicados y que funcione sin problemas.

Estoy convencido de que estoy haciendo algo mal, pero he estado golpeando mi cabeza contra una pared con esto durante dos días, tratando de encontrar lo que es sin suerte en absoluto, cualquier ayuda sería más que apreciada !

¡Gracias de antemano!

Respuesta

6

no me gusta la solución de Nate B.

  • que necesita un elemento contenedor adicional
  • recrea todo, perdiendo así ya entró
  • crea un problema de mantenimiento: Formato HTML de la fieldset se duplica (una vez en HTML, una vez como cadena para agregar)
  • crea de ID no válido para los conjuntos de campos (de ID no puede comenzar con un número)

Esto hace lo que quiere y es similar a lo que hizo. Mantiene solo los identificadores en un atributo de datos en el elemento original (en lugar de mantener todo el objeto clonado que podría usar cantidades masivas de memoria). Mantiene todos los valores ya ingresados. No recrea todo si cambias de, por ejemplo, 3 a 5. En su lugar, solo genera dos nuevos conjuntos de campo. Los quita en orden inverso donde fueron creados.

jQuery.fn.fieldsManage = function (number) { 
    var ele = $(this); 
    var clones = ele.data("clones"); 
    clones = clones ? clones : new Array(ele.attr("id")); 
    if (clones.length < number) { 
     var clone; 
     while(clones.length < number) { 
      clone = ele.clone(true); 
      var id = clones[0]+clones.length; 
      clone.attr("id", id); 
      $("#"+clones[clones.length-1]).after(clone); 
      clones.push(id); 
     } 
    } else { 
     while(clones.length > number) { 
      $("#"+clones.pop()).remove(); 
     } 
    } 
    ele.data("clones", clones); 
} 

$(document).ready(function() { 
    $("#itemCount").change(function() { 
     $("#item_dup_1").fieldsManage(this.value); 
    }); 
}); 
+0

¡Brillante, funciona como un encanto! Eso es más o menos lo que tenía en mente, pero me quedé atrapado en el camino. Gracias, muy agradecido. –

+0

Quizás esto sea de conocimiento común, pero descubrí que si se han ingresado datos en los campos de entrada del campo que se está clonando antes de cambiar el recuento de campos, los datos ingresados ​​también se clonarán. Hacer un simple clone.find ("input"). Each (function() {jQuery (this) .val ("")}); después de que el clon haya sido creado le dará un clon limpio para trabajar. Espero que esto le ahorre a alguien un par de minutos. –

+1

Bueno, este es un conocimiento más o menos común y también la forma en que se supone que 'clon' funciona. El método jQuery 'clone' utiliza internamente el método DOM normal' cloneNode (true) '. Consulte aquí para obtener una descripción de cómo se comporta http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-3A0ED0A4 – jitter

0

¿Por qué está clonando en lugar de hacer algo como esto (junto con su oyente de eventos actual)?

$(".divWhereTheseGo").empty(); 
var count = 0; 
while (count < maxItems) { 
    $(".divWhereTheseGo").append("<fieldset id=\"" + count + "\">your form info</fieldset>"); 
    count++; 
} 

El count en el grupo de campos es como se puede manejar el tema único de identificación. datos

+0

Esto es definitivamente un enfoque útil e interesante que no he pensado, pero pude ver un problema con él en la forma de un usuario seleccionar 6 como el conjunto de campos contar y luego cambiar de opinión y sólo querer 4 conjuntos de campo. ¿Cómo voy a eliminar los dos últimos conjuntos de campos sin hacer un vacío() en el contenedor y, por lo tanto, hacer que el usuario ingrese los datos en los primeros 4 conjuntos de campos de nuevo? ¿Hay un opuesto a append()? –

+0

Por favor haga caso omiso de mi último comentario. Pensando más en eso, me di cuenta de que simplemente podía buscar el último hijo del contenedor en el que los conjuntos de campo generados van y eliminarlo. Un millón de gracias ! –

Cuestiones relacionadas