์ด ์์ ์์๋ Sortable ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ htmx์ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
๋จผ์ , Sortable
์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก .sortable
ํด๋์ค๋ฅผ ์ด๊ธฐํํฉ๋๋ค:
htmx.onLoad(function(content) {
var sortables = content.querySelectorAll(".sortable");
for (var i = 0; i < sortables.length; i++) {
var sortable = sortables[i];
var sortableInstance = new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class',
// `.htmx-indicator`๋ฅผ ์ ๋ ฌ ๋ถ๊ฐ๋ฅํ๊ฒ ๋ง๋ญ๋๋ค.
filter: ".htmx-indicator",
onMove: function (evt) {
return evt.related.className.indexOf('htmx-indicator') === -1;
},
// `end` ์ด๋ฒคํธ ์ ์ ๋ ฌ์ ๋นํ์ฑํํฉ๋๋ค.
onEnd: function (evt) {
this.option("disabled", true);
}
});
// `htmx:afterSwap` ์ด๋ฒคํธ์์ ์ ๋ ฌ์ ๋ค์ ํ์ฑํํฉ๋๋ค.
sortable.addEventListener("htmx:afterSwap", function() {
sortableInstance.option("disabled", false);
});
}
})
๋ค์์ผ๋ก, ๋ด๋ถ์ ์ ๋ ฌ ๊ฐ๋ฅํ div๋ค์ด ์๋ ํผ์ ์์ฑํ๊ณ , Sortable.js์ end
์ด๋ฒคํธ์์ ajax ์์ฒญ์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค:
<form class="sortable" hx-post="/items" hx-trigger="end">
<div class="htmx-indicator">Updating...</div>
<div><input type='hidden' name='item' value='1'/>Item 1</div>
<div><input type='hidden' name='item' value='2'/>Item 2</div>
<div><input type='hidden' name='item' value='3'/>Item 3</div>
<div><input type='hidden' name='item' value='4'/>Item 4</div>
<div><input type='hidden' name='item' value='5'/>Item 5</div>
</form>
๊ฐ div์๋ ํด๋น ํ์ ํญ๋ชฉ ID๋ฅผ ์ง์ ํ๋ ์จ๊ฒจ์ง input์ด ํฌํจ๋์ด ์์ต๋๋ค.
Sortable.js ๋๋๊ทธ ์ค ๋๋กญ์ผ๋ก ๋ชฉ๋ก์ด ์ฌ์ ๋ ฌ๋๋ฉด end
์ด๋ฒคํธ๊ฐ ๋ฐ์ํฉ๋๋ค. htmx๋ ์๋ก์ด ์์์ ํญ๋ชฉ ID๋ค์ /items
๋ก POSTํ์ฌ ์๋ฒ์ ์ ์ฅํ๊ฒ ๋ฉ๋๋ค.
์ด๊ฒ ์ ๋ถ์ ๋๋ค!