programing

복제가 선택한 값을 복제하고 있지 않습니다.

padding 2023. 9. 15. 20:49
반응형

복제가 선택한 값을 복제하고 있지 않습니다.

예상하지 못했지만 복제된 값 검사에서 다음 테스트가 실패합니다.

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");
});

이게 맞나

추가적인 연구 끝에 JQuery 버그 트래커 시스템에서 이 티켓을 찾았습니다. 이 티켓은 버그를 설명하고 해결책을 제공합니다.분명히 선택 값을 복제하는 것은 너무 비싸서 수정되지 않을 것입니다.

https://bugs.jquery.com/ticket/1294

클론 메소드를 사용한 것은 무엇이든 복제할 수 있는 일반적인 메소드였기 때문에 값을 설정할 선택이 언제나 있을지 확실하지 않습니다.그래서 다음과 같이 덧붙였습니다.

var selects = $(cloneSourceId).find("select");
$(selects).each(function(i) {
    var select = this;
    $(clone).find("select").eq(i).val($(select).val());
});

다음은 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);

Chief7의 답변으로 플러그인을 만들었습니다.

(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);

간단히 테스트만 했는데, 잘 되는 것 같습니다.

저의 접근 방식은 조금 다릅니다.

복제 중에 선택 항목을 수정하는 대신에 모든 것을 보고 있습니다.select의 페이지에 있는change이벤트, 그리고 나서 값이 변경되면 필요를 추가합니다.selected선택한 항목에 속성 지정<option>그래서.<option selected="selected">. 이제 선택 항목이 에 표시되어 있습니다.<option>마크업은 당신이 할 때 통과될 것입니다..clone()그것.

필요한 코드는 다음과 같습니다.

//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
});

이제 원하는 방법으로 선택한 내용을 복사할 수 있으며, 그 값도 복사할 수 있습니다.

$("#my-select").clone(); //will have selected value copied

이 솔루션은 사용자 정의가 덜하다고 생각하기 때문에 나중에 수정할 경우 코드가 끊어질까 걱정하지 않으셔도 됩니다.

페이지의 모든 선택 항목에 적용하지 않으려면 다음과 같이 첫 번째 줄의 선택 항목을 변경할 수 있습니다.

$(document).on("change", "select.select-to-watch", function(){

Chief 7의 답변 간소화:

var cloned_form = original_form.clone()
original_form.find('select').each(function(i) {
    cloned_form.find('select').eq(i).val($(this).val())
})

다시 한번, jQuery 티켓은 다음과 같습니다. http://bugs.jquery.com/ticket/1294

예. 왜냐하면 'select' DOM 노드의 'selected' 속성이 옵션의 'selected' 속성과 다르기 때문입니다.jQuery는 어떤 식으로든 옵션의 속성을 수정하지 않습니다.

대신 이 방법을 사용해 보십시오.

$('option', select).get(1).setAttribute('selected', 'selected');
//    starting from 0   ^

밸브 기능이 어떻게 작동하는지 정말로 관심이 있다면 검사해 보는 것이 좋을 것입니다.

alert($.fn.val)

클로닝 a<select>복사하지 않습니다.value=에 대한 재산.<option>s. 그래서 마크의 플러그인은 모든 경우에 작동하지 않습니다.

수정하려면 복제하기 전에 이 작업을 수행합니다.<select>값:

var $origOpts = $('option', this);
var $clonedOpts = $('option', $clone);
$origOpts.each(function(i) {
   $clonedOpts.eq(i).val($(this).val());
});

복제하는 또 다른 방법은<select>jQuery 1.6.1+...에서 옵션이 선택되었습니다.

// instead of:
$clonedSelects.eq(i).val($(this).val());

// use this:
$clonedSelects.eq(i).prop('selectedIndex', $(this).prop('selectedIndex'));

후자를 사용하면 다음을 설정할 수 있습니다.<option>설정 후 값selectedIndex.

$(document).on("change", "select", function(){
    original = $("#original");
    clone = $(original.clone());
    clone.find("select").val(original.find("select").val());

});

양식을 직렬화하기 위해 선택한 값이 필요한 경우 이 방법을 사용할 수 있습니다.

$clonedForm.find('theselect').val($origForm.find('theselect').val());

1시간 동안 효과가 없었던 다양한 솔루션을 시도한 끝에 이 간단한 솔루션을 개발했습니다.

$clonedItem.find('select option').removeAttr('selected');
$clonedItem.find('select option[value="' + $originaItem.find('select').val() + '"]').attr('selected', 'true');

@pie6k는 좋은 아이디어를 보여줍니다.

제 문제를 해결해 줬습니다.조금 바꿔봅니다.

$(document).on("change", "select", function(){
    var val = $(this).val();
    $(this).find("option[value=" + val + "]").attr("selected",true);
});

보고만 하고 있습니다.어떤 경건하게 알려지지 않은 이유로, 그리고 이것이 내가 처음으로 시험했던 것이고, 나는 내 코드를 전혀 바꾸지 않았지만, 이제.

$("#selectTipoIntervencion1").val($("#selectTipoIntervencion0").val());

어프로치가 효과가 있습니다.왜 그런지, 아니면 내가 뭔가를 바꾸자마자 다시 작동을 멈출지는 모르겠지만, 일단은 이것으로 진행할 것입니다.도와주신 모든 분들께 감사합니다.

언급URL : https://stackoverflow.com/questions/742810/clone-isnt-cloning-select-values

반응형