Giter Site home page Giter Site logo

discolabs / cartjs Goto Github PK

View Code? Open in Web Editor NEW
476.0 476.0 84.0 3.46 MB

A Javascript library to power cart management for Shopify themes.

Home Page: https://cartjs.org

License: MIT License

CoffeeScript 88.02% JavaScript 7.86% HTML 4.12%
rivets shopify shopify-theme

cartjs's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cartjs's Issues

Being able to use Rivets.js?

Hi again (sorry for all the problems :'(),

I'm trying to integrate myself shipping estimator until it is done natively. I'm trying to use native Rivets code for that. But I fail to make Rivets work.

In my code, I've reproduce a small use case (my code is included AFTER CartJS + Rivets):

<table id="my-table">
        <tr rv-each-row="rows">
          <td rv-text="row.name"></td>
        </tr>
      </table>

Then in my JS code:

$table = $("#my-table");

  var state = {};
  state.rows = [];

  rivets.bind($table, state);

  state.rows.push({name: "bar"});
  state.rows.push({name: "bar"});
  state.rows.push({name: "bar"});

I expect it to display bar three times. However that's not the case. It displays nothing.

Interestingly, if I replace "rivets-cart.min.js" by "rivets+sigthlass 0.8.1" (found in Rivets website), then "cart.min.js"... the pure Rivets part work correctly (so it displays three bars)... but in turn the CartJS displayed items does not work.

What am I doing wrong?

Thansk!

Dropping Compatibility Mode

Now that Shopify's theme requirements have been changed to require only IE9+, I'd like to drop the compatibility additions made in #22.

@bakura10 - wanted to get your thoughts on this as you were the main driving force behind the IE8 compatibility.

Bug when displaying items

Hi :),

I think I'm having a major bug here. Also, I have a strange result: interpolation works, but using HTML binding never works here (or in strange circumstances).

If I take the example in your home page, the following code:

<tr rv-each-item="cart.items">
            <td>
              <strong rv-text="item.vendor"></strong>
              <ul rv-hide="item.propertyArray | empty">
                <li rv-each-property="item.propertyArray < properties" rv-text="property.value"></li>
              </ul>
            </td>
          </tr>

This displays the vendor. However, if I remove the ul:

<tr rv-each-item="cart.items">
            <td>
              <strong rv-text="item.vendor"></strong>
            </td>
          </tr>

The vendor does not appear anymore. In my full example, I simply have nothign that appears:

<div class="cart--desktop" data-cart-view="data-cart-view" rv-show="cart.item_count | gt 0">
    <div class="table__scroll">
      <table>
        <thead>
          <tr>
            <th>{{ 'cart.items.product' | t }}</th>
            <th>{{ 'cart.items.price' | t }}</th>
            <th>{{ 'cart.items.quantity' | t }}</th>
            <th>{{ 'cart.items.subtotal' | t }}</th>
            <th></th>
          </tr>
        </thead>

        <tbody>
          <tr rv-each-item="cart.items">
            <td class="cart-item__product">
              <a rv-href="item.url" oncanplay="cart-item__link">
                <img class="cart-item__image" rv-src="item.image | productImageSize small">
              </a>

              <div class="cart-item__info">
                <span class="cart-item__brand" rv-text="item.vendor"></span>
                <span class="cart-item__title" rv-text="item.product_title"></span>
                <span class="cart-item__variant" rv-text="item.variant_title"></span>
              </div>
            </td>

            <td class="cart-item__price" rv-html="item.price | money"></td>

            <td class="cart-item__quantity">
              {item.quantity}

              <div class="quantity__actions">
                <a href="#" rv-data-cart-update="index | plus 1" rv-data-cart-quantity="item.quantity | minus 1">
                  <i class="icon-minus"></i>
                </a>
                <a href="#" rv-data-cart-update="index | plus 1" rv-data-cart-quantity="item.quantity | plus 1">
                  <i class="icon-plus"></i>
                </a>
              </div>
            </td>

            <td class="cart-item__subtotal"></td>

            <td class="cart-item__remove">
              <a href="#" rv-data-cart-remove="index | plus 1">
                <i class="icon-cross"></i>
              </a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

Replacing everything by interpolation (using {item.vendor} for instance, properly works.

In all cases, the Currency conversion never works. It properly changes the currency symbol, but always return a 0 value.

Thanks :)

Add weight support

