Drag And Drop Sortable List
by Keith Rowles • 04/11/2023JavaScript
Summary
Fun drag and drop sortable list using javascript, css and html.
Sort the list from 1 to 10. Top 10 NRL Teams in 2023.
Then check your answers by clicking on the check order button.
Note: The list is generated by javascript.
HTML
<h1>Top 10 NRL Teams 2023</h1>
<p>Drag and Drop Items to place in the correct order. From 1 to 10.</p>
<ul class="draggable-list" id="draggable-list"></ul>
<button class="check-btn" id="check">
Check Order
<i class="fas fa-paper-plane"></i>
</button>
CSS
@import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
:root {
--border-color: #e3e5e4;
--background-color: #c3c7ca;
--text-color: #34444f;
--heading-color: dodgerblue;
--text-color-white: white;
}
* {
box-sizing: border-box;
}
body {
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
height: 100vh;
margin: 0;
font-family: 'Lato', sans-serif;
}
h1 {
color: var(--heading-color);
}
.draggable-list {
border: 1px solid var(--border-color);
color: var(--text-color);
padding: 0;
list-style-type: none;
}
.draggable-list li {
background-color: #fff;
display: flex;
flex: 1;
}
.draggable-list li:not(:last-of-type) {
border-bottom: 1px solid var(--border-color);
}
.draggable-list .number {
background-color: var(--heading-color);
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
height: 60px;
width: 60px;
color: var(--text-color-white);
}
.draggable-list li.over .draggable {
background-color: #b4b4b4;
}
.draggable-list .person-name {
margin: 0 20px 0 0;
}
.draggable-list li.right .person-name {
color: #3ae374;
}
.draggable-list li.wrong .person-name {
color: #ff3838;
}
.draggable {
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px;
flex: 1;
}
.check-btn {
background-color: var(--heading-color);
border: none;
color: var(--text-color-white);
font-size: 16px;
padding: 10px 20px;
cursor: pointer;
border-radius: 5px;
}
.check-btn:hover {
background-color: darkslategray;
}
.check-btn:active {
transform: scale(0.98);
}
.check-btn:focus {
outline: none;
}
JavaScript
const draggable_list = document.getElementById('draggable-list');
const check = document.getElementById('check');
const nrlteams = [
'Penrith Panthers',
'Brisbane Broncos',
'Melbourne Storm',
'New Zealand Warriors',
'New Castle Knights',
'Cronulla Sharks',
'Easts Roosters',
'Canberra Raiders',
'Souths Rabbitohs',
'Paramatta Eels',
];
// store the list items
const listItems = [];
let dragStartIndex;
createList();
// insert list items into dom
function createList() {
[...nrlteams]
.map((a) => ({ value: a, sort: Math.random() }))
.sort((a, b) => a.sort - b.sort)
.map((a) => a.value)
.forEach((person, index) => {
const listItem = document.createElement('li');
listItem.setAttribute('data-index', index);
listItem.innerHTML = `
<span class="number">${index + 1}</span>
<div class="draggable" draggable="true">
<p class="person-name">${person}</p>
<i class="fas fa-grip-lines"></i>
</div>
`;
listItems.push(listItem);
draggable_list.appendChild(listItem);
});
addEventListeners();
}
function dragStart() {
// console.log('Event: ', 'dragstart');
dragStartIndex = +this.closest('li').getAttribute('data-index');
console.log(dragStartIndex);
}
function dragEnter() {
// console.log('Event: ', 'dragenter');
this.classList.add('over');
}
function dragLeave() {
// console.log('Event: ', 'dragleave');
this.classList.remove('over');
}
function dragOver(e) {
// console.log('Event: ', 'dragover');
e.preventDefault();
}
function dragDrop() {
// console.log('Event: ', 'drop');
const dragEndIndex = +this.getAttribute('data-index');
swapItems(dragStartIndex, dragEndIndex);
this.classList.remove('over');
}
// swap list items
function swapItems(fromIndex, toIndex) {
const itemOne = listItems[fromIndex].querySelector('.draggable');
const itemTwo = listItems[toIndex].querySelector('.draggable');
console.log(itemOne, itemTwo);
listItems[fromIndex].appendChild(itemTwo);
listItems[toIndex].appendChild(itemOne);
}
// check the order of list items
function checkOrder() {
listItems.forEach((listItem, index) => {
const personName = listItem.querySelector('.draggable').innerText.trim();
if (personName !== nrlteams[index]) {
listItem.classList.add('wrong');
} else {
listItem.classList.remove('wrong');
listItem.classList.add('right');
}
});
}
function addEventListeners() {
const draggables = document.querySelectorAll('.draggable');
const dragListItems = document.querySelectorAll('.draggable-list li');
draggables.forEach((draggable) => {
draggable.addEventListener('dragstart', dragStart);
});
dragListItems.forEach((item) => {
item.addEventListener('dragover', dragOver);
item.addEventListener('drop', dragDrop);
item.addEventListener('dragenter', dragEnter);
item.addEventListener('dragleave', dragLeave);
});
}
check.addEventListener('click', checkOrder);
Demo
Open demo on Code Pen.
Link to Demo