変更前の選択(ドロップダウン)の値の取得


237

私が達成したいことはいつでも <select>ドロップダウンが変更さ変更前のドロップダウンの値が欲しいことです。私はjQueryの1.3.2バージョンを使用しており、変更イベントを使用していますが、変更後の値はそこにあります。

<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
:あなたは、このチェックアウトしたstackoverflow.com/questions/1983535/...
Rajat

回答:


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以降を使用していないため、focusおよびchangeイベントでlive()を使用することはできません。あなたができる唯一のことは、要素がページに挿入された後にバインドするようにスクリプトを調整することです。
Andy E

1
おかげで私はすでにライブとバインドしていて、それはうまくいきました。:)
Alpesh 2010年

4
変更ハンドラーの選択要素にもフォーカスする必要があることに注意してください。そうしないと、値の変更を繰り返した後にトリガーされません
Alex

52
私はこの解決策に同意しません。一度値を変更すると機能しますが、もう一度変更すると機能しません。どこかをクリックしてフォーカスを外し、もう一度ドロップダウンをクリックする必要があります。$( "#dropdownId")。on( 'change'、function(){var ddl = $(this); var previous = ddl.data( 'previous'); ddl.data( 'previous'、ddl .val());});
free4ride 14年

5
@ free4ride、$(this).blur();変更関数の最後に呼び出すだけであることを修正するには
chiliNUT

135

これにはグローバル変数を使用しないでください-前の値をデータに保存してください。ここに例を示します:http : //jsbin.com/uqupu3/2/edit

refのコード:

$(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、2010年

9
では、jQuery.dataを使用することに対するあなたの反対は何ですか?私の知る限り、jQueryライブラリは内部でも使用しており、使用することを推奨しています
Avi Pinto

jQuery Dataの使用に間違いなく同意します。グローバル変数を使用しようとしていたことを思い出させてくれてありがとう。グローバル変数に問題はありませんが、データを使用する方が簡潔です。しかし、フォーカスをチェーンしてから変更することも素晴らしいです:)
Piotr Kula

4
@ppumkin:グローバル変数の1つの間違いは間違いです:1つしかサポートしませ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
2番目の部分は正常に機能しますが、最初の部分はデータ属性を設定していません。何か案は?
Sinaesthetic 2013

1
@Sinaesthetic、私は同じ問題を抱えていました(そしてすでにこの回答に賛成しています)。$(this)が.data()メソッドを生き残るとは思いません。Avi Pintoの答えはその値のselect要素に戻り、これでうまくいきました(つまり、Aviも賛成しました)。
goodeye 2013

1
これは!== $( 'mySelect')なので機能しません。これは修正バージョンです。 var $selectStatus = $('.my-select'); $selectStatus.on('change', function () { var newStatus = $(this).val(); var oldStatus = $(this).data('pre'); }).data('pre', $selectStatus.val());
2014年

2
@Sinaestheticこの行は、すべての「mySelect」要素$('mySelect').data('pre', $(this).val());に1つの値を設定します。$('mySelect').each(function() { $(this).data('pre', $(this).val()); });次のようになります。答えを編集するのに十分な評判がありません:/
Abderrahim

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、2010年

1
ベストアンサー。このソリューションは、usign focus()およびchange()よりも優れていると思います。ブラウザの互換性を確保するためにjqueryに依存しているため、両方のメソッドの正しいフローefの実行が
原因です

@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にあるセレクタの上の代わりの1、感謝
malkoty

2
変更イベントはユーザーの操作なしで発生する可能性があるため、これは簡単ではありません
qdev

3

私はイベント「ライブ」を使用しています。私のソリューションは基本的にディミティアと似ていますが、「フォーカス」を使用する代わりに、「クリック」がトリガーされたときに以前の値が保存されます。

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

2
私はこれを使いません。ユーザーが選択要素に「タブ」で移動し、キーボードの矢印を使用して別のオプションを選択するとどうなりますか?
Christian Lundahl、2015

@Perplexorはい、キーでは機能しません。そうでない場合、キーを押すたびに各値が保存されます。これは、ユーザーがドロップダウンメニューをクリックすることを前提としています。問題は、「ライブ」イベントが「フォーカス」で機能しないことです。これ以上の解決策はわかりません。
シカグスティアーニ2015年

現在のフォーカスの値を別の変数に格納できます。これは頭​​のてっぺんからですので、これが理想的かどうかはわかりません。
クリスチャンランダール2015年

「フォーカス」が「ライブ」イベントで機能する場合、それは完璧です。しかし、これらのドロップダウンメニューを動的に作成する場合、使用できるのは「ライブ」のみです。残念ながら、「ライブ」に「フォーカス」してもイベントはトリガーされず、新しい値が保存されませんが、新しいjqueryでは知らない
Cica Gustiani

jQueryの新しいバージョンでライブは死んでいます![ stackoverflow.com/questions/14354040/...
レモ

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()メソッドを使用すると、selectのインスタンスではなく、selectのコピーが保存されます。


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になります。ここでの依存関係ですが、これは純粋なJavaScriptで動作するように適合させることができます。(ボディにリスナーを追加し、元のターゲットが選択、実行関数であるかどうかを確認します...)。

変更リスナーを本体に接続することで、selectの特定のリスナーの後にこれが起動することをほぼ確実にできます。そうしないと、「data-previous」の値が読み取られる前に上書きされます。

もちろん、これはset-previousとcheck-valueに別々のリスナーを使用することを好むことを前提としています。それは単一責任パターンとぴったり合います。

注:これにより、この「以前の」機能がすべての選択に追加されるため、必要に応じてセレクターを微調整してください。


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
この回答は「Selectric」jsライブラリに基づいており、「プレーン」なjQueryやJavaScriptには基づいていません。Eventhoughが最高です。元の質問には適合せず、ユーザーがそれを機能させるために何か他のものをインストールする必要があるとは言いません
gadget00

0

希望する結果を得るにはいくつかの方法があります。これは私の謙虚な方法です。

要素に以前の値を保持させるため、属性 'previousValue'を追加します。

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

初期化すると、 'previousValue'を属性として使用できるようになります。JSで、このselectのpreviousValueにアクセスするには:

$("#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.