4
votes

I've been trying all day long to include this liquid code inside javascript with no luck so far..

I'm simply trying to update a div with the cart data to show the image and name, this is what I've got.

$('.openCart').click(function(e)
{          
    $.ajax({
        type: 'POST',
        url: '/cart/add.js',
        data: data,
        dataType: 'json',
        success: function()
        {
          {% capture content %}{% include 'addItemToCartDetails' %}{% endcapture %}
          var content = {{ content | json }};
          $("._second").html(content);
        }
    });
 });

Overall the following code doesn't work(simply because of the for loop, and I have no clue how to get around this..): If I remove the for loop then the code retrieves the divs and everything, besides the item data since the loop isn't working.

This is the addItemToCartDetails.liquid,

{% for item in cart.items %}

    <div class="_second_1">
      <a href="{{ item.url | widivin: collections.all }}" class="cart-image">
        <img width="320" src="{{ item | img_url: '700x700' }}" alt="{{ item.title | escape }}">
      </a>
    </div>

    <div class="_second_2"><h3>Product Name</h3>{{ item.product.title }}</div>

    <div class="_second_3"><h3>Remove Product</h3><span class="clearCart">Remove</span></div>

    <div class="_second_4"><h3>Quantity</h3><input class="quantity" type="input" name="updates[]" id="updates_{{ item.id }}" value="{{ item.quantity }}" min="0" data-id="{{ item.id }}" title="If you'd like another subscription please checkout separately" alt="If you'd like another subscription please checkout separately" disabled></div>

    <div class="_second_5">
      <h3>Total Price</h3>

      <div class="totalDetails">Total: {{ item.line_price | plus: 0 | money }} / month</div>

    </div>

    <div class="_third">
      <input type="submit" name="checkout" value="PROCEED TO CHECKOUT">
    </div>

{% endfor %}
2
In the JavaScript code, remove the trailing }jrbedard
@jrbedard sorry, I forgot to fix that, the live site is already fixed but that wasn't the problem though, issue still maintains. :/iBrazilian2
Did you try passing the variable {% include 'addItemToCartDetails', items: cart.items %} then the for loop in the other file {% for item in items %} jrbedard
To answer the question you asked, is your openCart click function in a snippet or in an asset file? However, I have a feeling that what you're trying to do is the wrong approach - could you clarify exactly what you're trying to do? If you're trying to update the DOM after a product gets added to show the most recently added product, there are much better ways to approach the problem.Dave B

2 Answers

5
votes

You are trying to use Liquid when you should be using Javascript

All of the Liquid processing happens on the backend to construct an HTML file that gets passed to the browser. Once the HTML page has been passed to the user's browser, Javascript can be used to manipulate the document and make this appear/disappear/change.

Practically, this means that your {% for item in cart.items %} in addItemToCartDetails.liquid will be rendered once, before page load, and never again afterwards. No matter how many items are added to the cart, the results of that snippet will only ever be current as of page load.

You should be using the Javascript variables instead

Shopify passes the line item object representing the most recently-added product to your success callback function. Your code should look something like this:

$('.openCart').click(function(e)
{          
    $.ajax({
        type: 'POST',
        url: '/cart/add.js',
        data: data,
        dataType: 'json',
        success: function(line_item)
        {
          var content = '<h3>You added a ' + line_item.title + '!</h3>' +
                        '<p> We appreciate that you want to give us ' + Shopify.formatMoney(line_item.line_price, {{ shop.money_format }}) + '!</p>' + 
                        '<p>That is very nice of you!  Cheers!</p>';
          // Note: Not every theme has a Shopify.formatMoney function.  If you are inside an asset file, you won't have access to {{ shop.money_format }} - you'll have to save that to a global javascript variable in your theme.liquid and then reference that javascript variable in its place instead.
          $("._second").html(content);
        }
    });
 });

If you're curious about what all you can access in the response object, add a console.log(line_item) to the beginning of your success function to print the object to your browser's console. (In most browsers you can right-click any element on the page and select 'Inspect Element' to bring up your developer tools. There should be a tab called 'Console' where the logs get printed to, and once your information is there you should be able to click on the object to expand its contents.)

0
votes

In your first snippet, pass cart.items as the variable items to the template:

{% include 'addItemToCartDetails', items: cart.items %}

In the file addItemToCartDetails.liquid template, modify the for loop statement accordingly:

{% for item in items %}