Basket: Cookies containing only 2 - 5 items

This is probably an easy solution (simple reputation +200), for those who have JavaScript skills.

Demonstration of the problem: http://shoppingcart-bthub.blogspot.com/ Just add all the items to the cart and click "Refresh" to see the problem with cookies.

Everything works correctly, except for the part of the code that processes cookies for items that are added to the shopping cart. For some reason, it contains only 2-5 items, depending on the browser:

Google Chrome - contains only 2 items (all other items in the cart disappear after page reload)

Firefox - Just 4 Elements

Safari - 4

Internet Exploer - 5

javascript demo: http://shopppingcart.googlecode.com/files/simplecart.js

The javascript link portion above that is encoded to handle cookies:

/*** data storage and retrival ****/ /* load cart from cookie */ me.load = function () { var me = this; /* initialize variables and items array */ me.items = {}; me.total = 0.00; me.quantity = 0; /* retrieve item data from cookie */ if( readCookie('simpleCart') ){ var data = unescape(readCookie('simpleCart')).split('++'); for(var x=0, xlen=data.length;x<xlen;x++){ var info = data[x].split('||'); var newItem = new CartItem(); if( newItem.parseValuesFromArray( info ) ){ newItem.checkQuantityAndPrice(); /* store the new item in the cart */ me.items[newItem.id] = newItem; } } } me.isLoaded = true; }; /* save cart to cookie */ me.save = function () { var dataString = ""; for( var item in this.items ){ dataString = dataString + "++" + this.items[item].print(); } createCookie('simpleCart', dataString.substring( 2 ), 30 ); }; 

To check the complete code in real time:

For a complete live template with all the codes, open a free blog at blogger.com and upload the XML template here to upload it to a blogger: http://www.bloggermint.com/2011/05/shopping-cart-blogger-template/ Download is in the left sidebar. Alternatively, follow the instructions on this page to get it on blogger.com

+4
source share
2 answers

In my opinion, the problem is with the cookie size limit 4K.
Your shopppingcart code tries to save all the item data in a simpleCart cookie, but when such data becomes more than 4K, the items are not saved in the cookie even if they are displayed in the basket, so when the page reloads, these items disappear.
Consider, for example, the site http://shoppingcart-bthub.blogspot.in/ and, in particular, the HTML markup for the “Sony VAIO laptop”:

 <table border="1" style="width: 660px;"> <tbody> <tr> <th class="item_thumb" id="thumb" width="45%"><img border="0" src="http://3.bp.blogspot.com/-LcQD--Bb_YE/TeDI44AmUsI/AAAAAAAACBw/K4IJZE2CpMY/s1600/sony+vaio.JPG"></th> <td> <input class="item_add" type="button" value="Add to Cart" id="s1"> </td> </tr> <tr> <th><b>Item Name</b></th> <td class="item_name">Sony VPCEE42FX 15.5" 2.30GHz 500GB VAIO Laptop</td> </tr> <tr> <th><b>Price</b></th> <td class="item_price">$610.00</td> </tr> <tr> <th><b>Description</b></th> <td class="item_Description"> The VPCEE42FX is big enough to be useful, but small enough to be portable. With 500GB of hard drive space, youll have to work hard to fill up the memory. The 15.5 HD resolution screen and AMD Mobility Radeon HD graphics card ensure that youll see crisp, fast action, even when youre watching DVDs on the DVD drive. And at under six pounds, the laptop is easy to pack up and haul with you. </td> </tr> <tr> <th><b>Available Stock</b></th> <td>2 more available</td> </tr> </tbody> </table> 

When this product is added to the basket, the simpleCart will contain the following line:

