변경 전 선택 (드롭 다운) 값 얻기


237

내가 달성하고자하는 것은 <select>드롭 다운이 변경 될 때마다 변경하기 전에 드롭 다운 값을 원한다는 것입니다. 1.3.2 버전의 jQuery를 사용하고 on change 이벤트를 사용하고 있지만 내가 얻은 값은 변경 후입니다.

<select name="test">
<option value="stack">Stack</option>
<option value="overflow">Overflow</option>
<option value="my">My</option>
<option value="question">Question</option>
</select>

onchange 이벤트에서 스택으로 변경할 때 (즉, 스택으로 변경했을 때) 현재 My 옵션이 선택되어 있다고 가정 해 보겠습니다.이 경우 이전 값을 원합니다.

이것이 어떻게 달성 될 수 있습니까?

편집 : 내 경우에는 같은 페이지에 여러 개의 선택 상자가 있고 모든 항목에 동일한 항목이 적용되기를 원합니다. 또한 모든 선택은 ajax를 통해 페이지를로드 한 후에 삽입됩니다.


1
이것을 확인
하셨습니까

답변:


434

포커스 이벤트를 변경 이벤트와 결합하여 원하는 것을 달성하십시오.

(function () {
    var previous;

    $("select").on('focus', function () {
        // Store the current value on focus and on change
        previous = this.value;
    }).change(function() {
        // Do something with the previous value after the change
        alert(previous);

        // Make sure the previous value is updated
        previous = this.value;
    });
})();

실례 : http://jsfiddle.net/x5PKf/766


1
@Alpesh : 불행히도, jQuery 1.4.1 이상을 사용하지 않기 때문에 포커스변경 이벤트 와 함께 live () 를 사용할 수 없습니다 . 요소를 페이지에 삽입 한 후 바인드하도록 스크립트를 조정하면됩니다.
Andy E

1
고마워 나는 이미 라이브와 함께 바인딩했으며 성공적으로 작동했습니다. :)
Alpesh

4
변경 핸들러에서 select 요소에 집중해야합니다. 그렇지 않으면 반복되는 값 변경 후에 트리거되지 않습니다.
Alex

52
이 솔루션에 동의하지 않습니다. 값을 한 번 변경하면 작동하지만 한 번 더 변경하면 작동하지 않습니다. 초점을 풀려면 드롭 다운을 클릭하고 다른 곳을 클릭해야합니다. 제안 : $ ( "# dropdownId"). on ( 'change', function () {var ddl = $ (this); var previous = ddl.data ( 'previous'); ddl.data ( 'previous', ddl .val ());});
free4ride

5
@ free4ride, $(this).blur();변경 함수의 끝에서 호출 할 수 있도록 수정
chiliNUT

135

이것에 전역 변수를 사용하지 마십시오-여기에 데이터에 이전 값을 저장하십시오 예 : http://jsbin.com/uqupu3/2/edit

심판의 코드 :

$(document).ready(function(){
  var sel = $("#sel");
  sel.data("prev",sel.val());

  sel.change(function(data){
     var jqThis = $(this);
     alert(jqThis.data("prev"));
     jqThis.data("prev",jqThis.val());
  });
});

방금 페이지에 많은 선택이 있음을 보았습니다.이 방법은 각 선택에 대해 선택 값의 데이터에 이전 값을 저장하기 때문에 효과가 있습니다.


jQuery.data는 여기서 좋은 솔루션입니다. 솔루션에서 선택 요소가 많으면 성능에 영향을 미치는 각 선택 항목에 대한 클로저를 작성합니다
Avi Pinto

내 관심사는 성능에 관한 것이 아니었고, 함수를 만드는 것이 jQuery.data어쨌든 느리다는 것을 확신하지 못한다 .
August Lilleaas

9
jQuery.data 사용에 대한 반대 의견은 무엇입니까? 내가 아는 한 jQuery 라이브러리도 내부적으로 사용하고 그것을 사용하는 것이 좋습니다
Avi Pinto

jQuery Data를 사용하는 것에 확실히 동의합니다. 전역 변수를 사용하려고한다는 사실을 상기시켜 주셔서 감사합니다. 전역 변수에는 아무런 문제가 없지만 데이터를 사용하는 것이 더 간결합니다. 그러나 체인 초점과 변화도 좋습니다 :)
Piotr Kula

4
@ppumkin : 전역 변수에있어 한 가지 분명한 것은 하나만 지원합니다 select! 수락 된 답변은 모두 일치 select하지만 첫 번째 답변 의 값만 저장 하므로 중단됩니다 . data 입니다 그것을 할 수있는 더 좋은 방법. +1 :)
Gone Coding

86

나는 Avi Pinto의 솔루션을 사용합니다. jquery.data()

