3

(Before writing this off as a duplicate of the various other questions of this nature, or as having been answered before, please read carefully.)

I'd like to make my HTML5 multiple select options so they never require Ctrl to be held down to select/deselect them without affecting other options. (This is for a Perl web application which I've been working on for years, and I've recently been asked to make the multiple select boxes less accident prone, i.e. users (some of whom are quite old) losing all other selected options when they click one, possibly without noticing.)

After spending hours testing various solutions I found on the web for this, I haven’t found any which do what I'd like, i.e.:

  1. I'd prefer not to use jQuery, since I haven't needed it yet in this application which I'd like to keep as lite as possible (and W3Schools says "after JavaScript Version 5 (2009), most of the jQuery utilities can be solved with a few lines of standard JavaScript").
  2. Work with simple HTML multiple select controls, and require no (or minimal) changes to the HTML markup.
  3. Any disabled <option>s (which might be pre-selected when the page loads) should not be selectable/unselectable by clicking them (or by clicking any other options).
  4. Clicking an option should not result in the list of options scrolling automatically, as happens with some solutions.
  5. Selected options should show in the traditional blue (or similar - not grey) in Chrome at least.
  6. Selected items should (preferably) be blue even before clicking the select box, in Chrome at least. (This happens by default with traditional multiple select options in Firefox, but not Chrome.)

One of the solutions I've been looking at is How to avoid the need for ctrl-click in a multi-select box using Javascript? (among the others on that page) and it's Fiddle (http://jsfiddle.net/xQqbR/1022). It's a good start, but doesn't cater for my requirements 1, 3 & 6. I see that various commenters have indicted that (and how) jQuery shouldn't be required for it, but after trying what they suggested I couldn't get it to work, and I hardly know any JavaScript to solve this myself.

Here's the kind of markup I'm dealing with:

<select multiple size=3>
  <option>Option 1</option>
  <option>Option 2</option>
  <option disabled>Option 3 (disabled)</option>
  <option>Option 4</option>
  <option>Option 5</option>
  <option>Option 6</option>
  <option selected>Option 7 (selected)</option>
  <option disabled selected>Option 8 (disabled+selected)</option>
</select>

Thanks in advance for your time and expertise.

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
Terry
  • 176
  • 9
  • 1
    Is there a reason why you couldn't use checkboxes instead? They seem like the most straightforward option here – Stubborn Jan 06 '20 at 06:23
  • 2
    @Stubborn That was my first idea too, but then I saw requirement #2. Apparently the OP needs to work with existing code that is resistant to changes. – Mr Lister Jan 06 '20 at 07:23
  • 1
    Thanks @Stubborn, but I don't see how I can use checkboxes, because I have a limited amount of space and sometimes dozens of options, so my select box might be only 4 lines high, and users scroll through it to get to the options they want. I've seen some custom select boxes with checkboxes next to each option, but I expect the solution is going to use significantly more screen space and/or be quite code intensive and possibly slower performing. Any suggestions? – Terry Jan 06 '20 at 08:28
  • 1
    @Terry how about something like autocomplete? For example https://github.com/yairEO/tagify#demo-page but with a dropdown menu showing suggestions for every item – Stubborn Jan 06 '20 at 09:20
  • 1
    Thanks again @Stubborn, nice facility, but probably overkill and not quite what I want in this case, which is just some tweaks to how the basic HTML multiple select box works. – Terry Jan 06 '20 at 23:27

1 Answers1

2

var expanded = false;
function showCheckboxes() {
  var checkboxes = document.getElementById("checkboxes");
  if (!expanded) {
    checkboxes.style.display = "block";
    expanded = true;
  } else {
    checkboxes.style.display = "none";
    expanded = false;
  }
}
#select22 {
 border-radius: 4px;
 width: 100%;
     height: 30px;
 color: white;
    padding-bottom: 2px;
        background-color: #00ced1;
         border: 1px solid #00ced1;
      border-bottom: 0.5px solid white;
 /* Here's the code we need */
 -webkit-appearance: none;
 -moz-appearance: none;
 -ms-appearance: none;
  -o-appearance: none;
  appearance: none;
}
.select-wrapper22:after {
 font-family: FontAwesome;
   content: '\f107';
   font-size: 20px;
   position: absolute;
   top: 6px;
   right: 4px;
   color: white;
   pointer-events: none;
}
.select-wrapper22:after:hover{
    font-family: FontAwesome;
   content: '\f107';
   font-size: 20px;
   position: absolute;
   top: 6px;
   right: 4px;
   color: #00ced1;
   pointer-events: none;
}
.overSelect {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}


#checkboxes {
    display: none;
    border: 1px #7e7e7e solid;
    background-color: white;
    padding-top: 10px;
}

#checkboxes label::before {
    display: block;
    font-family: Aller Light;
    background-color: white;
    color: #7e7e7e;
}

#checkboxes label::after {
    display: block;
    font-family: Aller Light;
    background-color: white;
    color: aqua;
}

#checkboxes label:hover {
    color: #00ced1;
}

#checkboxes label::after {
    color: #00ced1;
}
.cotner {
    display: block;
    position: relative;
    padding-left: 35px;
    margin-bottom: 12px;
    cursor: pointer;
    font-size: 15px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}


.cotner input {
    position: absolute;
    opacity: 0;
    cursor: pointer;
    height: 0;
    width: 0;
}


.chmk {
    position: absolute;
    top: 0;
    left: 0;
    height: 25px;
    width: 25px;
    background-color: white;
}


.chmk:after {
    content: "";
    position: absolute;
    display: none;
}


.cotner input:checked ~ .chmk:after {
    display: block;
    color: aqua;
}


.cotner .chmk:after {
    left: 9px;
    top: 2px;
    width: 5px;
    height: 10px;
    border: solid #00ced1;
    border-width: 0 3px 3px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
}

input[type=checkbox]:checked + label {
    color: red
}
 <div>
                        <p class="sideheadingdrop">Hard Skills<i style="" class="fa fa-exclamation-circle"></i></p>
                        <div  class="select-wrapper22" onclick="showCheckboxes()">
      <select id="select22" >
        <option value="" disabled selected hidden></option>
      </select>
      <div class="overSelect"></div>
    </div>
    <div id="checkboxes">
      <label for="one" class="cotner">
        <input type="checkbox" id="one" />
          <span class="chmk"></span>First checkbox</label>
      <label for="two" class="cotner">
        <input type="checkbox" id="two" />
          <span class="chmk"></span>Second checkbox</label>
      <label for="three" class="cotner">
        <input type="checkbox" id="three" />
          <span class="chmk"></span>Third checkbox</label>
    </div>
                    </div>

I have created multi checkbox without use of ctrl.

Suraj-Ui
  • 196
  • 2
  • 14
  • When you will on dropdown you will get list and can select multiples. – Suraj-Ui Jan 06 '20 at 11:26
  • Thanks for your efforts Suraj-Ui, looks beautiful, but it doesn't meet my requirement #2, for starters. I also suggest you use the "kind of markup I'm dealing with" (see the bottom of my original post) as your sample data, to ensure it's going to meet my other requirements, e.g. #3 & #4. Thanks. – Terry Jan 06 '20 at 21:22