title: Click and drag select, outside of scrollable select element, and prevent scroll to top when selecting options
body: <p>I am trying to make a multiselectlist in which you do not have to click ctrl or shift to add additional selections. I have prevented the default behavior in favor of the new functionality. It is mostly working except for two issues.</p>
  <ol>
  <li><p>If I scroll down and click an option it will usually, not always, go to the top of the scroll list. I can't figure out a way to stop this from happening. I have tried using scrollTop() and had to put it inside a setTimeout() to work(I have commented around this code). But it does not seem to work all the time and I sometimes end up with a flashing behavior where I have to click a few times to select an item because it is jumping to the top and back down. Is there a better way to set the ScrollTop value to remove the flashing behavior I get sometimes?</p>
  </li>
  <li><p>The way I currently have the new select list working I cannot click and drag outside the select element to select all the options. I would like to have something similar to the default behavior when drag selecting but I can't seem to implement this type of behavior either. I have tried using mousemove capturing the y value and selecting options above or below a certain value but I could not get it working right. How would I implement this or is there a better way to do this?</p>
  </li>
  </ol>
  <p>I am fairly new to jquery and have been stumbling through the docs for a while now. Any help for the two problems above or just achieving the desired functionality with jquery if this is not a good way to achieve it is appreciated. Here is a link to a <a href="https://jsfiddle.net/skbraswell31/p8ce92hw/25/" rel="nofollow noreferrer">JSfiddle</a> I have been working with.</p>
  <p>(note for fiddle: Shift + click will only add items and shift + ctrl + click will only deselect items. Just clicking or click dragging will simply change option to opposite of current state.)</p>
  <p>JQuery:</p>
  <pre><code>$(document).ready(function() {
    $(&quot;select[multiple = 'multiple']&quot;).each(function() {
      var idLink = this.id;
      $(this).children().each(function() {
        $(this).attr('listgroup', idLink)
      })
    })
  })
  
  var shiftKeyPressed = false;
  var ctrlKeyPressed = false;
  
  $(&quot;option&quot;).mousedown(function(e) {
    e.preventDefault();
    var listGroup = $(this).attr('listgroup');
    var parent = $(this).parent();
    parent.focus();
    parent.keydown(function(evt) {
      if (evt.shiftKey) {
        shiftKeyPressed = true;
      }
      if (evt.ctrlKey) {
        ctrlKeyPressed = true;
      }
    }).keyup(function(evt) {
      shiftKeyPressed = false;
      ctrlKeyPressed = false;
    })
    //1 of 3 scrollTop code
    var top = parent.scrollTop();
    setTimeout(function() {
      parent.scrollTop(top);
    }, 1)
      // end scrollTop section 1
    if ($(this).prop(&quot;selected&quot;)) {
      $(this).prop(&quot;selected&quot;, false);
    } else {
      $(this).prop(&quot;selected&quot;, &quot;selected&quot;);
    }
  
    $(&quot;option[listgroup='&quot; + listGroup + &quot;']&quot;).mouseenter(function(e) {
       e.preventDefault();
       //2 of 3 scrollTop code
       setTimeout(function() {
        parent.scrollTop(top);
        //console.log('mouseEnter:' + top)
      }, 1)
      //end scrollTop section 2
      if (shiftKeyPressed &amp;&amp; ctrlKeyPressed) {
        if ($(this).prop(&quot;selected&quot;)) {
          $(this).prop(&quot;selected&quot;, false);
          $(this).removeClass(&quot;checkSelected&quot;);
        }
      } else if (shiftKeyPressed) {
        $(this).prop(&quot;selected&quot;, &quot;selected&quot;);
        $(this).addClass(&quot;checkSelected&quot;)
      } else {
        if ($(this).prop(&quot;selected&quot;)) {
          $(this).prop(&quot;selected&quot;, false);
          $(this).removeClass(&quot;checkSelected&quot;);
        } else {
          $(this).prop(&quot;selected&quot;, &quot;selected&quot;);
          $(this).addClass(&quot;checkSelected&quot;)
        }
      }
    })
    //3 0f 3 scrollTopCode
     parent.scroll(function(e) {
      e.preventDefault();
      setTimeout(function() {
        top = parent.scrollTop();
        parent.scrollTop(top);
      }, 1)
      console.log(top);
    })
    //end scrollTop section 3
  }).mouseup(function() {
    $(&quot;*&quot;).off(&quot;mouseenter&quot;);
    $(&quot;*&quot;).off(&quot;scroll&quot;);
  })
  </code></pre>
  <p>Html pseudo:</p>
  <pre><code>&lt;select&gt; *some options &lt;/select&gt;
  &lt;select&gt; *some options &lt;/select&gt;
  &lt;select&gt; *some options &lt;/select&gt;
  </code></pre>