L.F
L.F

Reputation: 33

How to change the text of an option item on onclick

I've been trying to setup a dropdown list for phone number extensions that would display the extension (just +xxx, e.g. +44), while the dropdown list would contain a more descriptive piece of text, like "United Kingdom (+44)" instead.

I managed to make some headway, but I'm having trouble making the text revert when the dropdown is re-opened with an item selected. And the dropdown will show the correct value, but the list of options will still show the number instead (However, it works fine in firefox, but not chrome/IE at the least)

I would appreciate any help on what can be done to achieve it, preferably while still using the 'standard' input control.

Current Code/jsFiddle:

var toggled = 1;
$(function(){
  $("#ddMobileExtension option").each(function () {
    // Set data item for all options
    $(this).data("data-txt", $(this).text());
  });
  $("#ddMobileExtension").change(function () {
    $("option", this).each(function () {
      // Reset all options to their corresponding data items
      $(this).text($(this).data("data-txt"));
    });
    // Set the selected option to be +XX
    // (Provided it's not the first item)
    $(this).find("option:selected").text(
      $(this).find("option:selected").attr("value") != "-1" ? "+" + $(this).find("option:selected").attr("value") : ""
    );
  });

  $("#ddMobileExtension").on("click", function(e){
    if(toggled == 1){
      // On dropdown being opened, set the option text back
      // to the more readable form
      $(e.target).find("option:selected").text($(e.target).find("option:selected").data("data-txt"));
      toggled = 0;
    } else {
      // On dropdown being closed, set the option text back
      // to the +XX format
      $(this).find("option:selected").attr("value") != "-1" ? $(e.target).find("option:selected").text("+" + $(this).find("option:selected").attr("value")) : "";
      toggled = 1;
    }
  }).blur(function(){
    // Catch for tabbing out and back in mid-selection
    toggled = 1;
  });
});


<select ID="ddMobileExtension" style="width:61px">
  <option Value="-1" Text="" />
  <option Value="44">United Kingdom (+44)</option>
  <option Value="1">United States (+1)</option>
  <option Value="1784">Saint Vincent and the Grenadines (+1784)</option>
  <option Value="976">Mongolia (+976)</option>
</select>

jsFiddle

Upvotes: 3

Views: 899

Answers (2)

Twisty
Twisty

Reputation: 30893

Here is what I would do, make use of jQuery UI Autocomplete:

https://jsfiddle.net/Twisty/3nxu01vg/4/

HTML

<input ID="ddMobileExtension" style="width:61px" />

JavaScript

var extensions = [{
  label: "United Kingdom (+44)",
  value: 44
}, {
  label: "United States (+1)",
  value: 1
}, {
  label: "Saint Vincent and the Grenadines (+1784)",
  value: 1784
}, {
  label: "Mongolia (+976)",
  value: 976
}];

$(function() {
  $("#ddMobileExtension").autocomplete({
    source: extensions,
    minLength: 0
  }).click(function() {
    $(this).trigger("keydown");
  });
});

This works the way you're describing.

If you do not want to do this, you can do as you propose, by changing the text of option once selected.

https://jsfiddle.net/Twisty/3nxu01vg/9/

HTML

<select ID="ddMobileExtension" style="width:61px">
  <option value="-1"></option>
  <option value="44" data-orig-text="United Kingdom (+44)">United Kingdom (+44)</option>
  <option value="1" data-orig-text="United States (+1)">United States (+1)</option>
  <option value="1784" data-orig-text="Saint Vincent and the Grenadines (+1784)">Saint Vincent and the Grenadines (+1784)</option>
  <option value="976" data-orig-text="Mongolia (+976)">Mongolia (+976)</option>
</select>

JavaScript

$(function() {
  $("#ddMobileExtension").focus(function(e) {
    var $items = $(this).find("option");
    $items.each(function(ind, elem) {
      if (ind !== 0) {
        $(elem).html($(elem).data("orig-text"));
      }
    });
  }).change(function(e) {
    var $item = $(this).find(":selected");
    if ($item.index() !== 0) {
      $item.html($item.val());
    }
    $(this).trigger("blur")
  });
});

Hope that helps.

Update for IE 8 -> 11

This code will not operate the same in Internet Explorer. This will operate in Edge.

See More: https://github.com/jquery/jquery/issues/2511

Unfortunately, all versions of IE (even IE 11) fire blur & focus events asynchronously and there is no easy way to work around it generically enough to include the workaround in jQuery.

Good news is it's fixed in the new Microsoft Edge browser but IE 11 will stay as it is forever.

Upvotes: 1

Mathankumar K
Mathankumar K

Reputation: 631

It can be achieve just add and remove label attribute in selected option element. we should use mousedown event to avoid this trouble making the text revert when the dropdown is re-opened with an item selected. It is actually take a time to update in options when use click event. check this things in DevTools when clicking select box. it works fine in firefox, chrome and IE.

Final fixed code: jsFiddle

$(function() {
  $("#ddMobileExtension").change(function() {
    var label = $(this).find("option:selected")[0].label;
    $($(this).find("option:selected")[0]).attr("label", label.substring(label.indexOf("(") + 1, label.indexOf(")")));
  });
  $("#ddMobileExtension").mousedown(function(e) {
    var rem = document.querySelector('option[label]')
    if (rem) {
      rem.removeAttribute("label")
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select ID="ddMobileExtension" style="width:61px">
  <option Value="-1" Text="" />
  <option Value="44">United Kingdom (+44)</option>
  <option Value="1">United States (+1)</option>
  <option Value="1784">Saint Vincent and the Grenadines (+1784)</option>
  <option Value="976">Mongolia (+976)</option>
</select>

Upvotes: 1

Related Questions