最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I store a simple cart using localStorage? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to create a javascript cart for a prototype project I'm working on. I realise that in this situation an MVC framework like Angular/Knockout etc would be absolute perfect but I'm still learning how to use those so I can't use them for this particular project. I also realise I could maintain the cart server-side but that's not an option in this scenario.

At the moment I have a list of html products like so:

<ul id="products">
  <li data-id="1" data-name="Product 1" data-price="10.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="2" data-name="Product 2" data-price="15.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="3" data-name="Product 3" data-price="20.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
</ul>

On page load I create an empty 'cart' object in localStorage like so:

var cart = {};
cart.products = [];

localStorage.setItem('cart', JSON.stringify(cart));

I've then bound to the click event of the button element as so:

$('button').on('click', function(e) {
    var product = $(this).parent();

    var quantity = $(product).find('input[type=text]').val();

    // Ensure a valid quantity has been entered
    if (!isValidInteger(quantity) === true) {
        alert('Please enter a valid quantity');
        return;
    }

    product.id = $(product).attr('data-id');
    product.name = $(product).attr('data-name');
    product.price = $(product).attr('data-price');
    product.quantity = quantity;

    addToCart(product);
});

I've then written an addToCart() function that should take this product and try to push it into the 'products' array that's a property of 'cart':

function addToCart(product) {
    // Retrieve the cart object from local storage
    if (localStorage && localStorage.getItem('cart')) {
        var cart = JSON.parse(localStorage.getItem('cart'));            

        cart.products.push(product);

        localStorage.setItem('cart', JSON.stringify(cart));
    } 
}

This isn't working and I'm getting an error:

Uncaught TypeError: Converting circular structure to JSON

I don't understand where I'm going wrong, is anyone able to help?

Also once this is resolved, I'm a little confused as to how I'm to maintain the state of the cart. I was hoping I could store all the data in the 'cart' object in localStorage by storing the product ids, names, prices and quantities and then reflecting this in a 'cart' div within the html. If items are added/removed, I'll update the 'cart' object in local storage and then reflect the changes within the html.

Is there a simpler way to do this? I could really use some pointing in the right direction.

Once again I realise that using Angular or even maintaining the state server-side would be an optimal solution but for this project I'm only able to use jquery/javascript so I need to work within my boundaries.

Thanks!

I'm trying to create a javascript cart for a prototype project I'm working on. I realise that in this situation an MVC framework like Angular/Knockout etc would be absolute perfect but I'm still learning how to use those so I can't use them for this particular project. I also realise I could maintain the cart server-side but that's not an option in this scenario.

At the moment I have a list of html products like so:

<ul id="products">
  <li data-id="1" data-name="Product 1" data-price="10.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="2" data-name="Product 2" data-price="15.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
  <li data-id="3" data-name="Product 3" data-price="20.00">
    <input type="text" /><br />
    <button>Add to cart</button>
  </li>
</ul>

On page load I create an empty 'cart' object in localStorage like so:

var cart = {};
cart.products = [];

localStorage.setItem('cart', JSON.stringify(cart));

I've then bound to the click event of the button element as so:

$('button').on('click', function(e) {
    var product = $(this).parent();

    var quantity = $(product).find('input[type=text]').val();

    // Ensure a valid quantity has been entered
    if (!isValidInteger(quantity) === true) {
        alert('Please enter a valid quantity');
        return;
    }

    product.id = $(product).attr('data-id');
    product.name = $(product).attr('data-name');
    product.price = $(product).attr('data-price');
    product.quantity = quantity;

    addToCart(product);
});

I've then written an addToCart() function that should take this product and try to push it into the 'products' array that's a property of 'cart':

function addToCart(product) {
    // Retrieve the cart object from local storage
    if (localStorage && localStorage.getItem('cart')) {
        var cart = JSON.parse(localStorage.getItem('cart'));            

        cart.products.push(product);

        localStorage.setItem('cart', JSON.stringify(cart));
    } 
}

This isn't working and I'm getting an error:

Uncaught TypeError: Converting circular structure to JSON

I don't understand where I'm going wrong, is anyone able to help?

