Using JavaScript, you can quite easily implement such a control yourself. Here is a very quick and dirty example that works in modern browsers (most notably, not in Internet Explorer). Since mobile browsers do fire click
events when handlers are attached directly to elements, this also works on mobile/touch devices. Of course, you may want to implement a slightly different layout for mobile devices, to make it easier to click elements. It may also be more intuitive to implement drag-and-dropping of elements to sort them on touch devices.
To make this work in a regular old form, a hidden input can be added and updated as well. To this end, we can add data attributes on the options, since they can be read easily with JavaScript. Another option would be to intercept the submit event of the form and doing the submit manually via AJAX, loading the event order then. The below demo implements the first option: populating a hidden input.
function orderInput(list, upButton, downButton, input) {
updateInput(list, input);
// enable selection of list elements
for (let li of list.querySelectorAll('li')) {
li.addEventListener('click', () => {
for (let sibling of li.parentNode.children) {
if (!sibling.isSameNode(li)) {
sibling.classList.remove('selected');
}
}
li.classList.toggle('selected');
});
}
// enable moving an element up
upButton.addEventListener('click', () => {
var li = list.querySelector('li.selected');
if (li.previousElementSibling !== null) {
li.parentNode.insertBefore(li, li.previousElementSibling);
updateInput(list, input);
}
});
// enable moving an element down
downButton.addEventListener('click', () => {
var li = list.querySelector('li.selected');
if (li.nextElementSibling !== null) {
li.parentNode.insertBefore(li, li.nextElementSibling.nextElementSibling);
updateInput(list, input);
}
});
}
function updateInput(list, input) {
var values = [];
for (let li of list.querySelectorAll('li')) {
values.push(li.dataset.value);
}
input.value = values.join(';');
}
// instantiate on our fruits
orderInput(
document.querySelector('ul'),
document.getElementById('up'),
document.getElementById('down'),
document.querySelector('input[name="fruits"]')
);
ul {
padding-left: 0;
list-style-type: none;
border: 1px solid darkgray;
}
li {
padding: 2px 4px;
}
li:nth-child(even) {
background-color: lightgray;
}
li.selected {
background-color: blue;
color: white;
}
<p>Click an item in the list to select it, change its place in the list using the up and down buttons.</p>
<button id="up">Up</button> - <button id="down">Down</button>
<ul>
<li data-value="red-apple">Apple</li>
<li data-value="yellow-banana">Banana</li>
<li data-value="cherries">Cherry</li>
<li data-value="d-fruit">Dragon Fruit</li>
<li data-value="old-berry">Elderberry</li>
<li data-value="not-a-figure">Fig</li>
<li data-value="blue-grape">Grape</li>
</ul>
<input type="hidden" name="fruits" />