Feature

Sortable lists with sortable JS

Preview

This feature uses the javascript library sortable js to handle drag and drop sorting. Install it with:

yarn add sortablejs

The javascript is initiated with a LiveView hook. InitSortable. The idea is that the as soon the the sorting event is triggered, I send a push event to the component with the list of task ids and the sortorder.

In this example, there are also two connected lists and the tasks can be sorted and drag between both lists.

In the markup, I use data attributes like:

data-target-id="#<%= @id %>" <!-- The LiveView Component that I need to send the event to -->
data-list-id="<%= list_id %>" <!-- The is of the current list -->
data-sortable-id="<%= task[:id] %>" <!-- The id of the current task in the list -->

Note that when the tasks are returned from the Tasks contect, they are sorted by the sort_order attribute.

tasks = Tasks.list_tasks()
lib/phoenix_features_web/live/components/sortable_simple.ex
defmodule PhoenixFeaturesWeb.Components.SortableSimple do
  use PhoenixFeaturesWeb, :live_component

  alias PhoenixFeatures.Tasks

  @lists ~w(1 2)

  def mount(socket) do
    tasks = Tasks.list_tasks()

    {:ok,
      socket
      |> assign(:tasks, tasks)
      |> assign(:lists, @lists)
    }
  end

  def handle_event("sort", %{"list" => [_|_] = list}, socket) do
    list
    |> Enum.each(fn %{"id" => id, "list_id" => list_id, "sort_order" => sort_order} ->
      Tasks.get_task(id)
      |> Tasks.update_task(%{list_id: list_id, sort_order: sort_order})
    end)

    {:noreply, socket}
  end
end