I don’t know a ready-made component that does this - either in HTML5 or using some library or framework. The logic, however, is quite simple:
- On the left and right you have components that allow multiple selection (e.g.: a
select
attribute-ridden multiple
, or something more complex);
- When you click the right arrow button, you take all the selected elements from the list on the left and transfer them to the list on the right;
- Idem to left arrow, just reversing the lists.
Here is a simple example, using select multiple
(similar to the one used in Django):
function mover(fonte, destino) {
var selecionados = fonte.querySelectorAll("option:checked");
for ( var i = 0 ; i < selecionados.length ; i++ ) {
fonte.removeChild(selecionados[i]);
destino.appendChild(selecionados[i]);
}
}
document.querySelector("button.dir").onclick = function() {
mover(document.querySelector("select.esq"),
document.querySelector("select.dir"));
};
document.querySelector("button.esq").onclick = function() {
mover(document.querySelector("select.dir"),
document.querySelector("select.esq"));
};
<div style="display:flex">
<select multiple class="esq">
<option>Item A</option>
<option>Item B</option>
<option>Item C</option>
<option>Item D</option>
<option>Item E</option>
</select>
<div style="display:flex; flex-direction:column">
<button class="dir">▶</button>
<button class="esq">◀</button>
</div>
<select multiple class="dir"></select>
</div>
So just adapt to be more like what you want. In this second example, I replaced the select multiple
by a list in which each item has a checkbox
to mark the selection, and used the functionality of drag-and-drop jQuery UI so that items can be moved this way too:
function mover(fonte, destino) {
var selecionados = fonte.querySelectorAll("li input:checked");
for ( var i = 0 ; i < selecionados.length ; i++ ) {
var li = selecionados[i].parentNode.parentNode;
fonte.removeChild(li);
destino.appendChild(li);
selecionados[i].checked = false;
}
}
document.querySelector("button.dir").onclick = function() {
mover(document.querySelector("ul.esq"),
document.querySelector("ul.dir"));
};
document.querySelector("button.esq").onclick = function() {
mover(document.querySelector("ul.dir"),
document.querySelector("ul.esq"));
};
// Drag-and-drop
$( function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".connectedSortable"
}).disableSelection();
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div style="display:flex">
<ul id="sortable1" class="esq connectedSortable" style="list-style-type: none;">
<li><label><input type="checkbox"> Item A</label></li>
<li><label><input type="checkbox"> Item B</label></li>
<li><label><input type="checkbox"> Item C</label></li>
<li><label><input type="checkbox"> Item D</label></li>
<li><label><input type="checkbox"> Item E</label></li>
</ul>
<div style="display:flex; flex-direction:column; margin-left: 10px">
<button class="dir">▶</button>
<button class="esq">◀</button>
</div>
<ul id="sortable2" class="dir connectedSortable" style="list-style-type: none;"></ul>
</div>
I do not know if there is a component ready with this functionality, it seems to me more a pattern that uses several components to achieve a goal (select a subset of items in a set). Anyway, I suggest you take a look in this example in jQuery UI for a way to do this using drag-and-drop (is not a complete solution, but it is a good starting point).
– mgibsonbr
As I had spoken about this component, it is not necessary that the same be 'Drag n Drop', but use arrows to separate available content from required content, as is done in many control panel interfaces
– Thales Carvalho