snapjay / ngCart

Really simple shopping cart for AngularJS
http://ngcart.snapjay.com
380 stars 236 forks source link

Products with options #8

Open humbkr opened 9 years ago

humbkr commented 9 years ago

How would you manage products with options?

For example I have a t-shirt item with a size option. I should be able to add to my cart this product in 2 different sizes, which is currently impossible as the item ID is the same.

seopolis commented 9 years ago

I have the same problem. It should be great if we could add options for the products, since this is a very common scenario.

I'm newbie at AngularJS, but the ngCart is doing already the 90% of what I want to achieve, so I will try to find a solution for this.

humbkr commented 9 years ago

As the unicity of a product is based on the "id" property, a workaround is to modify the product id string when an option is selected, so the id is unique for a product with a given option.

But this is not a good solution in my opinion.

seopolis commented 9 years ago

Nah this is not a clean solution and it can add too much products.

Here is a real world scenario. Let's say I have to create a menu for a restaurant, and for the main dishes customers have the option to chose their side dish from a wide variety (rice, potatoes, grilled veggies etc.) So in this kind of situation is not logical to create a new product for each combination, but instead to be able to provide a checkbox with options for the customer to select.

The same applies for many kind of products.

snapjay commented 9 years ago

Yes I agree - this as a very reasonable request - I'll consider a way to solution for this.

Mr-Chilly commented 9 years ago

Has there been any movement with this? I would LOVE to see this implemented

amejiarosario commented 9 years ago

A possible workaround is using the data option from the ngcart-addtocart directive.

<ngcart-addtocart id="{{ item.id }}" name="{{ item.name }}" price="{{ item.price }}" quantity="1" quantity-max="30" data="item"></ngcart-addtocart>

Instead of passing the item object as data, Product's option can be passed there.

mastersoftwaresolutions commented 8 years ago

Guys, any updates here. This is very critical feature. I need to add two same products bit with different sizes options like L, XL, S , M to cart but its increasing quantity every-time. Please provide any patch if someone has tried or done this?.

linkblade0 commented 8 years ago

A way I used to work around it is by using ng-options... `

```
Add to Cart
```

` I have the sizes listed in an options object in my service. Which when they select the option under the item in question and hit add to cart is takes the option I selected and adds it successfully to the cart.

anthony9981 commented 8 years ago

Here is my solution: In product.html


Size: 
                                    <select ng-model="productoption" name="size">
                                       <option ng-repeat="attribute in product.attributes" value="{{attribute.attribute_value}}">{{attribute.attribute_value}}</option>
                                    </select>

                                    <ngcart-addtocart id="{{ product.id }}" name="{{ product.name + productsize }}" price="{{ product.price }}" option="{{productoption}}" quantity="1" quantity-max="30" data="product"></ngcart-addtocart></p>

In summary.html or cart.html add

{{ item.getOption() }}

after item.getName()

In ngCart.js change

this.addItem = function (id, name, price, quantity, data) {

            var inCart = this.getItemById(id);

            if (typeof inCart === 'object'){
                //Update quantity of an item if it's already in the cart
                inCart.setQuantity(quantity, false);
            } else {
                var newItem = new ngCartItem(id, name, price, quantity, data);
                this.$cart.items.push(newItem);
                $rootScope.$broadcast('ngCart:itemAdded', newItem);
            }

            $rootScope.$broadcast('ngCart:change', {});
        };

to

this.addItem = function (id, name, price, quantity, data, option) {

            var inCart = this.getItemByIdOption(id, option);

            if (typeof inCart === 'object'){
                //Update quantity of an item if it's already in the cart
                inCart.setQuantity(quantity, false);
            } else {
                var newItem = new ngCartItem(id, name, price, quantity, data, option);
                this.$cart.items.push(newItem);
                $rootScope.$broadcast('ngCart:itemAdded', newItem);
            }

            $rootScope.$broadcast('ngCart:change', {});
        };
        this.getItemByIdOption = function (itemId, option){
            var items = this.getCart().items;
            var build = false;

            angular.forEach(items, function (item) {
                if  (item.getId() === itemId && item.getOption() == option) {
                    build = item;
                }
            });
            return build;
        }

find

angular.forEach(storedCart.items, function (item) {
                _self.$cart.items.push(new ngCartItem(item._id,  item._name, item._price, item._quantity, item._data));
            });

change to

angular.forEach(storedCart.items, function (item) {
                _self.$cart.items.push(new ngCartItem(item._id,  item._name, item._price, item._quantity, item._data, item._option));
            });

change

var item = function (id, name, price, quantity, data, option) {
            this.setId(id);
            this.setName(name);
            this.setPrice(price);
            this.setQuantity(quantity);
            this.setData(data);
        };

to

var item = function (id, name, price, quantity, data, option) {
            this.setId(id);
            this.setName(name);
            this.setPrice(price);
            this.setQuantity(quantity);
            this.setData(data);
            this.setOption(option);
        };
        item.prototype.setOption = function(option){
            if (option) this._option = option;
        }
        item.prototype.getOption = function(){
            return this._option;
        }

change

item.prototype.toObject = function() {
            return {
                id: this.getId(),
                name: this.getName(),
                price: this.getPrice(),
                quantity: this.getQuantity(),
                data: this.getData(),
                option: this.getOption(),
                total: this.getTotal()
            }
        };

to

item.prototype.toObject = function() {
            return {
                id: this.getId(),
                name: this.getName(),
                price: this.getPrice(),
                quantity: this.getQuantity(),
                data: this.getData(),
                total: this.getTotal()
            }
        };

change

.directive('ngcartAddtocart', ['ngCart', function(ngCart){
        return {
            restrict : 'E',
            controller : 'CartController',
            scope: {
                id:'@',
                name:'@',
                quantity:'@',
                quantityMax:'@',
                price:'@',
                data:'='
            },

to

.directive('ngcartAddtocart', ['ngCart', function(ngCart){
        return {
            restrict : 'E',
            controller : 'CartController',
            scope: {
                id:'@',
                name:'@',
                quantity:'@',
                option: '@',
                quantityMax:'@',
                price:'@',
                data:'='
            },

find ALL

ngCart.getItemById(attrs.id)

replace with

ngCart.getItemByIdOption(attrs.id, attrs.option)

I thing this help.