Hi !

I've had a customer that was trying to output the weight of the cart, however it seems CartJS does not have any weight formatter to do that.

Bye!

Expose more data on product

Hi,

One of our customer is using our theme. However, they'd like to be able to use display the product's tags in the cart. But it seems that CartJS do not expose those properties.

Would it be possible to expose the full "product" object (currently, only a subset with "product_id", "product_description", "product_title" and "product_type" are exposed, it would be nice to have a "product" hash with all the properties).

Thanks!

Format money without ".00"?

Hi there,

Is it possible to adjust the formatMoney filter to display item price without without the decimal and cents? For example, just like what this Liquid filter would output:

Liquid

${{ product.price | money_without_currency | remove: '.00' }}

Result

$140

Thanks!

Sites using Cart.js

People are doing some really great things with Cart.js, so it would be great to showcase their sites on cartjs.org. This issue can serve as a way for anyone using Cart.js to let us know they'd like to be considered for inclusion on the site.

Currently, I know of (and have received permission to list):

Currency conversion not working

Hi :),

First of all thank you for the library, it looks nice!

I've been trying it and I'm having an issue with the currency converison that Shopify recommends (https://docs.shopify.com/manual/configuration/store-customization/currencies-and-translations/currencies/how-to-show-multiple-currencies).

It works perfectly for any span with class money, but for things rendered by CartJS those are not converted. I'm suspected that the issue is that when the Shopify script run to convert elements, Rivets has not yet rendered its stuff, hence doesn ot converting the values.

Did you have the occasion to play with that?

Thansk!

CartJS does not remove the right element

Hi again,

Sorry for pinging you again. I'm still trying to integrate animation. So here is my try: when clicking on the element, I first toggle the element using jQuery, then I remove the item using CartJS:

removeProduct: function(event) {
      var element = $(event.currentTarget),
          item = element.closest('.mini-cart__item'),
          variantToRemove = item.attr('data-variant');

      item.toggle(150, function() {
        CartJS.updateItemById(variantToRemove, 0);
      });

      return false;
    }

What happen is the following:

jQuery performs its animation, and set the element as display: none. Then, CartJS remove the element. But it seems that because the lement is hidden, binding does not work correctly, and instead of removing the first one that was hidden, it actually removes the first one and then... add all the classes that was on the first element (display: none), and apply it to the second element (hence making it invisisible).

I'm not sure if this is clear, but the simplest is to try it to understand the issue :).

Issue when product does not have image

Hi,

One of our customer just reported an issue: if a product does not have any image, the productImageSize helper fails, and hence nothing is rendered. This is inconsistent with the default Shopify behaviour where it uses their placeholder image instead.

CartJS.updateItem quantity issue

If a quantity isn't provided to updateItem (it's undefined), I guess the quantity should stay as is.

Currently, it's set to 1.

removeItemById does not exist

Hi :),

It seems that the method "removeItemById" is not defined. Actually, if I oepn the inspector even in your demo page, CartJS.removeItemById is undefined method.

Possible to combine with server-side?

Hi,

We are on the verge of releasing our second theme, but during the last step of validation, we were asked that the theme sold on Theme Store must be "usable" without JavaScript.

By usable they mean: you must be able to go to the homepage, selecting a product, adding it to the cart, and going to checkout.

Obviously, the issue is that because the cart is rendered client-side, I had to duplicate all my code, put it inside a "noscript" tag, and display it. This is a bit annoying as I have duplicated code.

I'm not sure if this is possible, but is there any way to actually render using Liquid server side, adding the various attribute, but still being able to take advantage of JS binding? I've tried it but unfortunately I couldn't find any way of doing it :(.

Thanks!

Using cartjs on a custom site?

First off, cartjs looks incredibly helpful for creating ajax carts with Shopify. Keep up the great work!

I'd like to use it on my custom bootstrap site, but am not sure how to initialize it properly.

In the cartjs documentation (which is great by the way) it says under configuration to call CartJS.init() and pass a liquid cart object as JSON. As I'm not using liquid, how can I create a liquid-cart-like JSON object and pass it to cartjs?

The only other related documentation I've found so far that might help is about Adding to cart from a remote website.

Only working on Product and Home page

Hi - I have been trying to implement cart.js on my shop, and it is looking great so far. Thanks!

Let's say I am trying to generate a mini cart that sits in the header, and I have the following in my theme.liquid file:

