Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show a different text for the selected option for `<select>`s

I want the text that's displayed in the <select> to be different from the selected <option>'s text. I have limited width to work with, so if I display all the text in the <option>, then some text with be cut off.

For example, if my markup is this:

<select>
  <option>Open (some description)</option>
  <option>Closed (a bunch of text</option>
</select>

When the first option is selected, I want to show only the word "Open" to save space. I can't just use Javascript to replace the text because if the user opens the select, then they'll see the shortened text.

Is there a way to do this using the <select> tag (i.e. without using a custom selector)?

like image 265
Leo Jiang Avatar asked Oct 16 '15 22:10

Leo Jiang


2 Answers

Using JS, you can add a focus and blur event listeners which modify the text of the options:

function focus() {
  [].forEach.call(this.options, function(o) {
    o.textContent = o.getAttribute('value') + ' (' + o.getAttribute('data-descr') + ')';
  });
}
function blur() {
  [].forEach.call(this.options, function(o) {
    console.log(o);
    o.textContent = o.getAttribute('value');
  });
}
[].forEach.call(document.querySelectorAll('.shortened-select'), function(s) {
  s.addEventListener('focus', focus);
  s.addEventListener('blur', blur);
  blur.call(s);
});
<select class="shortened-select">
  <option value="Open" data-descr="some description"></option>
  <option value="Closed" data-descr="a bunch of text"></option>
</select>
like image 177
Oriol Avatar answered Sep 28 '22 08:09

Oriol


You could create a second select element, which has abbreviated options. Show it by default and hide the select element with un-abbreviated options.

When the abbreviated select is hovered, show the other select element.

When you change an option, set the abbreviated select element's selectedIndex to match, which will keep both elements in sync:

document.getElementById('s2').addEventListener('input', function() {
  document.getElementById('s1').selectedIndex= this.selectedIndex;
});
#s1 {
  position: absolute;
}

#s2 {
  display: none;
}

#s2:hover, #s1:hover + select {
  position: relative;
  display: inline;
}
<select id="s1">
  <option>Open</option>
  <option>Closed</option>
</select>

<select id="s2">
  <option>Open (some description)</option>
  <option>Closed (a bunch of text</option>
</select>
like image 20
Rick Hitchcock Avatar answered Sep 28 '22 10:09

Rick Hitchcock