Ich habe es nicht erwartet, aber der folgende Test schlägt bei der Überprüfung des geklonten Werts fehl:
test("clone should retain values of select", function() {
var select = $("<select>").append($("<option>")
.val("1"))
.append($("<option>")
.val("2"));
$(select).val("2");
equals($(select).find("option:selected").val(), "2", "expect 2");
var clone = $(select).clone();
equals($(clone).find("option:selected").val(), "2", "expect 2");
});
Ist das richtig?
html
selected
bei jeder Änderung ein Attribut hinzufügen , damit es einfach geklont werden kann?Hier ist eine feste Version der Klonmethode für jQuery:
https://github.com/spencertipping/jquery.fix.clone
// Textarea and select clone() bug workaround | Spencer Tipping // Licensed under the terms of the MIT source code license // Motivation. // jQuery's clone() method works in most cases, but it fails to copy the value of textareas and select elements. This patch replaces jQuery's clone() method with a wrapper that fills in the // values after the fact. // An interesting error case submitted by Piotr Przybył: If two <select> options had the same value, the clone() method would select the wrong one in the cloned box. The fix, suggested by Piotr // and implemented here, is to use the selectedIndex property on the <select> box itself rather than relying on jQuery's value-based val(). (function (original) { jQuery.fn.clone = function () { var result = original.apply(this, arguments), my_textareas = this.find('textarea').add(this.filter('textarea')), result_textareas = result.find('textarea').add(result.filter('textarea')), my_selects = this.find('select').add(this.filter('select')), result_selects = result.find('select').add(result.filter('select')); for (var i = 0, l = my_textareas.length; i < l; ++i) $(result_textareas[i]).val($(my_textareas[i]).val()); for (var i = 0, l = my_selects.length; i < l; ++i) result_selects[i].selectedIndex = my_selects[i].selectedIndex; return result; }; }) (jQuery.fn.clone);
quelle
$('.inputPrefixListIx:first').clone().insertAfter('.inputPrefixListIx:last');
wie es aussehen sollte, wenn man darüber nachdenktjQuery.fn.clone
?Aus der Antwort von Chief7 wurde ein Plugin erstellt:
(function($,undefined) { $.fn.cloneSelects = function(withDataAndEvents, deepWithDataAndEvents) { var $clone = this.clone(withDataAndEvents, deepWithDataAndEvents); var $origSelects = $('select', this); var $clonedSelects = $('select', $clone); $origSelects.each(function(i) { $clonedSelects.eq(i).val($(this).val()); }); return $clone; } })(jQuery);
Nur kurz getestet, aber es scheint zu funktionieren.
quelle
Mein Ansatz ist etwas anders.
Anstatt die Auswahl während des Klonens zu ändern, beobachte ich nur jede
select
Seite auf einchange
Ereignis. Wenn der Wert geändert wird, füge ichselected
dem ausgewählten das erforderliche Attribut hinzu,<option>
damit es wird<option selected="selected">
. Da die Auswahl jetzt im<option>
Markup markiert ist , wird sie übergeben, wenn Sie es tun.clone()
.Der einzige Code, den Sie benötigen:
//when ANY select on page changes its value $(document).on("change", "select", function(){ var val = $(this).val(); //get new value //find selected option $("option", this).removeAttr("selected").filter(function(){ return $(this).attr("value") == val; }).first().attr("selected", "selected"); //add selected attribute to selected option });
Und jetzt können Sie die Auswahl nach Belieben kopieren, und der Wert wird ebenfalls kopiert.
$("#my-select").clone(); //will have selected value copied
Ich denke, diese Lösung ist weniger benutzerdefiniert, sodass Sie sich keine Sorgen machen müssen, wenn Ihr Code beschädigt wird, wenn Sie später etwas ändern.
Wenn Sie nicht möchten, dass es auf jede Auswahl auf der Seite angewendet wird, können Sie die Auswahl in der ersten Zeile wie folgt ändern:
$(document).on("change", "select.select-to-watch", function(){
quelle
initial selection
?Vereinfachung der Antwort von Chief7:
var cloned_form = original_form.clone() original_form.find('select').each(function(i) { cloned_form.find('select').eq(i).val($(this).val()) })
Hier ist wieder das jQuery-Ticket: http://bugs.jquery.com/ticket/1294
quelle
Ja. Dies liegt daran, dass sich die Eigenschaft 'selected' eines DOM-Knotens 'select' vom Attribut 'selected' der Optionen unterscheidet. jQuery ändert die Attribute der Optionen in keiner Weise.
Versuchen Sie stattdessen Folgendes:
$('option', select).get(1).setAttribute('selected', 'selected'); // starting from 0 ^
Wenn Sie wirklich daran interessiert sind, wie die val-Funktion funktioniert, sollten Sie dies untersuchen
quelle
Durch das Klonen von a
<select>
wird die Eigenschaft auf s nicht kopiert . Das Plugin von Mark funktioniert also nicht in allen Fällen.value=
<option>
Führen Sie zum Beheben folgende Schritte aus, bevor Sie die
<select>
Werte klonen :var $origOpts = $('option', this); var $clonedOpts = $('option', $clone); $origOpts.each(function(i) { $clonedOpts.eq(i).val($(this).val()); });
Eine andere Möglichkeit zum Klonen der
<select>
ausgewählten Option in jQuery 1.6.1 + ...// instead of: $clonedSelects.eq(i).val($(this).val()); // use this: $clonedSelects.eq(i).prop('selectedIndex', $(this).prop('selectedIndex'));
Mit letzterem können Sie die
<option>
Werte nach dem Einstellen von einstellenselectedIndex
.quelle
$(document).on("change", "select", function(){ original = $("#original"); clone = $(original.clone()); clone.find("select").val(original.find("select").val()); });
quelle
Wenn Sie nur den Wert der Auswahl benötigen, um das Formular oder ähnliches zu serialisieren, funktioniert dies für mich:
$clonedForm.find('theselect').val($origForm.find('theselect').val());
quelle
Nachdem ich 1 Stunde lang verschiedene Lösungen ausprobiert hatte, die nicht funktionierten, habe ich diese einfache Lösung erstellt
$clonedItem.find('select option').removeAttr('selected'); $clonedItem.find('select option[value="' + $originaItem.find('select').val() + '"]').attr('selected', 'true');
quelle
@ pie6k zeigen eine gute Idee.
Es hat mein Problem gelöst. Ich ändere es ein wenig klein:
$(document).on("change", "select", function(){ var val = $(this).val(); $(this).find("option[value=" + val + "]").attr("selected",true); });
quelle
Ich melde mich nur zurück. Aus irgendeinem gottesfürchtigen unbekannten Grund, und obwohl dies das erste war, was ich getestet habe und ich meinen Code überhaupt nicht geändert habe, jetzt das
$("#selectTipoIntervencion1").val($("#selectTipoIntervencion0").val());
Ansatz funktioniert. Ich habe keine Ahnung warum oder ob es nicht mehr funktioniert, sobald ich etwas ändere, aber ich werde jetzt damit weitermachen. Vielen Dank an alle für die Hilfe!
quelle