4

I want to get custom attribute value from multiple select, here is my html,code

<select multiple name="tax[]" id="tax_classes" onChange="getSelectedOptions(this)">  
   <option value="2" data-percentage="9.00">CGST(9.00%)</option>  
   <option value="1" data-percentage="18.00">GST(18.00%)</option> 
   <option value="3" data-percentage="9.00">IGST(9.00%)</option> 
   <option value="4" data-percentage="12.00">Tax(12.00%)</option> 
</select>

From above tag, I wanted to get the data-percentage attribute value.

Here is the script what i tried so far

function getSelectedOptions(tax) 
{
  var options = [], option;
  var len = tax.options.length;
  for (var i = 0; i < len; i++) {
    option = tax.options[i]; 
    if (option.selected) { 
      options.push(option); 
      alert(option.value); 
    }
  }  
} 

I am getting output as 2,1,3,

But my expected output is 9.00, 18.00, 9.00 .

Lets-c-codeigniter
  • 682
  • 2
  • 5
  • 18

2 Answers2

4

The easiest way to build an array of the data attributes of the selected option elements is to use map().

Also note that inline event handlers are not considered best practice; you should use unobtrusive event handlers instead. As you've already included jQuery in the page, here's an example of how to do that:

$('#tax_classes').on('change', function() {
  var options = $(this).find('option:selected').map(function() {
    return $(this).data('percentage');
  }).get();
  console.log(options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple name="tax[]" id="tax_classes">
  <option value="2" data-percentage="9.00">CGST(9.00%)</option>
  <option value="1" data-percentage="18.00">GST(18.00%)</option>
  <option value="3" data-percentage="9.00">IGST(9.00%)</option>
  <option value="4" data-percentage="12.00">Tax(12.00%)</option>
</select>

If you want to stick with plain JS, here's how to do that:

document.querySelector('#tax_classes').addEventListener('change', function() {
  var options = Array.from(this.options).filter(o => o.selected).map(o => o.dataset.percentage);
  console.log(options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple name="tax[]" id="tax_classes">
  <option value="2" data-percentage="9.00">CGST(9.00%)</option>
  <option value="1" data-percentage="18.00">GST(18.00%)</option>
  <option value="3" data-percentage="9.00">IGST(9.00%)</option>
  <option value="4" data-percentage="12.00">Tax(12.00%)</option>
</select>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
3

You say that you want to get the attribute value, but you are logging .value instead, which refers to the value attribute. You need to use getAttribute('data-percentage') instead.

function getSelectedOptions() {
  var options = [],
    option;
  var tax = document.getElementById('tax_classes');
  var len = tax.options.length;
  console.clear();
  for (var i = 0; i < len; i++) {
    option = tax.options[i];
    if (option.selected) {
      options.push(option);
      console.log(option.getAttribute('data-percentage'));
    }
  }
}
 
window.addEventListener('DOMContentLoaded', getSelectedOptions);
<select multiple name="tax[]" id="tax_classes" onChange="getSelectedOptions()">
  <option value="2" data-percentage="9.00">CGST(9.00%)</option>
  <option value="1" data-percentage="18.00" selected>GST(18.00%)</option>
  <option value="3" data-percentage="9.00">IGST(9.00%)</option>
  <option value="4" data-percentage="12.00" selected>Tax(12.00%)</option>
</select>
Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
  • Is it possible call above function on page load and onchange select tag ? If yes pls help me – Lets-c-codeigniter Oct 28 '19 at 11:18
  • 1
    `window.addEventListener('DOMContentLoaded', getSelectedOptions);` and `document.getElementById('tax_classes').addEventListener('change', getSelectedOptions);` - you'll need to do the element selection inside the handler then. I updated the code snippet and added `selected` attributes for demonstration purposes. – Constantin Groß Oct 28 '19 at 11:34