초점을 사용하는 것은 유효한 해결책이 아닙니다. 처음에는 옵션을 변경할 때 작동하지만 해당 선택 요소를 유지 한 상태에서 "위"또는 "아래"키를 누릅니다. 포커스 이벤트를 다시 거치지 않습니다.

따라서 솔루션은 다음과 같이 보입니다.

//set the pre data, usually needed after you initialize the select element
$('mySelect').data('pre', $(this).val());

$('mySelect').change(function(e){
    var before_change = $(this).data('pre');//get the pre data
    //Do your work here
    $(this).data('pre', $(this).val());//update the pre data
})

3
선택된 답변보다 훨씬 나은 훌륭한 솔루션!
TJL

2
두 번째 부분은 잘 작동하지만 첫 번째 부분은 데이터 속성을 설정하지 않습니다. 어떤 아이디어?
Sinaesthetic

1
@ Sinaesthetic, 나는 같은 문제가 있었고 이미이 대답을 찬성했습니다. 나는 $ (this)가 .data () 메소드에서 살아남지 않는다고 생각합니다. Avi Pinto의 대답은 그 가치에 대한 선택 요소로 되돌아 갔고 이것은 나를 위해 일했습니다 (따라서 Avi도 찬성했습니다).
goodeye

1
이것은! == $ ( 'mySelect') 이후 작동하지 않습니다. 다음은 고정 버전입니다. var $selectStatus = $('.my-select'); $selectStatus.on('change', function () { var newStatus = $(this).val(); var oldStatus = $(this).data('pre'); }).data('pre', $selectStatus.val());
Capy

2
은 "mySelect"요소를 모두 @Sinaesthetic이 라인 세트 하나 개의 값 $('mySelect').data('pre', $(this).val());이 같이되어야한다 : $('mySelect').each(function() { $(this).data('pre', $(this).val()); });나는 편집에 대한 답변을 충분히 평판이 없습니다 : /
압 데라

8

손으로 값을 추적하십시오.

var selects = jQuery("select.track_me");

selects.each(function (i, element) {
  var select = jQuery(element);
  var previousValue = select.val();
  select.bind("change", function () {
    var currentValue = select.val();

    // Use currentValue and previousValue
    // ...

    previousValue = currentValue;
  });
});

내가 다루어야 할 동일한 페이지에 여러 개의 선택 상자가 있기 때문에 위의 방법을 사용할 수 없습니다.
Alpesh

1
귀하의 질문에 여러 선택 버튼에 대해 언급하지 않았습니다. 여러 상자를 지원하도록 답변을 업데이트했습니다.
August Lilleaas

1
가장 좋은 답변입니다. 나는 그 다음 브라우저 호환성 raither에 대한 JQuery와에 의존하는 두 가지 방법의 올바른 흐름 EF 실행 원인이 솔루션 ') usign 초점 ()과 변화 (보다 더 좋은 생각
coorasse

@ coorasse : 올바른 실행 흐름은 결코 다를 수 없습니다. 요소가 포커스를 갖기 전에 사용자가 선택 상자 값을 변경할 수 없었습니다 . 즉,이 접근 방식에는 아무런 문제가 없습니다 :-)
Andy E

'클로저'사용 관점에서 이것이 '초점'솔루션보다 나은지 확실하지 않습니다.
James Poulose 2013

8
 $("#dropdownId").on('focus', function () {
    var ddl = $(this);
    ddl.data('previous', ddl.val());
}).on('change', function () {
    var ddl = $(this);
    var previous = ddl.data('previous');
    ddl.data('previous', ddl.val());
});

이것은 나를 위해 일에만 약간의 보정은 dropdownId에 선택의에 하나가 아닌, 감사
malkoty

2
사용자 상호 작용없이 변경 이벤트가 발생할 수 있으므로 이는 생각이 아닙니다
qdev

3

이벤트 "live"를 사용하고 있는데 솔루션은 기본적으로 Dimitiar와 유사하지만 "focus"를 사용하는 대신 "click"이 트리거 될 때 이전 값이 저장됩니다.

var previous = "initial prev value";
$("select").live('click', function () {
        //update previous value
        previous = $(this).val();
    }).change(function() {
        alert(previous); //I have previous value 
    });

2
나는 이것을 사용하지 않을 것입니다. 사용자가 select 요소를 '탭'하고 키보드 화살표를 사용하여 다른 옵션을 선택하면 어떻게됩니까?
크리스티안 런달

@Perplexor 예, 키로는 작동하지 않습니다. 그렇지 않으면 키를 누를 때마다 각 값이 저장됩니다. 이것은 사용자가 드롭 다운 메뉴를 클릭한다고 가정합니다. 문제는 '실시간'이벤트가 '포커스'와 함께 작동하지 않는다는 것입니다. 더 나은 해결책을 모르겠습니다.
시카 구 스티 아니

