Pergunta

I have links and groups (of links).
I have a groups show page that shows one group and the members it contains.

How can I reorder the links and have the state saved to the database?

I've added jquery-ui and used .sortable so I can actually move the li rows in the ui. Now I need to add the rails code to save this sort. How do I do this? All the examples I see are for a full list and the whole list gets re-written so the index of the loop can be used.
Mine however look like:

<ul>
<li id='361'>
  <a href="http://www.w.com" title="www.w.com">w.com</a>
  -             &nbsp;&nbsp;<a href="/links/361" title="">details</a>            &nbsp;&nbsp;<a href="/links/361/edit" title="">edit</a>
</li>
<li id='362'>
  <a href="http://www.snap2web.com" title="www.snap2web.com">snap2web.com</a>
  -             &nbsp;&nbsp;<a href="/links/362" title="">details</a>            &nbsp;&nbsp;<a href="/links/362/edit" title="">edit</a>
</li>
<li id='363'>
  <a href="http://http://www.w.commm" title="htttp://www.w.commm">htttp://w.commm</a>
  -             &nbsp;&nbsp;<a href="/links/363" title="">details</a>            &nbsp;&nbsp;<a href="/links/363/edit" title="">edit</a>
</li>
<li id='365'>
  <a href="http://www.testabc.com" title="www.testabc.com">testabc.com</a>
  -             &nbsp;&nbsp;<a href="/links/365" title="">details</a>            &nbsp;&nbsp;<a href="/links/365/edit" title="">edit</a>
</li>
</ul>

If the positions for these three elements are 15,21,209,65 How can I reorder them in the groups controller?

I'm currently adding this in the HAML doc:

%script
 $(document).ready(function () {
     $('UL').sortable({
         axis: 'y',
         dropOnEmpty: false,
         handle: '.handle',
         cursor: 'crosshair',
         items: 'li',
         opacity: 0.4,
         scroll: true,
         update: function () {
             $.ajax({
                 url: '/links/sort',
                 type: 'post',
                 data: $('#links').sortable('serialize'),
                 dataType: 'script',
                 complete: function (request) {
                     $('#links').effect('highlight');
                 }
             });
         }
     });
 });

and was planning to add something like this to the groups controller:

def sort
  @links = Group.find(:id).links
  @links.each do |link|
    link.position = params['link'].index(link.id.to_s) + 1
  book.save
  render :null
end

but not sure if this is the right approach?

Nenhuma solução correta

Outras dicas

Let's simplify the case to assume the current_user who'll sort this list is the only man who can save the order to db.

In this case you need one extra field in Link to save the changed sequence. Let's name it seq. It will be the major method to order the links.

Then, for jQuery part, I find toArray would be simple to use, instead of current 'serialize', with others untouched.

The jQuery ajax will post to sort method in controller. And the params[:links](I'm not sure about the key, just assume it's links) will be an array of ids.

# GroupsController
def sort
  ids = params[:links]
  ids.each_with_index do |id, index|
    link = Link.find(id)
    link.seq = index
    link.save
  end
end

# Then always ship links with order of seq
def show
  group = Group.find(params[:id])
  @links = group.links.order('seq ASC')
end

Just a note that my implementation sort method is not efficient that there are multiple queries executed. A better approach would be construct custom sQL to update in a batch. This is just a quick answer to present the idea.

Please have a try with this.

In the controller to show the list ul/li

@links = Group.find(:id).links.order('position')

In the HAML

= text_field_tag :id_list, @links.map{|link| link.id.to_s}.join(',')
=#YOUR rails code to populate the li goes here

In the Javascript

$(document).ready(function(){
  $('UL').sortable({
     axis: 'y',
     dropOnEmpty: false,
     handle: '.handle',
     cursor: 'crosshair',
     items: 'li',
     opacity: 0.4,
     scroll: true,
     beforeStop: function(event, ui){
       // get the id_list of the li separated by ','
       var id_list = "li".map(function(i, n) {
                       return $(n).attr('id');
                       }).get().join(",");

       if(id_list != $('#id_list').val()){
           $.post('/links/sort', 
             {id_list: id_list},
             function(res){
               // YOUR CODE GOES HERE. 
            });
       }
   });
});

In the sort action

def sort
  list_id_arr = params['id_list'].split(',')
  list_id_arr.each_with_index.map{|list_id, i| Link.find(list_id).update_attribute(:position, i+1)}
  render :text => 'true'
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top