Reputation: 9833
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
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
Reputation: 12693
How about a recursion? It will find the closest value:
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
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
Reputation: 74420
I'll go like this:
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
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
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