iBrazilian2
iBrazilian2

Reputation: 2293

How to include liquid inside javascript?

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 %}

Upvotes: 4

Views: 21636

Answers (3)

Ulysses Lanugon
Ulysses Lanugon

Reputation: 56

In your case, you can put this {% capture content %}{% include 'addItemToCartDetails' %}{% endcapture %} in your liquid code somewhere in your HTML probably hidden and append it to the element where you want it to appear like so.

success: function()
    {          
      var content = $("#addItemToCartDetails-wrapper").html();
      $("._second").html(content);
    }

Something like that. Hope that helps!

Upvotes: 0

Dave B
Dave B

Reputation: 3248

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.)

Upvotes: 6

jrbedard
jrbedard

Reputation: 3730

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 %}

Upvotes: 0

Related Questions