可排序

在这个示例中,我们展示了如何将 Sortable JavaScript 库与 htmx 集成。

首先,我们用 Sortable JavaScript 库初始化 .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">更新中...</div>
  <div><input type='hidden' name='item' value='1'/>项目 1</div>
  <div><input type='hidden' name='item' value='2'/>项目 2</div>
  <div><input type='hidden' name='item' value='3'/>项目 3</div>
  <div><input type='hidden' name='item' value='4'/>项目 4</div>
  <div><input type='hidden' name='item' value='5'/>项目 5</div>
</form>

注意,每个 div 内部都有一个隐藏的输入框,指定了该行的项目 id。

当通过 Sortable.js 的拖放重新排序列表时,将触发 end 事件。然后 htmx 会将新的顺序下的项目 id 提交到 /items,由服务器持久化。

就是这样!

服务器请求 ↑ 显示

🔗演示