<aside id="cart-drawer" data-cart-view="data-cart-view">   
  <!-- FOR EACH ITEM IN CART -->
  <div class="cart-drawer-item" rv-each-item="cart.items">
    <div class="cart-drawer-item-image"><a rv-href="item.url" href=""><img rv-src="item.image | productImageSize 'small'" src=""/></a></div>
    <div class="cart-drawer-title-price"> 
      <div class="cart-drawer-item-title" rv-text="item.title"></div>
      <div class="cart-drawer-item-price" rv-html="item.line_price | money Currency.currentCurrency">        </div>
    </div>
  </div>
  <!-- END FOR EACH ITEM IN CART -->         
</aside>

This works perfectly on the product.liquid and index.liquid pages, but for some reason it doesn't seem to be pulling anything on the cart.liquid and collection.liquid pages. It's confusing me: As it's part of theme.liquid, shouldn't it either work on every page or not work at all? Do you have any ideas why this might be? Thanks again!

IE8/9 issue with console

Hi :),

After a lot of debugging, I still had issue with CartJS not working on IE8/9. The strange thing is that as soon as I opened the developer tools of IE... boom, CartJS was working. I was a bit surprised to say the least, and it appears that this is due to this bug: http://stackoverflow.com/questions/7742781/why-javascript-only-works-after-opening-developer-tools-in-ie-once

I've removed any reference to console.log in my own code, but the last two occurrences are... in CartJS. while it's wrapped and checked existence of console, it seems that the sole existence of console.log in the source code make everything crash.

I already had such crazy issues with IE8, where a variable called "case" would make everything crash, even if it was situated in a code that wasn't called.

I'd therefore suggest that you simply remove any occurrence of that in the production code. Alternatively, adding this small code make the problem disappears completely:

if(!window.console) {
        console={};
        console.log = function(){};
      }

Crazy IE....

Money Formatting not working

I cannot seem to get the money formatting to work with DOM binding. I copied the code exactly as it appears in the demo and cannot get a formatted money string. It does render the correct money value but with no decimals or formatting.

<div data-cart-view="data-cart-view">
  <p rv-text="cart.total_price | money"></p>
</div>

updateItemByID using Change.js

The Shopify API allows addition of an ID via Update.js, we were writing the following for the API before we discovered Cartjs (which is great, by the way!).
The Update function here uses Change.js (which will not add a new variant to cart, only modify a variant that is already in the cart) doesn't match that of the Shopify Update.js, so for the sake of clarity, I would suggest adjusting to use Update.js, rename it to changeItemById or just document the fact this will only Change exiting cart items and not add new ones.

Use case:
A client has 4 variants, of which only 1 may be in the cart at one time (they are delivery options/enhancements). I appreciate this is probably a rare occurrence.

Because the updateItemById function uses Change.js the solution with cartjs is to remove all, then add the applicable variant:

CartJS.updateItemById(1118014272, 0); CartJS.updateItemById(1118014280, 0); CartJS.updateItemById(1118014284, 0); CartJS.updateItemById(1118014276, 0); CartJS.addItem(1118014284, 1);

If Cartjs were to use update.js this could be simplified to:

CartJS.updateItemById(1118014272, 0); CartJS.updateItemById(1118014280, 0); CartJS.updateItemById(1118014284, 1); CartJS.updateItemById(1118014276, 0);

It could be further reduced of course by interrogating the cart for the existence of the 'wrong' variant and removing that one, and adding the 'correct' one - but this is so much more straightforward - one of the appeals of Cartjs!

Not sure how much of an impact one less call makes, but thought I'd take the time to mention it. For me it was more the assumption that updateItem matched Update.js functionality. Not likely to be an issue for those that aren't already familiar with the Shopify AJAX API.

Obviously also not a problem for updateItem(); as it refers to cart lines not variant IDs.

Thanks,
Oli

RV Templating: Conditionally show text based on string contents?

Hi there,

Firstly, just wanted to say thanks so much for putting this great library together and I'm really looking forward to future roll-outs of docs and enhancements!

Here's a question for you:

Essentially, I've broken out how I display product title and it's variants in the cart for UX purposes and would like to not show variants that contain 'Default Title', while testing for variants that contain 'Giftwrap' to show specific messaging…if that makes sense.

Regarding the giftwrap logic, this code block is absolutely bloated:

