David David - 6 months ago 9
jQuery Question

Why is jQuery .html generating an extra element before replacing the original element in Rails?

I'm trying to update the cart status when a product is added to the cart.

When I click the "Add to cart" button, it runs:

$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text') %>")


This strangely generates a new DOM element and then starts updating that new element, instead of replacing the contents of the original element. See the problem in action here:

https://gyazo.com/f3781639b0c8d4008bb38428f6c783bd

Here's my current code:

https://github.com/davidalejandroaguilar/simple-cart

EDIT:

Application Layout

<!DOCTYPE html>
<html>
<head>
<title>Workspace</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>

<% flash.each do |key,value| %>
<%= content_tag :div, value, class: "alert alert-#{key}" %>
<% end %>

<p class="cart-text">
<%= render 'layouts/cart_text' %>
</p>

<%= yield %>

</body>
</html>


Create.js.erb in views/order_items

$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text') %>")


OrderItems Controller

class OrderItemsController < ApplicationController
def create
@order = current_order
@order_item = @order.order_items.build(order_item_params)
@order.save
session[:order_id] = @order.id
end

def update
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.update_attributes(order_item_params)
redirect_to :back
end

def destroy
@order = current_order
@order_item = @order.order_items.find(params[:id])
@order_item.destroy
redirect_to :back
end

private

def order_item_params
params.require(:order_item).permit(:product_id, :quantity)
end

end

Answer

You can't nest <p> tags (https://www.w3.org/TR/html401/struct/text.html#h-9.3.1). It creates an invalid DOM. You can look it up in your browser's inspector.

Removing the <p> from layouts/cart_text should fix the problem.