ID = C10 || = knurled% 3Cimg% 20border% 3D% 220% 22% 20src% 3D% 22http% 3A // 3.bp.blogspot.com / -LcQD - Bb_YE / TeDI44AmUsI / AAAAAAAACBw / K4IJZE2CpMY / S1600 / sony + v% 22 % 3E% 0A name || = Sony% 20VPCEE42FX% 2015.5% 22% 202.30GHz% 20500GB% 20VAIO% 20Laptop || price = 610 || description = Value% 20VPCEE42FX% 20is% 20big% 20enough% 20to% 20be% 20useful% 2C% 20but% 20small% 20enough% 20to% 20be% 20% 0Aportable. % 20With% 20500GB% 20of% 20hard% 20drive% 20space% 2C% 20youll% 20have% 20to% 20work% 20hard% 20to% 20% 0Afill% 20up% 20the% 20memory. % 20the% 2015.5% 20HD% 20resolution% 20screen% 20and% 20AMD% 20Mobility% 20% 0ARadeon% 20HD% 20graphics% 20card% 20ensure% 20that% 20youll% 20see% 20crisp% 2C% 20fast% 20action% 2C% 20even% 20 % 0Awhen% 20youre% 20watching% 20DVDs% 20on% 20the% 20DVD% 20drive. % 20 And% 20at% 20under% 20six% 20pounds% 2C% 20the% 20% 0Alaptop% 20is% 20easy% 20to% 20pack% 20up% 20and% 20haul% 20with% 20you. || quantity = 1

As you can see, it seems that all <td> elements with a class name starting with item_ are stored in a cookie.
Chrome Developer Tools shows a size of 828 bytes for this cookie.
Therefore, the number of elements that can be added to the basket is variable and depends on the length of each data element (name, description, etc.).
So what can you do to avoid this problem?

  • Reduce the minimum markup of the HTML element, for example by removing the item_thumb and item_Description .
  • Modify the addToCart method in addToCart code to reduce the length of the cookie while maintaining less information (see below for more details).
  • Modify the createCookie , readCookie and eraseCookie in eraseCookie code to use local storage instead of cookies to store item data (see this page for sample code or below for another example).

For example, to avoid storing the fields of the thumb and description element in a cookie, you can change the addToCart method as follows:

 ShelfItem.prototype.addToCart = function () { var outStrings = [],valueString; for( var field in this ){ if( typeof( this[field] ) != "function" && field != "id" ){ valueString = ""; //console.log(field); switch(field){ case "price": if( this[field].value ){ valueString = this[field].value; } else if( this[field].innerHTML ) { valueString = this[field].innerHTML; } /* remove all characters from price except digits and a period */ valueString = valueString.replace( /[^(\d|\.)]*/gi , "" ); valueString = valueString.replace( /,*/ , "" ); break; case "image": valueString = this[field].src; break; case "thumb": case "Description": case "description": /* don't store "thumb" and "description" in the cookie */ break; default: if( this[field].value ){ valueString = this[field].value; } else if( this[field].innerHTML ) { valueString = this[field].innerHTML; } else if( this[field].src ){ valueString = this[field].src; } else { valueString = this[field]; } break; } outStrings.push( field + "=" + valueString ); } } } 

It would be much better to use localStorage if the browser supports it, otherwise use cookies as a backup:

 function supports_html5_storage() { try { return 'localStorage' in window && window['localStorage'] !== null; } catch (e) { return false; } } function createCookie(name,value,days) { if (supports_html5_storage()) { if (value == '') { eraseCookie(name); } else { window.localStorage.setItem(name, JSON.stringify(value)); } } else { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else var expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } } function readCookie(name) { if (supports_html5_storage()) { return window.localStorage.getItem(name); } else { var ca = document.cookie.split(';'); var nameEQ = name + "="; for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length); } return null; } } function eraseCookie(name) { if (supports_html5_storage()) { window.localStorage.removeItem(name); } else { createCookie(name,"",-1); } } 

When using localStorage we can also store thumb and description fields without problems (since we have 5 MB of space), so we can additionally change the ShelfItem.prototype.addToCart function as follows:

  ... case "thumb": case "Description": case "description": if (!supports_html5_storage()) break; ... 
+6
source

It seems you are catching a black cat in a dark room, but the cat is not there.

So what I did:

What I found:

  • When you open the html page from the file system, you get what you have
  • If you put it on the server (in my case a local apache instance), then everything will work fine

2 Episode.

You are trying to add a lot of information in a cookie. An easy way to change the print function as follows

 CartItem.prototype.print = function () { var returnString = ''; for( var field in this ) { if( typeof( this[field] ) != "function" && field !="description") { returnString+= escape(field) + "=" + escape(this[field]) + "||"; } } return returnString.substring(0,returnString.length-2); }; 

Do you really need all the element fields in the cookie?

+1
source

Source: https://habr.com/ru/post/1491019/


All Articles