Also once this is resolved, I'm a little confused as to how I'm to maintain the state of the cart. I was hoping I could store all the data in the 'cart' object in localStorage by storing the product ids, names, prices and quantities and then reflecting this in a 'cart' div within the html. If items are added/removed, I'll update the 'cart' object in local storage and then reflect the changes within the html.

Is there a simpler way to do this? I could really use some pointing in the right direction.

Once again I realise that using Angular or even maintaining the state server-side would be an optimal solution but for this project I'm only able to use jquery/javascript so I need to work within my boundaries.

Thanks!

Share Improve this question asked May 8, 2014 at 23:42 sterix24sterix24 2,4006 gold badges35 silver badges52 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

You should declare a separate object for your product item.

$('button').on('click', function(e) {
    var li = $(this).parent();

    var quantity = $(li).find('input[type=text]').val();

    // Ensure a valid quantity has been entered
    if (!isValidInteger(quantity) === true) {
        alert('Please enter a valid quantity');
        return;
    }

    var product = {};
    product.id = $(li).attr('data-id');
    product.name = $(li).attr('data-name');
    product.price = $(li).attr('data-price');
    product.quantity = quantity;

    addToCart(product);
});

Rendering process of Products from Server.

function productSocket(doneFn,params){
                     $.ajax({
                           type:'GET',
                           url: "http://localhost:8080/"+params,
                           contentType: "application/json; charset=utf-8",
                           dataType: "json"
                     }).done(doneFn)
                       .fail(function(err){
           console.log("AJAX failed: " + JSON.stringify(err, null, 2));
                            });
    }

function productDoneFn(data){

  console.log("Okey done"+JSON.stringify(data));

  var productContainer=$('#productContainer');

  productContainer.empty();

  var productContent="";

  $.each(data ,function(i,e){

productContent+='<div class="col-md-4 col-sm-6">'+
                    '<div class="pr">'+
                        '<div class="pr-img-div">'+
                              '<a href="detail.html#store/public/parent/detail/'+e.id+'">'+
                                  '<img src="../fs/main/'+e.image+'" alt="" class="img-responsive">'+
                              '</a>'+
                        '</div>'+
                        '<div class="pr-text">'+
                          '<h3><a href="detail.html#store/public/parent/detail/'+e.id+'">'+e.nameEn+'</a></h3>'+
                          '<p class="price">$'+e.price+'</p>'+
                          '<p class="buttons">'+
                            '<a href="detail.html#store/public/parent/detail/'+e.id+'" class="btn btn-default">View detail</a>'+
                            '<a href="#" cartBtn pr_id='+e.id+' pr_name_en="'+e.nameEn+'" pr_price="'+e.price+'" pr_image="'+e.image+
                            '" class="btn btn-primary"><i class="fa fa-shopping-cart"></i>Add to cart</a>'+
                          '</p>'+
                        '</div>'+
                    '</div>'+
                '</div>';

  });

  productContainer.html(productContent);


}

Here is an element like button for adding an item to the Cart and appropriate attributes for saving in Web Storage like localStorage.


var productArray=[];


$(document).on('click','[cartBtn]',function(e){
  e.preventDefault();
  $(this).html('<i class="fa fa-check"></i>Added to cart');
  console.log('Item added ');
  var productJSON={"id":$(this).attr('pr_id'), "nameEn":$(this).attr('pr_name_en'), "price":$(this).attr('pr_price'), "image":$(this).attr('pr_image')};


  if(localStorage.getObj('product')!==null){
    productArray=localStorage.getObj('product');
    productArray.push(productJSON);  
    localStorage.setObj('product', productArray);  
  }
  else{
    productArray.push(productJSON);  
    localStorage.setObj('product', productArray);  
  }


});

Storage.prototype.setObj = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObj = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

After adding JSON object to Array the result is (in LocalStorage):

[{"id":"99","nameEn":"Product Name1","price":"767","image":"1462012597217.jpeg"},
{"id":"93","nameEn":"Product Name2","price":"76","image":"1461449637106.jpeg"},
{"id":"94","nameEn":"Product Name3","price":"87","image":"1461449679506.jpeg"}]

After this action you can easily send data to server as List in Java.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>