0

I'm using jQuery's .val() function to read the value of a <select> tag. It seems that, at least in Firefox, .val() returns the value of the option the user is currently hovering over. You can see this behaviour at this jsfiddle.

Is there any way using jQuery or pure javascript to get the value that is shown in the select box, i.e. the last value that actually fired a change event?

Original Idea

function foo() {
    var value = $('#select').val();
    // do something that depends on value
}

The problem with this is that I only want foo() to use the value that is currently selected. By selected I mean the option that was clicked. In the fiddle, you can see that this value changes as you hover over options.

Alternative

var value;

$('#select').change(function() {
    value = $('#select').val();
}

function foo() {
    // do something with value
}

This is OK, but the information appears to exist in the DOM, since the last clicked value is displayed in the select box.

So, my question is, is it possible to get the last clicked option from the DOM?

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
user545424
  • 14,409
  • 10
  • 49
  • 66
  • Is this what you are talking about? $('#bar').change(function (){ $('#foo').text($('#bar').val()); }).trigger("change"); – Sunand Sep 03 '14 at 20:52
  • Your question is not clear. –  Sep 03 '14 at 21:05
  • What is not clear about it? – user545424 Sep 03 '14 at 21:09
  • Possible duplicate: http://stackoverflow.com/questions/4076770/getting-value-of-select-dropdown-before-change – mccannf Sep 03 '14 at 21:20
  • In your Fiddle, the value doesn't change when you hover over an option, it changes once you select one. You are already capturing the last value that fired a change event (after 100ms of that event firing anyway). Like in Sunand's suggestion, though, it would be more efficient to add a handler for the change event, instead of firing your own event 10 times a second. – Mark Sep 03 '14 at 21:21
  • @mark.hch. In my browser it does change when you hover over an option. Maybe it is browser dependent? I am using Firefox 24.7.0. – user545424 Sep 03 '14 at 21:47
  • does this alert for you when you hover? `$('select').change(function() {alert();});` are you sure you're not confusing highlight with a selection being made? – im_brian_d Sep 03 '14 at 22:08
  • @Brian, no that does not alert. I understand that the change event is only fired after a selection is made, but the **value** returned by `val()` **does** change when highlighting an option. – user545424 Sep 03 '14 at 22:10
  • How do you know that if the change event isn't firing? – im_brian_d Sep 03 '14 at 22:11
  • Check out the fiddle. In my real code, the function `foo` is being run periodically and depends on the value of the select tag. – user545424 Sep 03 '14 at 22:12
  • Ah I see it now, my apologies. You won't have to worry about that if you retrieve the value after the change event has taken place and not at an interval. – im_brian_d Sep 03 '14 at 22:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60579/discussion-between-user545424-and-brian). – user545424 Sep 03 '14 at 22:17
  • I added an answer of using focus below, helpful? – im_brian_d Sep 04 '14 at 21:34

2 Answers2

0

You can do this on the change event instead of by interval

UPDATED CODE based on comments below

$('#bar').on('change', function(){
  var $t =$(this) , value=$t.val();
  $t.attr('data-answer', value);
});

setInterval(function(){
 $('#foo').text($('#bar').attr('data-answer'));
},1000);

your select would have this attribute on it

<select id="bar" data-answer="" >
 //options here
</select>

Or using .data method:

$('#bar').on('change', function(){
  var $t =$(this) , value=$t.val();
  $t.data('answer', value);
});

setInterval(function(){
 $('#foo').text($('#bar').data('answer'));
},1000);
Gary Storey
  • 1,771
  • 2
  • 12
  • 19
  • You can not get the value that is hovered over by the mouse as no event has occurred at that point. – Gary Storey Sep 03 '14 at 21:24
  • This works, but since other functions depend on the value, I'd prefer not to store the state in two places. See my updated question. I'm interested in whether it is possible to get this value directly from the DOM, or whether I need to store the state myself. – user545424 Sep 03 '14 at 21:45
  • Add a `data` attribute onto your select to hold the previously selected item. i will update answer. – Gary Storey Sep 03 '14 at 21:48
  • That would be helpful, but I'm more interested in whether it is possible to get this information from the DOM without adding anything. It seems to know what the last clicked value was, because it appears in the select box. Is that data accessible? I would be happy with knowing that it's not possible, and then I have to store it myself. – user545424 Sep 03 '14 at 21:52
  • I'm not sure I understand `$('#bar').val();` is getting the value from the DOM. You can use the `data` method from jQuery instead of the `.attr` method. jQuery stores its own copy of the data elements there and they can be read back at any time whether they exist in the markup or not. You would use it like `.data('answer')` instead of `.attr('data-answer');` – Gary Storey Sep 03 '14 at 21:57
  • I just mean that when you click the select box, the last clicked option still appears in the box. So that information is stored **somewhere**. Is it available in the DOM? Is there any way to access that? Or once you hover over an option that becomes the currently selected option and there is no way to get the last value that was clicked absent you storing it in a variable yourself? – user545424 Sep 03 '14 at 22:01
  • FYI: you can not get the previous value from the change event because the value has changed when the event fires. That's why you store the previous value in a data attribute so that you can get it even after the event has fired. – Gary Storey Sep 03 '14 at 22:05
  • @Brian, that's not true in my browser. Maybe it is an issue with Firefox, but in the fiddle I posted, the `.val()` returns different values when you hover over the options. – user545424 Sep 03 '14 at 22:08
  • Here is a fiddle that displays the previous value as well as the current value. http://jsfiddle.net/x4arsg92/4/ – Gary Storey Sep 03 '14 at 22:18
  • And here is it update to use `data` instead of `attr`. http://jsfiddle.net/x4arsg92/5/ – Gary Storey Sep 03 '14 at 22:20
0

Sounds like you're looking for focus()

$("select").focus(function () {

    var focusValue = this.value;

    $('#foo').text(focusValue);

})

You can chain the event listener focus with change to find the current value and then the selected.

$("select").focus(function () {

    var focusValue = this.value;

    $('#foo').text(focusValue);

}).change(function() {

    var changeValue = this.value  

    $('#foo').text(changeValue);

});

Here is a jsFiddle Demo

im_brian_d
  • 7,772
  • 2
  • 26
  • 43