현재 값을 포커스에 별도의 변수에 저장할 수 있습니다. 이것은 단지 내 머리 꼭대기에서 온 것이므로 이것이 이상적인지 확실하지 않습니다.
크리스티안 런달

'focus'가 'live'이벤트와 함께 작동 할 수 있으면 완벽합니다. 그러나 동적으로 드롭 다운 메뉴를 만들면 '실시간'만 사용할 수 있습니다. 이것이 바로 제가 아는 것입니다. '라이브'에 '초점'불행하게도, 새 값을 저장하기 위해 이벤트를 트리거하지 않습니다,하지만 난 새로운 jQuery로 모르는
CICA Gustiani에게

jQuery의 새 버전에서는 라이브가 죽었습니다! [ stackoverflow.com/questions/14354040/…
remo

2

드롭 다운 '변경시'액션 함수를 작성하기 전에 현재 선택된 드롭 다운 값을 선택한 jquery로 전역 변수에 유지하십시오. 함수에서 이전 값을 설정하려면 전역 변수를 사용할 수 있습니다.

//global variable
var previousValue=$("#dropDownList").val();
$("#dropDownList").change(function () {
BootstrapDialog.confirm(' Are you sure you want to continue?',
  function (result) {
  if (result) {
     return true;
  } else {
      $("#dropDownList").val(previousValue).trigger('chosen:updated');  
     return false;
         }
  });
});

1

각도 감시 유형 인터페이스와 함께 사용자 정의 jQuery 이벤트를 사용하는 것은 어떻습니까?

// adds a custom jQuery event which gives the previous and current values of an input on change
(function ($) {
    // new event type tl_change
    jQuery.event.special.tl_change = {
        add: function (handleObj) {
            // use mousedown and touchstart so that if you stay focused on the
            // element and keep changing it, it continues to update the prev val
            $(this)
                .on('mousedown.tl_change touchstart.tl_change', handleObj.selector, focusHandler)
                .on('change.tl_change', handleObj.selector, function (e) {
                // use an anonymous funciton here so we have access to the
                // original handle object to call the handler with our args
                var $el = $(this);
                // call our handle function, passing in the event, the previous and current vals
                // override the change event name to our name
                e.type = "tl_change";
                handleObj.handler.apply($el, [e, $el.data('tl-previous-val'), $el.val()]);
            });
        },
        remove: function (handleObj) {
            $(this)
                .off('mousedown.tl_change touchstart.tl_change', handleObj.selector, focusHandler)
                .off('change.tl_change', handleObj.selector)
                .removeData('tl-previous-val');
        }
    };

    // on focus lets set the previous value of the element to a data attr
    function focusHandler(e) {
        var $el = $(this);
        $el.data('tl-previous-val', $el.val());
    }
})(jQuery);

// usage
$('.some-element').on('tl_change', '.delegate-maybe', function (e, prev, current) {
    console.log(e);         // regular event object
    console.log(prev);      // previous value of input (before change)
    console.log(current);   // current value of input (after change)
    console.log(this);      // element
});

1

나는 이것이 오래된 실이라는 것을 알고 있지만 조금 더 추가 할 수 있다고 생각했습니다. 제 경우에는 텍스트, val 및 기타 데이터 속성을 전달하고 싶었습니다. 이 경우 전체 옵션을 val이 아닌 prev 값으로 저장하는 것이 좋습니다.

아래 예제 코드 :

var $sel = $('your select');
$sel.data("prevSel", $sel.clone());
$sel.on('change', function () {
    //grab previous select
    var prevSel = $(this).data("prevSel");

    //do what you want with the previous select
    var prevVal = prevSel.val();
    var prevText = prevSel.text();
    alert("option value - " + prevVal + " option text - " + prevText)

    //reset prev val        
    $(this).data("prevSel", $(this).clone());
});

편집하다:

요소에 .clone ()을 추가하는 것을 잊었습니다. 값을 되 찾을 때 이전 선택이 아닌 선택의 새 사본을 가져옵니다. clone () 메소드를 사용하면 인스턴스 대신 선택 사본을 저장합니다.


0

음, 현재 선택된 값을 저장하지 않는 이유는 무엇입니까? 선택한 항목이 변경되면 이전 값이 저장됩니까? (원하는대로 다시 업데이트 할 수 있습니다)


내 경우에는 동일한 페이지에 여러 개의 선택 상자가 있기 때문에 그렇게 할 수 없습니다. 그리고 처음에 모든 초기 가치를 저장하는 것은 너무 번거로울 것입니다.
Alpesh

0

다음 코드를 사용하여 테스트했으며 작동합니다.

var prev_val;
$('.dropdown').focus(function() {
    prev_val = $(this).val();
}).change(function(){
            $(this).unbind('focus');
            var conf = confirm('Are you sure want to change status ?');

            if(conf == true){
                //your code
            }
            else{
                $(this).val(prev_val);
                $(this).bind('focus');
                return false;
            }
});

0
(function() {

    var value = $('[name=request_status]').change(function() {
        if (confirm('You are about to update the status of this request, please confirm')) {
            $(this).closest('form').submit(); // submit the form
        }else {
            $(this).val(value); // set the value back
        }
    }).val();
})();

0

이 문제를 해결하기 위해 다른 옵션을 제공하고 싶습니다. 위에서 제안한 솔루션이 내 시나리오를 해결하지 못했기 때문에.

(function()
    {
      // Initialize the previous-attribute
      var selects = $('select');
      selects.data('previous', selects.val());

      // Listen on the body for changes to selects
      $('body').on('change', 'select',
        function()
        {
          $(this).data('previous', $(this).val());
        }
      );
    }
)();

이것은 jQuery를 사용하여 def를 사용합니다. 여기에 의존하지만 순수한 자바 스크립트에서 작동하도록 조정할 수 있습니다. (본인에 리스너를 추가하고 원래 대상이 선택, 실행 기능인지 확인하십시오.)

바디에 변경 리스너를 연결하면 선택에 대한 특정 리스너 이후에 이것이 발생하는지 확인할 수 있습니다 . 그렇지 않으면 데이터를 읽기 전에 '데이터 이전'값을 덮어 씁니다.

이것은 물론 이전 값과 체크 값에 별도의 리스너를 사용하는 것을 선호한다고 가정합니다. 단일 책임 패턴과 잘 맞습니다.

참고 : 이렇게하면이 '이전'기능이 모든 선택에 추가되므로 필요한 경우 선택기를 미세 조정해야합니다.


0

이것은 @thisisboris 답변의 개선입니다. 데이터에 현재 값을 추가하므로 코드는 현재 값으로 설정된 변수가 변경되는시기를 제어 할 수 있습니다.

(function()
{
    // Initialize the previous-attribute
    var selects = $( 'select' );
    $.each( selects, function( index, myValue ) {
        $( myValue ).data( 'mgc-previous', myValue.value );
        $( myValue ).data( 'mgc-current', myValue.value );  
    });

    // Listen on the body for changes to selects
    $('body').on('change', 'select',
        function()
        {
            alert('I am a body alert');
            $(this).data('mgc-previous', $(this).data( 'mgc-current' ) );
            $(this).data('mgc-current', $(this).val() );
        }
    );
})();

0

최고의 솔루션 :

$('select').on('selectric-before-change', function (event, element, selectric) {
    var current = element.state.currValue; // index of current value before select a new one
    var selected = element.state.selectedIdx; // index of value that will be selected

    // choose what you need
    console.log(element.items[current].value);
    console.log(element.items[current].text);
    console.log(element.items[current].slug);
});

1
이 답변은 "일반"jQuery 또는 자바 스크립트가 아닌 "Selectric"js 라이브러리를 기반으로합니다. Eventhough가 최고이며, 원래 질문에 맞지 않거나 사용자가 작동하기 위해 다른 것을 설치해야한다고 말하지도 않습니다
gadget00

0

원하는 결과를 얻는 몇 가지 방법이 있습니다. 이것은 겸손한 방법입니다.

요소가 이전 값을 보유하게하려면 속성 'previousValue'를 추가하십시오.

<select id="mySelect" previousValue=""></select>

초기화되면 'previousValue'를 속성으로 사용할 수 있습니다. JS에서이 선택의 이전 값에 액세스하려면 다음을 선택하십시오.

$("#mySelect").change(function() {console.log($(this).attr('previousValue'));.....; $(this).attr('previousValue', this.value);}

'previousValue'를 사용한 후 속성을 현재 값으로 업데이트하십시오.


0

선택에 따라 다른 div를 공개해야했습니다.

이것이 jquery 및 es6 구문으로 수행하는 방법입니다

HTML

<select class="reveal">
    <option disabled selected value>Select option</option>
    <option value="value1" data-target="#target-1" >Option 1</option>
    <option value="value2" data-target="#target-2" >Option 2</option>
</select>
<div id="target-1" style="display: none">
    option 1
</div>
<div id="target-2" style="display: none">
    option 2
</div>

JS

$('select.reveal').each((i, element)=>{
    //create reference variable 
    let $option = $('option:selected', element)
    $(element).on('change', event => {
        //get the current select element
        let selector = event.currentTarget
        //hide previously selected target
        if(typeof $option.data('target') !== 'undefined'){
            $($option.data('target')).hide()
        }
        //set new target id
        $option = $('option:selected', selector)
        //show new target
        if(typeof $option.data('target') !== 'undefined'){
            $($option.data('target')).show()
        }
    })
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.