<div rv-show="item.variant_options.1 | eq 'Wrap'">
  <span class="meta">Giftwrap added</span>
</div>
<div rv-show="item.variant_options.0 | eq 'Wrap'">
  <span class="meta">Giftwrap added</span>
</div>

And, conversely, I'm at an impasse with not showing a variant if it equates to 'Default Title' because I haven't been able to find any evaluators that work in Rivets to test for "does not equal" or that simply state 'else'.

For example, you'd think this would work:

<div rv-show="item.variant_options.1 | != 'Default Title">
    <span class="var" rv-text="item.variant_options.0"></span>
</div>

All that said, I know Rivets.js discourages evaluating logic inside the binding declarations, so I'm curious if there's a better way to go about these 2 tests further upstream. If so, do you have some pointers on how?

I get by, but I'm no javascript ninja, so thanks so much for you help!
L

What does the `tags` property on `cart.item` object refer to?

Working on our current project, I noticed on inspecting CartJS.cart.items in the console that each item had a tags property - my first assumption was that this was pulling in the line_item's product's tags, but it was empty, even though the product does have tags. I know that a line_item only has limited product/variant properties bundled by Shopify, but I couldn't tell if I was misunderstanding the use of this property, or if it was a bug.

Shipping Rates estimator

Hi :),

It would be nice to have a native support for shipping rates around the Shopify shipping rates API.

Thanks!

Add basic automated tests for CI.

Would be nice to get some basic coverage going for 0.4, before expanding it in 0.5 and moving to plugins for 0.6.

  • Decide on JS test framework to use;
  • Create a few basic, easy tests (eg formatter tests);
  • Integrate with TravisCI.

Support for more events.

Currently, only cart.requestStarted and cart.requestComplete are supported. Want to make this a little better, like cart.itemAdded, cart.itemUpdated, cart.attributeUpdated et cetera.

Automatically extracting data from form

Hi,

When developing a theme, you cannot know in advance which properties a product have. As a consequence, this:

CartJS.addItem(12345678, 3, {
        "size": "XL"
    });

Is not possible because we cannot know that it will have the "size" property. The problem is that jQuery does not have any nice built-in function to extract the data from a form in a way that is easily consumed by CartJS. Here is the boilerplate code I've been doing:

var formData = this.serializeForm(this.element.find('.product__form'));
CartJS.addItem(formData['id'], formData['quantity'], formData['properties'], {});

where serializeForm is as follow:

Plugin.prototype.serializeForm = function(form) {
    var hash = {};

    function stringKey(key, value) {
      var beginBracket = key.lastIndexOf('[');
      if (beginBracket == -1) {
        var hash = {};
        hash[key] = value;
        return hash;
      }
      var newKey = key.substr(0, beginBracket),
        newValue = {};
      newValue[key.substring(beginBracket + 1, key.length - 1)] = value;

      return stringKey(newKey, newValue);
    }

    var els = form.find(':input').get();

    $.each(els, function() {
      if (this.name && !this.disabled && (this.checked || /select|textarea/i.test(this.nodeName) || /hidden|text|search|tel|url|email|password|datetime|date|month|week|time|datetime-local|number|range|color/i.test(this.type))) {
        var val = $(this).val();
        $.extend(true, hash, stringKey(this.name, val));
      }
    });

    return hash;
  },

I'm not the author of this complicated code, but basically, it allows to parse the keys (such as "properties[foo]") and returns something like:

{
   "id": 123,
   "quantity": 1,
   "properties": {
     "size": "XL",
     "other": "foo"
   }
}

This boilerplate code is required all the time in themes. Therefore, it would be nice to have a "addItemFromForm" method that would accept any jQuery object representing a form, and do this logic internally.

I'd be happy to contribute for that, I just want to be sure you don't have a better idea for that first ;).

Bye!

Add to cart Bug

I have a very simple button
<button data-cart-add="{{ product.id }}" data-cart-quantity="1">{{ product.title }}</button>
which tries to add an item to the cart but I get an error:
Cannot find variant
The product has no variants so i am a little confused why that would be the case.
Ever had this happen before?

Cart.js v0.3.5

IE8/9 support

Hi,

I've tried this on IE8 and 9 but it does not seem to work. Do we need special polyfills? I'm not using the dist CartJS, but rather CartJS + Rivets + Sightglass separately.

Thanks a lot ;)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.