Sortable Draggable Accordion In jQuery
| File Size: | 5.99 KB |
|---|---|
| Views Total: | 4527 |
| Last Update: | |
| Publish Date: | |
| Official Website: | Go to website |
| License: | MIT |
A tiny jQuery script to create a sortable accordion widget where you can reorder accordion items via drag and drop.
How to use it:
1. The accordion script requires jQuery UI's accordion widget and sortable interaction.
<link rel="stylesheet" href="/path/to/cdn/jquery-ui.css" /> <script src="/path/to/cdn/jquery.min.js"></script> <script src="/path/to/cdn/jquery-ui.min.js"></script>
2. Create an accordion widget from unordered lists as follows.
<div id="accordion">
<div class="group" data-section-id="1">
<h3>Accordion 1</h3>
<div>
<ul class="sortable" data-list-id="1">
<li data-item-id="1"><span class="draggable"></span>Item 1</li>
<li data-item-id="2"><span class="draggable"></span>Item 2</li>
<li data-item-id="3"><span class="draggable"></span>Item 3</li>
...
</ul>
</div>
</div>
<div class="group" data-section-id="2">
<h3>Accordion 2</h3>
<div>
<ul class="sortable" data-list-id="2">
<li data-item-id="11"><span class="draggable"></span>Item 11</li>
<li data-item-id="12"><span class="draggable"></span>Item 12</li>
<li data-item-id="13"><span class="draggable"></span>Item 13</li>
...
</ul>
</div>
</div>
...
</div>
3. Initialize the accordion widget.
$("#accordion").accordion({
header: "> div > h3",
event: "click",
active: false,
collapsible: true
}).sortable({
items: "> div",
handle: "h3",
revert: false,
stop: function(e, ui) {
var sectionList = $(this).sortable("toArray", { attribute: "data-section-id" });
var sectionId = ui.item.context.dataset.sectionId;
var index = ui.item.index();
updateData({sectionId, sectionList});
ui.item.children("h3").triggerHandler("focusout");
$(this).accordion("refresh");
}
});
4. Make the accordion sortable.
$(".sortable").sortable({
items: "> li",
handle: ".draggable",
revert: true,
revertDuration: 50,
placeholder: "ui-sortable-placeholder",
sort: function(event, ui){ ui.item.addClass("selected"); },
stop: function(event, ui){ ui.item.removeClass("selected"); },
update: function(e, ui) {
var questionList = $(this).sortable("toArray", { attribute: "data-item-id" });
var sectionId = e.target.dataset.listId;
var questionId = ui.item.context.dataset.itemId;
var index = ui.item.index();
updateData({sectionId, questionId, questionList});
}
});
function updateData(obj) {
var data = JSON.stringify(obj, null, 2);
$('.data').text(data);
}
5. Output the updated data.
<div class="display">
<details>
<summary>View updated data</summary>
<pre class="data">{}</pre>
</details>
</div>
6. Additional CSS styles for the accordion widget.
:root {
--item-bg: #e9e9e9;
--item-bg-hover: #f9f9f9;
--item-border: #ccc;
--placeholder-border:#c1780e;
--placeholder-bg: #ffe8af;
--ontrack-green: #b3c022;
--ontrack-green-light: #99CD3D;
--ontrack-green-dark: #616900;
--draggable-icon: url(../images/draggable.gif);
--body-padding: 40px;
}
/*************/
/* Accordion */
/*************/
#accordion {
width: calc(50vmax - 2 * var(--body-padding));
max-width: 400px;
float: left;
}
#accordion > div > div {
padding: 0;
background-color: var(--item-border);
}
#accordion > div > h3 {
margin: 5px 0 0 0;
}
#accordion > div > h3[aria-selected=true] {
color: #fff !important;
border: 1px solid var(--ontrack-green-dark);
background: var(--ontrack-green);
transition: all 0.15s ease;
}
#accordion > div > h3[aria-selected=false] {
color: #454545 !important;
transition: all 0.15s ease;
}
@media only screen and (max-width: 640px) {
#accordion {
width: 100%;
}
}
/*********/
/* Items */
/*********/
ul.sortable {
list-style-type: none;
margin: 0;
padding: 0;
width: auto;
overflow-y: hidden;
}
ul.sortable li {
background-color: var(--item-bg);
padding: 10px 10px 10px 15px;
font-size: 1rem;
transition: background-color 0.15s ease;
}
ul.sortable li:hover {
background-color: var(--item-bg-hover);
transition: background-color 0.15s ease;
}
ul.sortable li:not(:last-child) {
margin: 0 0 1px 0;
}
.draggable {
background-image: var(--draggable-icon);
display: block;
width: 18px;
height: 18px;
float: left;
margin: 1px 5px 0 0;
cursor: move;
}
.selected {
border: 1px solid var(--item-border);
/* box-shadow: 0px 0px 5px 2px #00000033; */
}
.ui-sortable-placeholder {
border: 2px dashed var(--placeholder-border);
background-color: var(--placeholder-bg) !important;
height: 16px;
}
.ui-widget-content {
border: 1px solid var(--item-border) !important;
}
Changelog:
2020-12-19
- Added connected sortable list
2020-12-10
- Code refactor
This awesome jQuery plugin is developed by rolandjlevy. For more Advanced Usages, please check the demo page or visit the official website.











