SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Zealot imagize's Avatar
    Join Date
    Oct 2004
    Location
    Australia
    Posts
    197
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Select multiple options without ctrl click

    I am looking to idiot proof certain aspects of my admin interface. I would like the user to be able to select various options from a multi select box by simply clicking the options instead of ctrl-click. There may be multiple select boxes on the page that require this functionality.,

    Thanks

  2. #2
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I think you will have to loop through all select boxes with a "multiple" attribute and attach an onchange event listener to each. Create an array for each select box (perhaps storing them all in an object) containing all the options and whether each is selected or not. Then whenever the select box changes, check which was clicked and if it's in the array, remove it. If not, add it. Then loop through the options and for each one make the relevant option selected (because if it's not in the array it doesn't need to be selected).

  3. #3
    SitePoint Zealot imagize's Avatar
    Join Date
    Oct 2004
    Location
    Australia
    Posts
    197
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Does anyone know of a pre-made script? Javascript is not my forte. Thanks for the help.

  4. #4
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    It works in Firefox and should work in all other browsers too, though I'm not sure about IE because I can't remember where it chokes regarding hasAttribute or removeAttribute. I'd be grateful if you could test it for me in IE because I've broken mine. There's also a nasty flicker when you click on any of the options, you'll see what I mean. Will try and deal with that later.
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
      <title>Badger</title>
      <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
      <meta name="generator" content="Crimson Editor" />
      <link rel="stylesheet" type="text/css" href="" />
      <script type="text/javascript">
        function init() {
          if (arguments.callee.done) return;
          arguments.callee.done = true;
          if (khtmltimer) clearInterval(khtmltimer);
          var s = document.getElementsByTagName('select');
          for (var i = 0; i < s.length; i++) {
            if (s[i].hasAttribute('multiple')) {
              s[i].onclick = updateSelect;
            }
          }
        }
        function updateSelect(e) {
          var opts = this.getElementsByTagName('option'), t, o;
          if (e) {
            e.preventDefault();
            t = e.target;
          }
          else if (window.event) {
            window.event.returnValue = false;
            t = window.event.srcElement;
          }
          else return;
          t = e.target || window.event.srcElement;
          if (t.getAttribute('class') == 'selected') t.removeAttribute('class');
          else t.setAttribute('class', 'selected');
          for (var i = 0, j = opts.length; i < j; i++) {
            if (opts[i].hasAttribute('class')) opts[i].selected = true;
            else opts[i].selected = false;
          }
        }
             
        if (document.addEventListener) document.addEventListener("DOMContentLoaded", init, false);
        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            var script = document.getElementById('__ie_onload');
            script.onreadystatechange = function() {
                if (this.readyState == 'complete') {
                    init();
                }
            };
        /*@end @*/
        if (/KHTML/i.test(navigator.userAgent)) {
            var khtmltimer = setInterval(function() {
                if (/loaded|complete/.test(document.readyState)) {
                    init();
                }
            }, 10);
        }
        window.onload = init;
      </script>
    </head>
    
    <body>
      <div id="a">
        <select name="x" multiple="multiple">
        <option value="xa">Badger</option>
        <option value="xb">Badger</option>
        <option value="xc">Badger</option>
        <option value="xd">Badger</option>
        <option value="xe">Badger</option>
        <option value="xf">Badger</option>
        <option value="xg">Badger</option>
        <option value="xh">Badger</option>
        <option value="xi">Badger</option>
        </select>
      </div>
    </body>
    </html>

  5. #5
    SitePoint Zealot imagize's Avatar
    Join Date
    Oct 2004
    Location
    Australia
    Posts
    197
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It works fine on firefox as you mentioned but IE doesn't support hasAttribute/setAttribute at all.

    Thanks.

  6. #6
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    That's true for hasAttribute, but IE does support setAttribute, just not entirely well.

    This should work in IE now:
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html>
    <head>
      <title>Badger</title>
      <script type="text/javascript">
        function init() {        
          var s = document.getElementsByTagName('select');
          for (var i = 0; i < s.length; i++) {
            if (s[i].multiple) {
              s[i].onclick = updateSelect;
            }
          }
        }
        function updateSelect(e) {
          var opts = this.getElementsByTagName('option'), t, o;
          if (e) {
            e.preventDefault();
            t = e.target;
          }
          else if (window.event) {
            window.event.returnValue = false;
            t = window.event.srcElement;
          }
          else return;
          t = e.target || window.event.srcElement;
          if (t.className == 'selected') t.className = '';
          else t.className = 'selected';
          for (var i = 0, j = opts.length; i < j; i++) {
            if (opts[i].className == 'selected') opts[i].selected = true;
            else opts[i].selected = false;
          }
        }
        window.onload = init;
      </script>
    </head>
    
    <body>
        <select name="x" multiple="multiple">
        <option value="xa">Badger</option>
        <option value="xb">Badger</option>
        <option value="xc">Badger</option>
        <option value="xd">Badger</option>
        <option value="xe">Badger</option>
        <option value="xf">Badger</option>
        <option value="xg">Badger</option>
        <option value="xh">Badger</option>
        <option value="xi">Badger</option>
        </select>
    </body>
    </html>
    The only caveat is that with this simple script you can't give the <option>s class attributes, but I think that's normally fairly unusual.

  7. #7
    SitePoint Zealot imagize's Avatar
    Join Date
    Oct 2004
    Location
    Australia
    Posts
    197
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That works fine in FF, but IE7 still will not select multiple.

  8. #8
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Well, I found out that IE doesn't support onclick events on <option> elements and that when you use the event on a <select> it gets the srcElement wrong anyway.

    I found this: http://www.mattkruse.com/temp/easier-multi-select.html - it does what you want, but it uses inline event handlers, so I added to it to work for any <select> with a multiple attribute. It works in IE.
    Code Javascript:
    var multiSelect = {};
        function init() {      
          var s = document.getElementsByTagName('select');
          for (var i = 0; i < s.length; i++) {
            if (s[i].multiple) {
              var n = s[i].name;
              multiSelect[n] = [];
              for (var j = 0; j < s[i].options.length; j++) {
                multiSelect[n][j] = s[i].options[j].selected;
              }
              s[i].onchange = changeMultiSelect;
            }
          }
        }
        function changeMultiSelect() {
          var n = this.name;
          for (var i=0; i < this.options.length; i++) {
            if (this.options[i].selected) {
              multiSelect[n][i] = !multiSelect[n][i];
            }
            this.options[i].selected = multiSelect[n][i];
          }
        }
        window.onload = init;


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •