Ask A Question

Notifications

You’re not receiving notifications from this thread.

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

Christopher Stewart asked in Gems / Libraries

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.

Reply

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.

Reply

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'))
Reply

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.

Reply

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?

Reply

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?

Reply

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
Reply

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

Reply

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).

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 87,563+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.