7

I'm trying to add some CSS ::before content to the <option> tags of a <select multiple> depending on if the option is selected or not.

The below is currently working fine in Chrome & FF, but I'm having issues in IE11.

select > option::before {
  display: inline-block;
  width: 10em;
}
select > option:checked::before {
  content: "SELECTED: ";
}
select > option:not(:checked)::before {
  content: "excluded: " ;
}
<select multiple>
  <option value="1" selected="selected">1</option>
  <option value="2" selected="selected">2</option>
  <option value="3" selected="selected">3</option>
  <option value="4" selected="selected">4</option>
  <option value="5" selected="selected">5</option>
</select>

I've read other SO posts (1, 2, 3, 4) about pseudo elements in IE and most seem to point to setting some sort of position or display attribute which I've tried.

Is this happening as <option> tags shouldn't contain child elements?

Vadim Ovchinnikov
  • 13,327
  • 5
  • 62
  • 90
Rob
  • 117
  • 11
  • Great Question. I'll bounty this in 48 hours. I'm trying to do the same thing in [this question](https://stackoverflow.com/a/48776016/1366033) I just answered It would appear though that this is not possible in IE as browsers have historically been a relatively opinionated on rendering `select` elements and their contents, but maybe there is some workaround – KyleMit Feb 13 '18 at 21:38
  • 2
    I don't think pseudo element inside of an option is valid https://stackoverflow.com/questions/19410679/using-before-with-option-element-in-a-drop-down-list – Huangism Feb 16 '18 at 17:53
  • We can't create what you desire in `IE` because it doesn't allow anything other than ` – Jithin Raj P R Feb 20 '18 at 07:41
  • Are you open to a JS solution? – Jonathan Chaplin Feb 20 '18 at 09:17
  • @Huangism I was afraid that was the case. – Rob Feb 21 '18 at 15:20
  • @JonathanChaplin Ideally I wanted a pure CSS one, but that doesn't look like it'll be possible. Will probably have to use JS and have an `.onchange` function that updates the content of the ` – Rob Feb 21 '18 at 15:25

2 Answers2

1

First Lets get one thing straight we can't create what you desire in IE because it doesn't allow anything other than <option>,<optgroup> tags inside a <select> box.

This is much of a workaround I can get using CSS only method in my opinion. If you prefer script there are plenty alternatives even select2 is one of the most used plugin for this type of customizations.

I Have used [type="checkbox"] for attain this result

jQuery is only being used to show the value.

var multyVal = [];
$('.multiple input[type="checkbox"]').each(function() {
  if ($(this).is(':checked')) {
    var Tval = $(this).val();
    multyVal.push(Tval);
  }
});

console.log($('select').val(), multyVal);
select>option::before {
  display: inline-block;
  width: 10em;
}

select>option:checked::before {
  content: "SELECTED: ";
}

select>option:not(:checked)::before {
  content: "excluded: ";
}

.multiple {
  height: 60px;
  display: inline-block;
  overflow-y: scroll;
  background: #d4d4d4;
  width: 10em;
  border: 1px solid #999;
  margin-left: 10px;
}

.multiple [type="checkbox"] {
  display: none;
}

.multiple label {
  width: 100%;
  float: left;
  font-size: 13px;
  text-align: right;
  background: #fff;
}

.multiple label::before {
  display: inline-block;
  float: left;
  font-family: arial, san-sarif;
  font-size: 11px;
}

.multiple [type="checkbox"]:checked+label::before {
  content: "SELECTED: ";
}

.multiple [type="checkbox"]:checked+label {
  background: #666;
  color: #fff;
}

.multiple [type="checkbox"]:not(:checked)+label::before {
  content: "excluded: ";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<select multiple>
  <option value="1" selected="selected">1</option>
  <option value="2" selected="selected">2</option>
  <option value="3" selected="selected">3</option>
  <option value="4" >4</option>
  <option value="5" >5</option>
</select>


<div class="multiple">
  <input type="checkbox" name="multiple" value="1" id="rad1" checked="checked">
  <label for="rad1">1</label>

  <input type="checkbox" name="multiple" value="2" id="rad2" checked="checked">
  <label for="rad2">2</label>

  <input type="checkbox" name="multiple" value="3" id="rad3" checked="checked">
  <label for="rad3">3</label>

  <input type="checkbox" name="multiple" value="4" id="rad4">
  <label for="rad4">4</label>

  <input type="checkbox" name="multiple" value="5" id="rad5">
  <label for="rad5">5</label>
</div>

Fiddle in case you want one.

Hoping this would come handy for you guys...

Jithin Raj P R
  • 6,667
  • 8
  • 38
  • 69
  • Thanks for the suggestion, I thought that would be the case; that only ` – Rob Feb 21 '18 at 15:22
  • @Rob it's k, glad I could be of some assistance. your `js` solution works well too. – Jithin Raj P R Feb 22 '18 at 05:04
1

Ideally I was looking for a pure CSS solution but as per the comments and @weBer

The <select> tag can only contain:

Zero or more <option>, <optgroup>, and script-supporting elements.

Therefore I will probably end up using a JavaScript solution like the below.

document.getElementById("multiSelect").onchange = function() {

  var opts = this.getElementsByTagName("option");

  for (var i = 0; i < opts.length; i++) {

    if (opts[i].selected === true) {
      opts[i].innerHTML = "SELECTED: " + opts[i].value;
    } else {
      opts[i].innerHTML = "excluded: " + opts[i].value;
    }

  }
};
select {
    height: 10em;
    width: 10em;
    overflow-y: hidden;
}
<select id="multiSelect" multiple>
    <option value="1">excluded: 1</option>
    <option value="2">excluded: 2</option>
    <option value="3">excluded: 3</option>
    <option value="4">excluded: 4</option>
    <option value="5">excluded: 5</option>
</select>
Rob
  • 117
  • 11
  • I actually haven't used `INCLUDED` and `excluded` text strings actually used the unicode characters for ballot box (with and without checks) as per @KyleMit [answer on this question](https://stackoverflow.com/a/48776016/2053770). – Rob Feb 22 '18 at 10:15