简体   繁体   中英

AJAX call being handled but not rendering in rails view

In a rails 4.2 application, a div lists and renders existing cartitems

  <div id='yield_cartitem'>
    <%= render 'cartitems' %>
  </div>

and the same page has forms (one per listed products).

<%= form_for(@cartitem, remote: true, id: 'data-js-cartitem-form', data: {'js-cartitem-form' => true}) do |f| %>

  <%= f.hidden_field :product_id, value: product.id %>
  <%= f.hidden_field :price, value: product.price %>
  <%= f.submit 'Add to cart' %>
<% end %>

The javascript for the class defines via jQuery

$(document).on('turbolinks:load', function() {
  $('[data-js-cartitem-form]').on("ajax:success", function(event, data, status, xhr){
    var cartitem = $(xhr.responseText).hide();
    $('#cartitems').append(cartitem);
    cartitem.fadeIn(1000);
    document.getElementById('data-js-cartitem-form').reset();
  });

  $('#cartitems').on("ajax:success", function(event, data, status, xhr){
    var cartitem_id = xhr.responseJSON.id;
    $('[data-js-cartitem-id=' + cartitem + ']').hide();
  });    
});

The controller create action runs as by design with the following rendering instruction.

  if @cartitem.save
    render partial: 'cartitem', locals: {cartitem: @cartitem}
  end

_cartitems.html.erb has

<div id=cartitems class='tableize'>
  <%= render partial: 'cartitem', collection: @cartitems %>
</div>

while _cartitem.html.erb defines

<div class='row' data-js-cartitem-id=<%= cartitem.id %>>
 <%= cartitem.quantity %>
 <%= cartitem.um %>
 <%= cartitem.product.try(:name) %>
 <%= cartitem.price %>
</div>

_cartitem.js.erb calls $("div#yield_cartitem").html('< %=j (render 'cartitem') %>');

The XHR response payload is returning $("div#yield_cartitem").html('< %=j (render 'cartitem') %>'); but the div is not refreshing with the newly created cartitem.

Where has this gone wrong?

update

Trying to simplify matters by changing the _cartitems.js.erb to an alert:

alert("<%= cartitem.quantity %> <%=j cartitem.um %> <%=j cartitem.product.try(:name) %> <%= number_to_currency(cartitem.price) %> Added")

The alert does effectively render.

alert("1.0 kg Prod 1,89 € Added")

I may be wrong but I noticed that in controller you are passing locals to cartitem html partial but not in js.erb file. So do that in cartitem.js.erb file:

$("div#yield_cartitem").html('< %=j (render 'cartitem', cartitem: cartitem) %>');

it's really hard to debug js.erb files but it's possible. Try to use gem pry to see context and variables inside the partial.

$("div#yield_cartitem").html('<%= binding.pry; j(render 'cartitem', cartitem: cartitem) %>');

$("div#yield_cartitem").html('<%=j (render 'cartitem') %>') this will replace the contents of #yield_cartitem

instead use $('#cartitems').append('<%= j render('cartitem', cartitem: @cartitem) %>')

and update this function

$('[data-js-cartitem-form]').on("ajax:success", function(event, data, status, xhr){
  // var cartitem = $(xhr.responseText).hide();
  // $('#cartitems').append(cartitem);
  // cartitem.fadeIn(1000);
  document.getElementById('data-js-cartitem-form').reset();
});

Additionally rename _cartitem.js.erb to create.js.erb then create will render it automatically

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