Reputation: 1162
I have a select box that dynamically shows a list of shipping options and prices. I want them to be in order from lowest to highest price.
Here's example html.
<select name="ShippingMethod">
<option value="ups:1">UPS Next Day Air ($30.08)</option>
<option value="ups:4">UPS 2nd Day Air ($14.77)</option>
<option value="ups:6">UPS 3 Day Select ($10.93)</option>
<option value="ups:7">UPS Ground ($8.00)</option>
<option value="flatzonc:Pick up in store">Pick up in store ($0.00)</option>
<option value="mvusps:PRIORITY">U.S.P.S. Priority Mail® ($7.45)</option>
</select>
I know how to put the values into an array with this:
shippingOptions = [];
$('select[name=ShippingMethod] option').each(function() {
myList.push($(this).html())
});
but thats as far as I got. I don't know how to use that to sort them and reinsert them in order. I'm new to javascript so I appriciate the help.
Thanks
Upvotes: 3
Views: 7236
Reputation: 1174
Meh, already answered but I had this written up so I'll post anyway, It's pretty much a mix of all the rest of these, lol.. Fancy that
$('select[name=ShippingMethod]').
html($('select[name=ShippingMethod] option').
clone().sort(function (a, b) {
a = a.innerHTML, b = b.innerHTML;
return parseFloat(
a.substr(a.indexOf('$') + 1)
) >= parseFloat(
b.substr(b.indexOf('$') + 1)
);
})
);
Edit: After reviewing the comments, this is a more efficient but more verbose answer:
var selectOpts = $('select[name="ShippingMethod"] option');
var len = selectOpts.length;
var options = new Array(len), out = "", i;
selectOpts.each(function (index) {
var self = $(this);
var txt = self.text();
options.push({
'html': '<option value="' + self.val() + '">' + txt + '</option>',
'price': parseFloat(txt.substr(txt.indexOf('$') + 1))
});
// Return if not last item
if (index !== len - 1) {
return;
}
// Sort options and set 'out'
options.sort(function (a, b) {
return a.price > b.price;
});
for (i = 0; i < len; i += 1) {
out += options[i].html;
};
}).parent('select').html(out);
Upvotes: 2
Reputation: 61036
// get all options
var shippingOptions = $('select[name=ShippingMethod] option');
// initialize sort
shippingOptions.sort(function(a,b) {
// define regex that pulls contents of parens
var patt = /\((.*)\)/;
// for each element in sort, find the price and remove the dollar sign
a.price = a.text.match(patt)[1].replace('\$', '');
b.price = b.text.match(patt)[1].replace('\$', '');
return a.price - b.price;
});
// update the select with the new option order
$('select[name=ShippingMethod]').append(shippingOptions);
// select the first option
$(shippingOptions[0]).attr("selected", "");
Upvotes: 3
Reputation: 7466
First you need to extract the $ amount of each option, then sort those and replace the existing dropdown, here is the complete code:
http://jsfiddle.net/amyamy86/L8qgX/
// Get the price in the option
var getPrice = function (str) {
var price = 0;
var result = str.match(/[0-9]+(.)[0-9]{2}/); //regex matches >1 digit followed by . decimal, followed by 2 digits
if (result.length > 0) {
price = parseFloat(result[0]);
}
return price;
};
// Sort the prices
var sortPrices = function (priceList) {
priceList.sort(function (a, b) {
return a.price > b.price; // > is sort ascending order
});
return priceList;
};
var prices = [];
// Get the option's label, value, price
$('select[name=ShippingMethod] option').each(function () {
var option = $(this);
var price = getPrice(option.text());
prices.push({
label: option.html(),
value: option.val(),
price: price
});
});
var shippingOptions = sortPrices(prices);
// create output HTML
var output = '';
for (var i = 0; i < shippingOptions.length; i++) {
output += '<option value="' + shippingOptions[i].value + '">' + shippingOptions[i].label + '</option>';
}
// replace <select> with sorted options
$('select[name="ShippingMethod"]').html(output);
You can learn more about using:
match()
with regular expressions: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions sort()
: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sortUpvotes: 3
Reputation: 9370
Try this.. Here Sorting is done on value.. You can use .text
to sort based on text
$("select").html($("select option").sort(function (a, b) {
return a.text == b.text ? 0 : a.value < b.value ? -1 : 1 ;
}));
Sort on text: Demo 2
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1 ;
Sort on values indside braces in text : Demo 3
$("select").html($("select option").sort(function (a, b) {
var a1 = parseFloat(a.text.match(/\(.*?([\d.]+).*?\)/)[1].replace("$",""));
var b1 = parseFloat(b.text.match(/\(.*?([\d.]+).*?\)/)[1].replace("$",""));
return a.text == b.text ? 0 : a1 < b1 ? -1 : 1
}));
Upvotes: 1