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.
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?
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?
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 JSfiddle I have been working with.
(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.)
JQuery:
$(document).ready(function() {
$("select[multiple = 'multiple']").each(function() {
var idLink = this.id;
$(this).children().each(function() {
$(this).attr('listgroup', idLink)
})
})
})
var shiftKeyPressed = false;
var ctrlKeyPressed = false;
$("option").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("selected")) {
$(this).prop("selected", false);
} else {
$(this).prop("selected", "selected");
}
$("option[listgroup='" + listGroup + "']").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 && ctrlKeyPressed) {
if ($(this).prop("selected")) {
$(this).prop("selected", false);
$(this).removeClass("checkSelected");
}
} else if (shiftKeyPressed) {
$(this).prop("selected", "selected");
$(this).addClass("checkSelected")
} else {
if ($(this).prop("selected")) {
$(this).prop("selected", false);
$(this).removeClass("checkSelected");
} else {
$(this).prop("selected", "selected");
$(this).addClass("checkSelected")
}
}
})
//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() {
$("*").off("mouseenter");
$("*").off("scroll");
})
Html pseudo:
<select> *some options </select>
<select> *some options </select>
<select> *some options </select>