简体   繁体   中英

What is the simplest way to allow a user to drag and drop table rows in order to change their order?

I have a Ruby on Rails application that I'm writing where a user has the option to edit an invoice. They need to be able to reassign the order of the rows. Right now I have an index column in the db which is used as the default sort mechanism. I just exposed that and allowed the user to edit it.

This is not very elegant. I'd like the user to be able to drag and drop table rows. I've used Scriptaculous and Prototype a bit and am familiar with them. I've done drag and drop lists, but haven't done table rows quite like this. Anyone have any suggestions for not only reordering but capturing the reorder efficiently?

Also, the user can dynamically create a new row in JS right now, so that row has to be reorderable as well.

Bonus points if it can be done with RJS instead of direct JavaScript.

I've used the Yahoo User Interface library to do this before:

http://developer.yahoo.com/yui/dragdrop/

MooTools sortables are actually better than script.aculo.us because they are dynamic; MooTools allows the addition/removal of items to the list. When a new item is added to a script.aculo.us sortable, you have to destroy/recreate the sortable to make the new item sortable. There'll be a lot overhead in doing so if the list has many elements. I had to switch from script.aculo.us to the more lightweight MooTools just because of this limitation and ended up being extremely happy with that decision.

The MooTools way of making a newly added item sortable is just:

sortables.addItems(node);

Okay, I did some more scouring and figured out something that seems to mostly be working.

edit.html.erb:

...
<table id="invoices">
   <thead>
     <tr>
      <th>Id</th>
      <th>Description</th>
     </tr>
   </thead>
   <tbody id="line_items">
      <%= render :partial => 'invoice_line_item', :collection => @invoice.invoice_line_items.sort %>
   </tbody>
</table>

<%= sortable_element('line_items', {:url => {:action => :update_index}, :tag => :tr, :constraint => :vertical}) -%>
...

app/controllers/invoices.rb

...
def update_index
  params["line_items"].each_with_index do |id, index|
    InvoiceLineItem.update(id, :index => index)
  end
  render :nothing => true
end
...

The important part is :tag => :tr in "sortable_element" and params["line_items"] -- this gives the new list of ids and is triggered on the drop.

Detriments: Makes the AJAX call on drop, I think I'd prefer to store the order and update when the user hits "save". Untested on IE.

I like jQuery http://docs.jquery.com/UI/Sortables

$("#myList").sortable({});

You will need to write some code to persist it but it isn't that tough.

雅虎的界面比我想象的要容易,在不到四个小时的时间内做了一些时髦的工作。

Scriptaculous的sortables好像去,因为它内置的方式。 http://github.com/madrobby/scriptaculous/wikis/sortable

With Prototype and Scriptaculous :

Sortable.create('yourTable', {
    tag: 'tr',
    handles: $$('a.move'),
    onUpdate: function() {
        console.log('onUpdate');
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM