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