asprin
asprin

Reputation: 9833

Finding Closest Matching Value using jQuery or javascript

Consider a markup such as

<select id="blah">
  <option value="3">Some text</option>
  <option value="4">Some text</option>
  <option value="8">Some text</option> // <---- target this tag based on value 7
  <option value="19">Some text</option>
</select>

Suppose I have a value with me, say 7. Is it possible to target the option tag whose value attribute is closest to 7 which, in this case, would be <option value="8">?

I'm aware of ^ which means starting with and $ which means ending with and was hoping if there is something like this to find the closest match for a given value.

Upvotes: 8

Views: 1295

Answers (6)

alexb
alexb

Reputation: 971

If you can use jquery I would do something like

$(function () {
        // comes from somewhere
        var val = 7;

        var sortByDifference = $("#blah option").sort(function (opt1, opt2) {
            return Math.abs(parseInt($(opt1).val()) - val) - Math.abs(parseInt($(opt2).val()) - val);
        });

        alert($(sortByDifference[0]).val());
    });

In sortByDifference you have all values sorted by how close they are to your value. The routine returns the closest greater or lower and doesn't require the options to be sorted.

Upvotes: 1

Akhil Sekharan
Akhil Sekharan

Reputation: 12693

How about a recursion? It will find the closest value:

JS-BIN Demo

function getClosest(val, ddl, increment){
  if(ddl.find('option[value="'+val+'"]').length){
      return val;
  }
  else
    try{
      if(increment)
    return getClosest(++val, ddl, increment);
      else
        return getClosest(--val, ddl, increment);
    }
  catch(err){
    return -1;
  }
}

function findClosest(val, ddl){
   var larger = getClosest(val, ddl, true);
   var smaller = getClosest(val, ddl, false);
  if(larger == smaller == -1)
    return -1;
  else if (larger == -1)
    return smaller;
  else if (smaller == -1 )
    return larger;

  if(larger - val > val - smaller)
    return smaller;
  else
    return larger
}    

Upvotes: 3

karaxuna
karaxuna

Reputation: 26940

function findClosest(num){
    var select = document.getElementById('blah');
    var options = select.options;
    var dif = Infinity;
    var index;
    for(var i = 0; i < options.length; i++){
        var newdif = Math.abs(parseInt(options[i].value) - num);
        if(newdif < dif){
             dif = newdif;
             index = i;
        }
    }
    select.selectedIndex = index;
}

Upvotes: 1

A. Wolff
A. Wolff

Reputation: 74420

I'll go like this:

http://jsfiddle.net/GNNHy/

var $tmpOption = $('<option value="7">Some text 7</option>');
$("#blah").append($tmpOption);
var my_options = $("#blah option");
my_options.sort(function(a,b) {
    if (parseInt(a.value,10) > parseInt(b.value,10)) return 1;
    else if (parseInt(a.value,10) < parseInt(b.value,10)) return -1;
    else return 0
})

$("#blah").empty().append( my_options );

Upvotes: 4

John Dvorak
John Dvorak

Reputation: 27297

The easiest way is perhaps the good old linear search (you can do binary, but it's more tricky than usual):

var target;
var $options;

var best=Infinity;
var bestAt;

$options.each(function(){
  var error = this.value - target;
  error = error>0 ? error : -error;
  if(error<=best){
    best=error;
    bestAt=this;
  }
})

//return $(bestAt);

Upvotes: 1

Rajiv007
Rajiv007

Reputation: 1136

Yes just substract your value (7) with the option values(use each function)...the value with the minimum positive outcome will be your targeted option. I hope you will have the desired result.

Upvotes: 1

Related Questions