Sure. I haven’t tested the following code for completeness, but the main idea is there.
We can output information to the console as we go along, to help ensure that we are getting meaningful results.
I’ll also comment out old lines of code to help show how the code changes occur.
Get dataset info
First, we get the dataset information from each option. Here I’m assigning each option to a local variable, to help make the code easier to understand. I’ll also rename ov
to options
because when I look back at code after not using it for six months or more, I need all the help that I can get.
// var ov = SelectDropDown.options;
var options = SelectDropDown.options;
for(i=0; i<ov.length;i++){
// var option = ov[i];
var option = options[i];
var dataInfo = option.dataset;
console.log(dataInfo); // {one: "59"} {two: "245"} {three: "1569"}
}
That gives a useful start to things:
Use forEach instead of a for loop
JavaScript has supported an improved technique instead of for loops for a long time, and that is the forEach method.
The above function can instead be done in the following manner, for which that option variable helps to make the transition easier to achieve:
options.forEach(function (option) {
var dataInfo = option.dataset;
console.log(dataInfo); // {one: "59"} {two: "245"} {three: "1569"}
});
Make the prices easier to retrieve
What happens from here depends on how we want to use the information. An effective thing to do from here is to put each price into an array, where the first of the select’s options is the first in the price array.
We want to end up with the following array of price values: [59, 245, 1569]
We can achieve that by adding a prices array, and adding each dataset value to it.
But how do we get each price from the dataset?
It would help if the data name was identical for each option, so I’m going to assume that you make that easy improvement to the dataset names on your HTML options:
<select class="license_type" name="license_type" id="license_type">
<!--<option value="license_one" data-one="59">Single Site License</option>-->
<option value="license_one" data-price="59">Single Site License</option>
<!--<option value="license_two" data-two="245">5 Site License</option>-->
<option value="license_two" data-price="245">5 Site License</option>
<!--<option value="license_three" data-three="1569">Developers License</option>-->
<option value="license_three" data-price="1569">Developers License</option>
</select>
Get the prices
With that, we can now easily add the prices to the array:
var prices = [];
options.forEach(function (option) {
var dataInfo = option.dataset;
prices.push(dataInfo.price);
});
console.log(prices); // ["59", "245", "1569"]
But that’s not yet done, because the array contains strings of the prices instead of number values.
We could make the forEach method more complex by updating the push line, but easier to understand results are obtained by using the map method on the array instead.
var prices = [];
options.forEach(function (option) {
var dataInfo = option.dataset;
prices.push(dataInfo.price);
});
prices = prices.map(function (strPrice) {
return Number(strPrice);
});
console.log(prices); // ["59", "245", "1569"]
Which gives us the following array: [59, 245, 1569]
Now that we’re getting the information that we need, we can work on improving the code.
Simplify code with filter, map, reduce
There’s a nice way to simply your code, for which many articles have been written including simply your code with filter, map, and reduce, where you filter information through several pipes until you end up with what you require.
For this example there’s nothing to filter. Map can be used to get the price from the data value, and I don’t think that reduce will even be needed either.
<Heavy sigh>: while editing I carried on to make lots of beneficial improvements to the code, before realizing that I can really simply things with the filter/map/reduce idea. This means of course deleting all that I had done rewriting things all over again. The quest for simplicity is not without its casualties.
Use map to get the prices
Instead of assigning an array to prices and using forEach to update it, we can instead use the map method to get the price. I’ll give names to the functions as well so it’s easier to understand what they do.
// var prices = [];
// options.forEach(function (option) {
var prices = options.map(function getPrice(option) {
var dataInfo = option.dataset;
// prices.push(dataInfo.price);
return dataInfo.price;
});
prices = prices.map(function toNumber(strPrice) {
return Number(strPrice);
});
console.log(prices); // [59, 245, 1569]
Bring common things together
We can now easily extract those functions, making it easier to understand how they’re used.
function getPrice(option) {
var dataInfo = option.dataset;
return dataInfo.price;
}
function toNumber(strPrice) {
return Number(strPrice);
}
var prices = options.map(getPrice);
prices = prices.map(toNumber);
console.log(prices); // [59, 245, 1569]
And we can remove that reassignment at the end, by chaining on the .map method:
function getPrice(option) {
var dataInfo = option.dataset;
return dataInfo.price;
}
function toNumber(strPrice) {
return Number(strPrice);
}
// var prices = options.map(getPrice);
// prices = prices.map(toNumber);
var prices = options.map(getPrice).map(toNumber);
console.log(prices); // [59, 245, 1569]
Arrow functions
If we make that getPrice function a simple one-liner, we can simplify those functions even further.
function getPrice(option) {
// var dataInfo = option.dataset;
// return dataInfo.price;
return option.dataset.price;
}
function toNumber(strPrice) {
return Number(strPrice);
}
var prices = options.map(getPrice).map(toNumber);
console.log(prices); // [59, 245, 1569]
Now that they’re simple one-liners, we can easily turn them into arrow functions. I’ll also rename var to const when doing this, to help make it crystal clear that we’re using ES6 techniques here instead.
// function getPrice(option) {
// return option.dataset.price;
// }
const getPrice = (option) => option.dataset.price;
// function toNumber(strPrice) {
// return Number(strPrice);
// }
const toNumber = (strPrice) => Number(strPrice);
// var prices = options.map(getPrice).map(toNumber);
const prices = options.map(getPrice).map(toNumber);
console.log(prices); // [59, 245, 1569]
Conclusion
That’s about as simple as the code normally gets.
The following code is all you need to get the prices from the data attributes of the options, however reading through the above content gives you access to much more information about how code is easily modified to achieve a different range of benefits.
const getPrice = (option) => option.dataset.price;
const toNumber = (strPrice) => Number(strPrice);
const prices = options.map(getPrice).map(toNumber);
console.log(prices); // [59, 245, 1569]
Hopefully some useful and meaningful information was learned along the way as well.