2009-12-12 8 views
5

Wie der Titel sagt, versuche ich, jQuery eine Reihe zusätzlicher Feldsets basierend auf dem in einem Dropdown-Feld ausgewählten Wert hinzuzufügen. Schachtel Wenn beispielsweise die Seite geladen wird, hat das Dropdown-Feld den Standardwert 1, und das Standard-Fieldset wird angezeigt. Wenn der Benutzer nun einen anderen Wert in dieser Dropdown-Liste auswählt, sollte die Anzahl der Feldgruppen durch Klonen entsprechend angepasst werden (ich nehme an, dies wäre die beste Lösung). Hier ist, was ich bisher:Verwenden von jQuery zum dynamischen Hinzufügen von Formularfeldern (oder Feldgruppen) basierend auf einem Dropdown-Wert

Dropdown-Feld Code ...

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

... die jQuery ändern Zuhörer ...

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

... und die Funktion selbst (es basiert tatsächlich auf einem jQuery-Plugin, das ich dachte, war ein guter Ausgangspunkt für das, was ich brauche):

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

das Objekt, das ist c loned ist etwas wie <fieldset id="item_dup_1"><input><input><input></fieldset>. Ich denke nicht, dass es notwendig ist, auch den vollständigen Code dafür zu zeigen.

Dies wirkt wie ein Charme für die erste Änderung, aber wenn der Benutzer den Wert erneut ändert, ist es, wenn die Dinge schief gehen, und anstatt die richtige Anzahl der Feldsets zeigt es mehr. Es sieht so aus, als würde es die Anzahl der benötigten Fieldsets von Grund auf neu berechnen, abgesehen von der Tatsache, dass Fieldsets bereits hinzugefügt wurden, und das ist, was mein Problem tatsächlich ist. Ich habe auch eine Funktion (hier nicht gezeigt, nur um die Frage klar und so kurz wie möglich zu halten), die dem geklonten Fieldset neue IDs zuweist, um doppelte IDs zu verhindern, und die ohne Probleme funktioniert.

Ich bin überzeugt, dass ich etwas falsch mache, aber ich habe meinen Kopf gegen eine Wand damit seit zwei Tagen geschlagen, versuchend zu finden, was es ohne Glück so überhaupt ist, jede Hilfe würde mehr als geschätzt sein !

Vielen Dank im Voraus!

Antwort

6

Ich mag es nicht, die Lösung von Nate B.

  • es benötigt ein zusätzliches Containerelement
  • alles neu erstellt, so dass Daten verloren gehen eingegeben bereits
  • ein Wartungsproblem schafft: HTML-Markup des fieldset dupliziert wird (einmal in HTML, einmal als String für anfügen)
  • erzeugt ungültige IDs für die fieldset
012 (ids kann nicht mit einer Zahl beginnen)

Das macht, was Sie wollen und ähnlich wie Sie es getan haben. Behält nur die IDs in einem Datenattribut auf dem ursprünglichen Element bei (anstatt das gesamte Klonobjekt zu behalten, das große Mengen an Speicher verwenden könnte). Hält alle bereits eingegebenen Werte. Erstellt nicht alles neu, wenn Sie z. 3 bis 5. Stattdessen werden nur zwei neue Feldgruppen generiert. Entfernt sie in umgekehrter Reihenfolge, in der sie erstellt wurden.

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

Brilliant, wirkt wie ein Charme! Das war etwas, was ich im Sinn hatte, blieb aber auf dem Weg stecken. Vielen Dank, sehr geschätzt. –

+0

Vielleicht ist dies allgemein bekannt, aber ich habe festgestellt, dass, wenn Daten in die Eingabefelder des Fieldsets eingegeben wurden, das geklont wird, bevor die Fieldset-Anzahl geändert wird, die eingegebenen Daten ebenfalls geklont werden. Doing eine einfache clone.find ("input"). Je (function() {jQuery (this) .val ("")}); Nachdem der Klon erstellt wurde, erhalten Sie einen sauberen Klon, mit dem Sie arbeiten können. Hoffe, das wird jemandem ein paar Minuten ersparen. –

+1

Nun, das ist mehr oder weniger allgemein bekannt und auch die Art und Weise, wie Klon funktionieren soll. Die jQuery 'clone' Methode verwendet intern die normale DOM Methode' cloneNode (true) '. Überprüfen Sie hier für eine Beschreibung, wie es sich verhält http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-3A0ED0A4 – jitter

0

Warum klonen Sie, anstatt nur etwas zu tun (zusammen mit Ihrem aktuellen Ereignis-Listener)?

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

Die count im Fieldset ist, wie Sie die eindeutige ID Problem umgehen kann.

+0

Dies ist definitiv ein nützlicher und interessanter Ansatz, den ich nicht gedacht, aber ich könnte ein Problem mit ihm in Form eines Benutzers der Auswahl 6 als Fieldset zähle und dann seine Meinung zu ändern und nur wollte 4 sehen Feldgruppen Wie würde ich die letzten zwei Feldsets entfernen, ohne eine Leerstelle() für den Container zu erstellen und den Benutzer so die Daten in den ersten vier Feldsets erneut eingeben zu lassen? Gibt es ein Gegenstück zu append()? –

+0

Bitte ignorieren Sie meinen letzten Kommentar. Wenn ich darüber nachdenke, merke ich, dass ich einfach nach dem letzten Kind des Containers suchen kann, in dem die generierten Feldsets stehen, und mache eine .remove() darauf. Tausend Dank ! –

Verwandte Themen