1

I'm trying to implement a table with the option to expand and collapse each row using ajax.

I'm using link_to :remote => true and works fine, the problem is when I click multiple times, all the calls stay alive. I would like to know how to track those calls and discard them if the user collapsed or if he requested a new one. Since I'm not making the $.ajax call my self I don't know how to do it.

Here is my code.

index.html.haml:

%tr{ :class => 'cmp_row'}
          %td
            = link_to "+", user_company_details_path(company_id), :remote => true , :method => :post, :cache => false, :class => "cmp_exp_link", :id => "#{company_id}

application.js.erb:

$('.cmp_exp_link').click(function (e) {
  var cmp_id = e.target.id
  if($(this).text() === "+"){
    $("<tr id='details_row_"+cmp_id+"'><td colspan = 11 id='details_cell_"+cmp_id+"' style='text-align:center' > </td> </tr>").insertAfter($(this).closest(".cmp_row"));
    $("#details_cell_"+cmp_id).html("<img src='/assets/colorbox/loading.gif' >")
    $(this).text("-");

  }else{
    $(this).text("+");
    $("#details_row_"+cmp_id).remove();
    return false;
  }
});

company_details.js.erb

// remove the loading icon
$("#details_cell_<%= params[:cmp_id] %>").html("");

// load partial
$("#details_cell_<%= params[:cmp_id] %>").html("<%= escape_javascript(render(:partial => "company_details", :locals => { :results => @results })) %>");

user_controller.rb

def company_details

    @results = @data
    respond_with(@results)

  end

Thanks a lot in advance!!

mikdiet
  • 9,859
  • 8
  • 59
  • 68
Alejandra
  • 726
  • 3
  • 9
  • 25
  • 2
    Can you try by adding a onclick handler: `if(ajax){ajax.abort();}` ? Take a look at this also http://stackoverflow.com/questions/8878115/how-to-stop-previous-ajax-call-sent-in-jquery – MrYoshiji Feb 24 '14 at 15:30
  • 1
    I don't think you actually need to worry about this: when you expand a row, you use ajax to populate it, but after that, you would just collapse and expand it normally, wouldn't you? Ie, you only ever need to do one ajax load per row: when expanding, you can see if there's anything in the the row, and if it's empty do the ajax call, if it's populated just show the contents. – Max Williams Feb 24 '14 at 15:55
  • Thanks guys for your help but on firebug I see all the calls loading, I don't want to create extra traffic that required, the table will be very long and maybe each call will retrieve a lot of records. I just want to do not have duplicated calls loading or if the user collapsed then stop the current call. – Alejandra Feb 24 '14 at 16:00
  • 1
    Thanks @MrYoshiji :) im modifying the jquery-ujs.js where the actual ajax call is made and im using the answer you pointed to. :) – Alejandra Feb 24 '14 at 17:07
  • Great, you should post your own answer on SO to give hints for the other developpers ;) And Im also interested in the resulting code – MrYoshiji Feb 24 '14 at 17:16

1 Answers1

1

As you've gathered from the comments, you can use ajax abort to cancel the current request, however, I felt compelled to write an answer


JQuery-ujs.js

I would highly recommend not changing the JQuery-ujs file (unless you plan to submit a gist to the Rails repo), primarily for compatibility purposes. It's a core component of the Rails asset pipeline, and will just a pain to keep updating to keep in line with Rails updates

Instead, I would recommend using the Ajax global settings & manually stopping previous calls:

#app/assets/javascripts/application.js
$(document).on("click", "#table_row", function() {
    $.ajax({ 
        url: $(this).attr("your-link-attr"),
        data: $(this).attr("data-something"),
        success: function(data) {
            //Returned Data
        }
    })
});

$(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);

This may or may not work, but I'd recommend it over customizing the core Rails dependencies :)

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • 1
    Yes my TL told me the same, I'm making the ajax call myself on the application.js.erb and I used the code for this question (http://stackoverflow.com/questions/18775455/ajax-prevent-multiple-request-on-click) to disable the functionality of the expand link during the call. I think your idea is more efficient in order to kill ongoing and undesired calls (when some one collapses before the call is finished) Thanks a lot for your help :) – Alejandra Feb 25 '14 at 19:14