Skip to main content

Are there any up to date tutorials for jquery-sortable?

Gems / Libraries • Asked by Christopher Stewart


I've built a todo list that consists of lists and tasks. I am looking to use sortable to allow someone to move items around and between lists. Can anyone recommend any resources on how to do this? I would like to be able to create as many lists as I need and have them available to be dragged and dropped to. Not sure how to go about that.

Gravatar Chris Oliver commented on : Mod Staff

Hey Chris,

That's a good question. Honestly the Railscasts episode is probably the most recent that I've seen on that. http://railscasts.com/episodes/147-sortable-lists-revised?view=comments

I should do an episode on it, but I don't think too much has changed. The general idea is that you will keep track of the sort order in the db and then when the user drops an item, you tell the server to update all the positions of items accordingly.

Thanks Chris. I stumbled upon that tutorial and was able to get it working for one list. I am struggling trying to get it to work with multiple dynamic lists though. In my app I can create new lists when I need so I was looking to set this up to be able to drag and drop events between whatever lists that are there. Any ideas on howw to do something like that?

<% @tasklists.each do |tasklist| %>
    <ul class="sortable-list connectList agile-list" id="sortable" data-update-url="<%= sort_tasklists_url %>">
        <%= tasklist.taskitems.each do |taskitems| %>


            <li class="info-element" id="list_<%= taskitems.id %>">

          <%= taskitems.content %>

          <div class="agile-detail">

            <%= link_to "Delete", tasklist_taskitem_path(tasklist, taskitems.id), :class=>"pull-right btn btn-xs btn-    danger", method: :delete, data: { confirm: "Are you sure?" } %>
            <i class="fa fa-clock-o"></i>
            <%= taskitems.created_at.strftime('%m/%d/%Y %I:%M %p') %>
          </div>
    </li>
        <% end %>
      </ul>

Coffee script:

jQuery ->
  $("#sortable").sortable
      update: ->
      $.post($(this).data('update-url'), $(this).sortable('serialize'))
Gravatar Chris Oliver commented on : Mod Staff

Ah I see, kinda like Trello board columns. I believe you would want to make sure you submitted the tasklist for the one that the item landed on. You would probably need to check that and see what $(this) references, whether it was for the column it was picked up, or the column of where it dropped. Then server-side you can take those items and make sure that they're all updated with the correct tasklist_id which would do the moving of the item between tasklists on the db side.

This might make for a good screencast.

Yup like Trello. I have seen some Trello clone tutorials but none that include the sortable fucntionality. That would be a great screencast!

Would I need to name the UL a unique value? Like sortable_<%= tasklist.id %>, or would checking "this" get what list I am dropping to?

I'm very close I think. At least I have the correct params coming through now.

  Parameters: {"list"=>["2"], "item"=>["5", "4", "10"]}

I just need to get the update working. It is updating positions, but multiple lists at the same time and not setting the correct list ID.

    def sort
      @items = params[:item]
      @items.each_with_index do |id, index|
        taskitem = Taskitem.where(tasklist_id: params[:list], id: id).update_all(:position => (index +1))
      end
      render :nothing => true
    end

Any thoughts on how I can change this?

Gravatar Chris Oliver commented on : Mod Staff

This is looking pretty good. I think the tough spot now is that you need to set the update to set the tasklist_id as well.

I think this should work:

def sort
  @list_id = params[:list].first
  @items = params[:item]
  @items.each_with_index do |id, index|
    taskitem = Taskitem.find(id).update(tasklist_id: @list_id, position: (index +1))
  end
  render :nothing => true
end

Yup that did it! Thanks a lot. It's all working now.

Chris , you're creating an N+1 query with your code by calling find inside an iterator.
I think the logic can change to calling Takitem.find( @items ) and than use Active-Import gem to to a bulk update on all items.
That will be 2 database calls instead of @items.size * 2 (a find and update per iteration).

Login or create an account to join the conversation.