I have a multi-select box which has 2 buttons on the right which are sorting an option up and down the list. This works fine, however if I move the option up or below the top or bottom boundary of the multiselect the scrollbar won’t take that into effect and move accordingly. Any suggestions?
JavaScript:
$(document).ready(function() {
$("#mup")[0].attachEvent("onclick", moveUpItem);
$("#mdown")[0].attachEvent("onclick", moveDownItem);
});
function moveUpItem() {
$('#list option:selected').each(function() {
$(this).insertBefore($(this).prev());
});
}
function moveDownItem() {
$('#list option:selected').each(function() {
$(this).insertAfter($(this).next());
});
}
//Holding down the Up/Down buttons
$(document).ready(function() {
var timer;
$("#mup, #mdown").on('mousedown', function() {
if (this.id === 'mup') {
timer = setInterval(moveUpItem, 250);
} else {
timer = setInterval(moveDownItem, 250);
}
}).on('mouseup', function() {
clearInterval(timer);
});
});
$(document).ready(function() {
$("#submit").click(function() {
$("#list").each(function() {
$("#list option").attr("selected","selected");
});
$("#detColumnSortorder").submit;
});
});
HTML:
<table>
<tr>
<td align="center">
<select id="list" name="fieldNames" size="15" multiple="multiple" style="width: 250px;">
<c:forEach var="field" items="${detFields}">
<option value="${field.fieldName}">${field.displayName}</option>
</c:forEach>
</select>
</td>
<td>
<button id="mup">
<img src="../images/button_up.gif" alt="Hold to move up faster."/>
</button>
</td>
<td>
<button id="mdown">
<img src="../images/button_down.gif" alt="Hold to move down faster."/>
</button>
</td>
</tr>
<tr>
<td style="text-align: center;">
<input name="action" id="submit" type="submit" value="Submit"/>
<input name="action" type="submit" value="Cancel"/>
</td>
</tr>
</table>
Wow, this was interesting. It looks like there are some bugs with how Chrome/WebKit handle option movement in a select. I’m not entirely sure what the current behavior is. Sometimes it moves and sometimes it doesn’t.
So, I thought, easy… I’ll just code a quick workaround. Turns out, it’s not so easy. WebKit doesn’t provide javascript access to some information, such as option height, etc.
So, after quite a few workarounds I have a hack that seems to work:
http://jsfiddle.net/jtbowden/7NEqk/
Take it for what it is worth. Basically, the code tracks selected items within the visible window of the select box. If the top goes above the visible window, move up, etc.
A couple of notes:
.get().reverse(), otherwise, if you have adjacent selected items, you will simply have them swap positions, instead of moving down. (1moves below2, then2moves below1).17. This is my best guess, but you could tweak it. Also, this means your options can’t be different heights. I don’t think that is possible in WebKit anyway.return false;in themousedownhandler. This is the same asevent.preventDefault(), etc. It keeps the button from stealing focus from the select, which in Chrome, makes the selected options turn gray, instead of their normal blue.Of course, after saying all of this, there is probably a better way of managing this select system in the first place… But, I took it as a challenge to make it work the way I thought it should.
P.S. Who knows about IE… I didn’t check it, and I am afraid to.