Posted By

shan2batman1 on 02/06/12


Tagged

blogs cart 4


Versions (?)

simplecart


 / Published in: JavaScript
 

URL: shop.subcontinentaldef.net

just a simple cart

  1. /****************************************************************************
  2. Copyright (c) 2011 The Wojo Group
  3.  
  4. thewojogroup.com
  5. simplecartjs.com
  6. http://github.com/thewojogroup/simplecart-js/tree/master
  7.  
  8. The MIT License
  9.  
  10. Permission is hereby granted, free of charge, to any person obtaining a copy
  11. of this software and associated documentation files (the "Software"), to deal
  12. in the Software without restriction, including without limitation the rights
  13. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. copies of the Software, and to permit persons to whom the Software is
  15. furnished to do so, subject to the following conditions:
  16.  
  17. The above copyright notice and this permission notice shall be included in
  18. all copies or substantial portions of the Software.
  19.  
  20. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. THE SOFTWARE.
  27. ****************************************************************************/
  28.  
  29. var Custom="Custom",GoogleCheckout="GoogleCheckout",PayPal="PayPal",Email="Email",IndonesianRupiah="IDR",IDR="IDR",AustralianDollar="AUD",AUD="AUD",CanadianDollar="CAD",CAD="CAD",CzechKoruna="CZK",CZK="CZK",DanishKrone="DKK",DKK="DKK",Euro="EUR",EUR="EUR",HongKongDollar="HKD",HKD="HKD",HungarianForint="HUF",HUF="HUF",IsraeliNewSheqel="ILS",ILS="ILS",JapaneseYen="JPY",JPY="JPY",MexicanPeso="MXN",MXN="MXN",NorwegianKrone="NOK",NOK="NOK",NewZealandDollar="NZD",NZD="NZD",PolishZloty="PLN",PLN="PLN",PoundSterling="GBP",GBP="GBP",SingaporeDollar="SGD",SGD="SGD",SwedishKrona="SEK",SEK="SEK",SwissFranc="CHF",CHF="CHF",ThaiBaht="THB",THB="THB",USDollar="USD",USD="USD";
  30. function Cart(){
  31.  
  32. var me = this;
  33. /* member variables */
  34. me.nextId = 1;
  35. me.Version = '2.2.2';
  36. me.Shelf = null;
  37. me.items = {};
  38. me.isLoaded = false;
  39. me.pageIsReady = false;
  40. me.quantity = 0;
  41. me.total = 0;
  42. me.taxRate = 0;
  43. me.taxCost = 0;
  44. me.shippingFlatRate = 0;
  45. me.shippingTotalRate = 0;
  46. me.shippingQuantityRate = 0;
  47. me.shippingRate = 0;
  48. me.shippingCost = 0;
  49. me.currency = USD;
  50. me.checkoutTo = PayPal;
  51. me.email = "";
  52. me.merchantId = "";
  53. me.successUrl = null;
  54. me.cancelUrl = null;
  55. me.cookieDuration = 30; // default duration in days
  56. me.storagePrefix = "sc_";
  57. me.MAX_COOKIE_SIZE = 4000;
  58. me.cartHeaders = ['Name','Price','Quantity','Total'];
  59. me.events = {};
  60. me.sandbox = false;
  61. me.paypalHTTPMethod = "GET";
  62. /*
  63. cart headers:
  64. you can set these to which ever order you would like, and the cart will display the appropriate headers
  65. and item info. any field you have for the items in the cart can be used, and 'Total' will automatically
  66. be price*quantity.
  67.  
  68. there are keywords that can be used:
  69.  
  70. 1) "_input" - the field will be a text input with the value set to the given field. when the user
  71. changes the value, it will update the cart. this can be useful for quantity. (ie "Quantity_input")
  72.  
  73. 2) "increment" - a link with "+" that will increase the item quantity by 1
  74.  
  75. 3) "decrement" - a link with "-" that will decrease the item quantity by 1
  76.  
  77. 4) "remove" - a link that will remove the item from the cart
  78.  
  79. 5) "_image" or "Image" - the field will be an img tag with the src set to the value. You can simply use "Image" if
  80. you set a field in the items called "Image". If you have a field named something else, like "Thumb", you can add
  81. the "_image" to create the image tag (ie "Thumb_image").
  82.  
  83. 6) "_noHeader" - this will skip the header for that field (ie "increment_noHeader")
  84.  
  85.  
  86. */
  87.  
  88.  
  89.  
  90.  
  91. /******************************************************
  92. add/remove items to cart
  93. ******************************************************/
  94.  
  95. me.add = function ( values ) {
  96. var me=this;
  97. /* load cart values if not already loaded */
  98. if( !me.pageIsReady ) {
  99. me.initializeView();
  100. me.update();
  101. }
  102. if( !me.isLoaded ) {
  103. me.load();
  104. me.update();
  105. }
  106.  
  107. var newItem = new CartItem();
  108.  
  109. /* check to ensure arguments have been passed in */
  110. if( !arguments || arguments.length === 0 ){
  111. error( 'No values passed for item.');
  112. return null;
  113. }
  114. var argumentArray = arguments;
  115. if( values && typeof( values ) !== 'string' && typeof( values ) !== 'number' ){
  116. argumentArray = values;
  117. }
  118.  
  119. newItem.parseValuesFromArray( argumentArray );
  120. newItem.checkQuantityAndPrice();
  121.  
  122. if( me.trigger('beforeAdd', [newItem] ) === false ){
  123. return false;
  124. }
  125. var isNew = true;
  126.  
  127. /* if the item already exists, update the quantity */
  128. if( me.hasItem(newItem) ) {
  129. var foundItem=me.hasItem(newItem);
  130. foundItem.quantity= parseInt(foundItem.quantity,10) + parseInt(newItem.quantity,10);
  131. newItem = foundItem;
  132. isNew = false;
  133. } else {
  134. me.items[newItem.id] = newItem;
  135. }
  136.  
  137. me.update();
  138. me.trigger('afterAdd', [newItem,isNew] );
  139.  
  140. return newItem;
  141.  
  142. };
  143.  
  144.  
  145. me.remove = function( id ){
  146. var tempArray = {};
  147.  
  148. me.each(function(item){
  149. if( item.id !== id ){
  150. tempArray[item.id] = item;
  151. }
  152. });
  153. this.items = tempArray;
  154. };
  155.  
  156. me.empty = function () {
  157. me.items = {};
  158. me.update();
  159. };
  160.  
  161. /******************************************************
  162. item accessor functions
  163. ******************************************************/
  164.  
  165. me.find = function (criteria) {
  166. if( !criteria ){
  167. return null;
  168. }
  169.  
  170. var results = [];
  171.  
  172. me.each(function(item,x,next){
  173.  
  174. fits = true;
  175.  
  176. me.each( criteria , function(value,j,name){
  177. if( !item[name] || item[name] != value ){
  178. fits = false;
  179. }
  180. });
  181.  
  182. if( fits ){
  183. results.push( item );
  184. }
  185. });
  186. return (results.length === 0 ) ? null : results;
  187. };
  188.  
  189.  
  190. me.each = function( array , callback ){
  191. var next,
  192. x=0,
  193. result;
  194.  
  195. if( typeof array === 'function' ){
  196. var cb = array
  197. items = me.items;
  198. } else if( typeof callback === 'function' ){
  199. var cb = callback,
  200. items = array;
  201. } else {
  202. return;
  203. }
  204.  
  205. for( next in items ){
  206. if( typeof items[next] !== "function" ){
  207. result = cb.call( me , items[next] , x , next );
  208. if( result === false ){
  209. return;
  210. }
  211. x++;
  212. }
  213. }
  214.  
  215. };
  216.  
  217.  
  218. me.chunk = function(str, n) {
  219. if (typeof n==='undefined'){
  220. n=2;
  221. }
  222. var result = str.match(RegExp('.{1,'+n+'}','g'));
  223. return result || [];
  224. };
  225.  
  226.  
  227. /******************************************************
  228. checkout management
  229. ******************************************************/
  230.  
  231. me.checkout = function() {
  232. if( me.quantity === 0 ){
  233. error("Cart is empty");
  234. return false;
  235. }
  236. switch( me.checkoutTo ){
  237. case PayPal:
  238. me.paypalCheckout();
  239. break;
  240. case GoogleCheckout:
  241. me.googleCheckout();
  242. break;
  243. case Email:
  244. me.emailCheckout();
  245. break;
  246. default:
  247. me.customCheckout();
  248. break;
  249. }
  250. };
  251.  
  252. me.paypalCheckout = function() {
  253.  
  254.  
  255. var form = document.createElement("form"),
  256. counter=1,
  257. current,
  258. item,
  259. descriptionString;
  260.  
  261. form.style.display = "none";
  262. form.method = me.paypalHTTPMethod =="GET" || me.paypalHTTPMethod == "POST" ? me.paypalHTTPMethod : "GET";
  263. form.action = me.sandbox ? "https://www.sandbox.paypal.com/cgi-bin/webscr" : "https://www.paypal.com/cgi-bin/webscr";
  264. form.acceptCharset = "utf-8";
  265.  
  266.  
  267. // setup hidden fields
  268. form.appendChild(me.createHiddenElement("cmd", "_cart"));
  269. form.appendChild(me.createHiddenElement("rm", me.paypalHTTPMethod == "POST" ? "2" : "0" ));
  270. form.appendChild(me.createHiddenElement("upload", "1"));
  271. form.appendChild(me.createHiddenElement("business", me.email ));
  272. form.appendChild(me.createHiddenElement("currency_code", "me.currency"));
  273.  
  274. if( me.taxRate ){
  275. form.appendChild(me.createHiddenElement("tax_cart",me.taxCost ));
  276. }
  277.  
  278. if( me.shipping() !== 0){
  279. form.appendChild(me.createHiddenElement("handling_cart", me.shippingCost ));
  280. }
  281.  
  282. if( me.successUrl ){
  283. form.appendChild(me.createHiddenElement("return", me.successUrl ));
  284. }
  285.  
  286. if( me.cancelUrl ){
  287. form.appendChild(me.createHiddenElement("cancel_return", me.cancelUrl ));
  288. }
  289.  
  290.  
  291.  
  292. me.each(function(item,iter){
  293.  
  294. counter = iter+1;
  295.  
  296. form.appendChild( me.createHiddenElement( "item_name_" + counter, item.name ) );
  297. form.appendChild( me.createHiddenElement( "quantity_" + counter, item.quantity ) );
  298. form.appendChild( me.createHiddenElement( "amount_" + counter, item.price ) );
  299. form.appendChild( me.createHiddenElement( "item_number_" + counter, counter ) );
  300.  
  301. var option_count = 0;
  302.  
  303. me.each( item , function( value, x , field ){
  304. if( field !== "id" && field !== "price" && field !== "quantity" && field !== "name" && field !== "shipping" && option_count < 10) {
  305. form.appendChild( me.createHiddenElement( "on" + option_count + "_" + counter, field ) );
  306. form.appendChild( me.createHiddenElement( "os" + option_count + "_" + counter, value ) );
  307. option_count++;
  308. }
  309. });
  310.  
  311. form.appendChild( me.createHiddenElement( "option_index_" + counter, option_count) );
  312.  
  313. });
  314.  
  315.  
  316. document.body.appendChild( form );
  317. form.submit();
  318. document.body.removeChild( form );
  319.  
  320. };
  321.  
  322. me.googleCheckout = function() {
  323. var me = this;
  324.  
  325.  
  326. if( me.currency !== USD && me.currency !== GBP ){
  327. error( "Google Checkout only allows the USD and GBP for currency.");
  328. return;
  329. } else if( me.merchantId === "" || me.merchantId === null || !me.merchantId ){
  330. error( "No merchant Id for google checkout supplied.");
  331. return;
  332. }
  333.  
  334. var form = document.createElement("form"),
  335. counter=1,
  336. current,
  337. item,
  338. descriptionString;
  339.  
  340. form.style.display = "none";
  341. form.method = "POST";
  342. form.action = "https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/" +
  343. me.merchantId;
  344. form.acceptCharset = "utf-8";
  345.  
  346. me.each(function(item,iter){
  347.  
  348. counter = iter+1;
  349.  
  350. form.appendChild( me.createHiddenElement( "item_name_" + counter, item.name ) );
  351. form.appendChild( me.createHiddenElement( "item_quantity_" + counter, item.quantity ) );
  352. form.appendChild( me.createHiddenElement( "item_price_" + counter, item.price ) );
  353. form.appendChild( me.createHiddenElement( "item_currency_" + counter, me.currency ) );
  354. form.appendChild( me.createHiddenElement( "item_tax_rate_" + counter, me.taxRate ) );
  355. form.appendChild( me.createHiddenElement( "_charset_" , "" ) );
  356.  
  357. descriptionString = "";
  358.  
  359. me.each( item , function( value , x , field ){
  360.  
  361. if( field !== "id" &&
  362. field !== "quantity" &&
  363. field !== "price" ) {
  364.  
  365. descriptionString = descriptionString + ", " + field + ": " + value;
  366. }
  367. });
  368.  
  369. descriptionString = descriptionString.substring( 1 );
  370. form.appendChild( me.createHiddenElement( "item_description_" + counter, descriptionString) );
  371.  
  372. });
  373.  
  374. // hack for adding shipping
  375. if( me.shipping() !== 0){
  376. form.appendChild(me.createHiddenElement("ship_method_name_1", "Shipping"));
  377. form.appendChild(me.createHiddenElement("ship_method_price_1", parseFloat(me.shippingCost).toFixed(2)));
  378. form.appendChild(me.createHiddenElement("ship_method_currency_1", me.currency));
  379. }
  380.  
  381. document.body.appendChild( form );
  382. form.submit();
  383. document.body.removeChild( form );
  384. };
  385.  
  386.  
  387.  
  388. me.emailCheckout = function() {
  389. return;
  390. };
  391.  
  392. me.customCheckout = function() {
  393. return;
  394. };
  395.  
  396.  
  397.  
  398.  
  399. /******************************************************
  400. data storage and retrival
  401. ******************************************************/
  402.  
  403. /* load cart from cookie */
  404. me.load = function () {
  405. var me = this,
  406. id;
  407.  
  408. /* initialize variables and items array */
  409. me.items = {};
  410. me.total = 0.00;
  411. me.quantity = 0;
  412.  
  413. /* retrieve item data from cookie */
  414. if( readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks") ){
  415. var chunkCount = 1*readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks"),
  416. dataArray = [],
  417. dataString = "",
  418. data = "",
  419. info,
  420. newItem,
  421. y=0;
  422. if(chunkCount>0) {
  423. for( y=0;y<chunkCount;y++){
  424. dataArray.push( readCookie( simpleCart.storagePrefix + 'simpleCart_' + (1 + y ) ) );
  425. }
  426.  
  427. dataString = unescape( dataArray.join("") );
  428. data = dataString.split("++");
  429. }
  430. for(var x=0, xlen=data.length;x<xlen;x++){
  431.  
  432. info = data[x].split('||');
  433. newItem = new CartItem();
  434.  
  435. if( newItem.parseValuesFromArray( info ) ){
  436. newItem.checkQuantityAndPrice();
  437. /* store the new item in the cart */
  438. me.items[newItem.id] = newItem;
  439. }
  440. }
  441. }
  442.  
  443. me.isLoaded = true;
  444. };
  445.  
  446.  
  447.  
  448. /* save cart to cookie */
  449. me.save = function () {
  450. var dataString = "",
  451. dataArray = [],
  452. chunkCount = 0;
  453.  
  454. chunkCount = 1*readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks");
  455. for( var j=0;j<chunkCount;j++){
  456. eraseCookie(simpleCart.storagePrefix + 'simpleCart_'+ j);
  457. }
  458. eraseCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks");
  459.  
  460.  
  461. me.each(function(item){
  462. dataString = dataString + "++" + item.print();
  463. });
  464.  
  465. dataArray = simpleCart.chunk( dataString.substring(2) , simpleCart.MAX_COOKIE_SIZE );
  466.  
  467. for( var x=0,xlen = dataArray.length;x<xlen;x++){
  468. createCookie(simpleCart.storagePrefix + 'simpleCart_' + (1 + x ), dataArray[x], me.cookieDuration );
  469. }
  470.  
  471. createCookie( simpleCart.storagePrefix + 'simpleCart_' + "chunks", "" + dataArray.length , me.cookieDuration );
  472. };
  473.  
  474.  
  475.  
  476. /******************************************************
  477. view management
  478. ******************************************************/
  479.  
  480. me.initializeView = function() {
  481. var me = this;
  482. me.totalOutlets = getElementsByClassName('simpleCart_total');
  483. me.quantityOutlets = getElementsByClassName('simpleCart_quantity');
  484. me.cartDivs = getElementsByClassName('simpleCart_items');
  485. me.taxCostOutlets = getElementsByClassName('simpleCart_taxCost');
  486. me.taxRateOutlets = getElementsByClassName('simpleCart_taxRate');
  487. me.shippingCostOutlets = getElementsByClassName('simpleCart_shippingCost');
  488. me.finalTotalOutlets = getElementsByClassName('simpleCart_finalTotal');
  489.  
  490. me.addEventToArray( getElementsByClassName('simpleCart_checkout') , simpleCart.checkout , "click");
  491. me.addEventToArray( getElementsByClassName('simpleCart_empty') , simpleCart.empty , "click" );
  492.  
  493. me.Shelf = new Shelf();
  494. me.Shelf.readPage();
  495.  
  496. me.pageIsReady = true;
  497.  
  498. };
  499.  
  500.  
  501.  
  502. me.updateView = function() {
  503. me.updateViewTotals();
  504. if( me.cartDivs && me.cartDivs.length > 0 ){
  505. me.updateCartView();
  506. }
  507. };
  508.  
  509. me.updateViewTotals = function() {
  510. var outlets = [ ["quantity" , "none" ] ,
  511. ["total" , "currency" ] ,
  512. ["shippingCost" , "currency" ] ,
  513. ["taxCost" , "currency" ] ,
  514. ["taxRate" , "percentage" ] ,
  515. ["finalTotal" , "currency" ] ];
  516.  
  517. for( var x=0,xlen=outlets.length; x<xlen;x++){
  518.  
  519. var arrayName = outlets[x][0] + "Outlets",
  520. outputString,
  521. element;
  522.  
  523. for( var y = 0,ylen = me[ arrayName ].length; y<ylen; y++ ){
  524. switch( outlets[x][1] ){
  525. case "none":
  526. outputString = "" + me[outlets[x][0]];
  527. break;
  528. case "currency":
  529. outputString = me.valueToCurrencyString( me[outlets[x][0]] );
  530. break;
  531. case "percentage":
  532. outputString = me.valueToPercentageString( me[outlets[x][0]] );
  533. break;
  534. default:
  535. outputString = "" + me[outlets[x][0]];
  536. break;
  537. }
  538. me[arrayName][y].innerHTML = "" + outputString;
  539. }
  540. }
  541. };
  542.  
  543. me.updateCartView = function() {
  544. var newRows = [],
  545. y,newRow,current,header,newCell,info,outputValue,option,headerInfo;
  546.  
  547. /* create headers row */
  548. newRow = document.createElement('div');
  549. for(var y=0,ylen = me.cartHeaders.length; y<ylen; y++ ){
  550. newCell = document.createElement('div');
  551. headerInfo = me.cartHeaders[y].split("_");
  552.  
  553. newCell.innerHTML = me.print( headerInfo[0] );
  554. newCell.className = "item" + headerInfo[0];
  555. for(var z=1,zlen=headerInfo.length;z<zlen;z++){
  556. if( headerInfo[z].toLowerCase() == "noheader" ){
  557. newCell.style.display = "none";
  558. }
  559. }
  560. newRow.appendChild( newCell );
  561.  
  562. }
  563. newRow.className = "cartHeaders";
  564. newRows[0] = newRow;
  565.  
  566. /* create a row for each item in the cart */
  567. me.each(function(item, x){
  568. newRow = document.createElement('div');
  569.  
  570. for(var y=0,ylen = me.cartHeaders.length; y<ylen; y++ ){
  571. newCell = document.createElement('div');
  572. info = me.cartHeaders[y].split("_");
  573.  
  574. outputValue = me.createCartRow( info , item , outputValue );
  575.  
  576. newCell.innerHTML = outputValue;
  577. newCell.className = "item" + info[0];
  578.  
  579. newRow.appendChild( newCell );
  580. }
  581. newRow.className = "itemContainer";
  582. newRows[x+1] = newRow;
  583. });
  584.  
  585.  
  586.  
  587. for( var x=0,xlen=me.cartDivs.length; x<xlen; x++){
  588.  
  589. /* delete current rows in div */
  590. var div = me.cartDivs[x];
  591. if( div.childNodes && div.appendChild ){
  592. while( div.childNodes[0] ){
  593. div.removeChild( div.childNodes[0] );
  594. }
  595.  
  596.  
  597. for(var j=0, jLen = newRows.length; j<jLen; j++){
  598. div.appendChild( newRows[j] );
  599. }
  600. }
  601.  
  602. }
  603. };
  604.  
  605. me.createCartRow = function( info , item , outputValue ){
  606.  
  607. switch( info[0].toLowerCase() ){
  608. case "total":
  609. outputValue = me.valueToCurrencyString(parseFloat(item.price)*parseInt(item.quantity,10) );
  610. break;
  611. case "increment":
  612. outputValue = me.valueToLink( "+" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].increment();\"" );
  613. break;
  614. case "decrement":
  615. outputValue = me.valueToLink( "-" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].decrement();\"" );
  616. break;
  617. case "remove":
  618. outputValue = me.valueToLink( "Remove" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].remove();\"" );
  619. break;
  620. case "price":
  621. outputValue = me.valueToCurrencyString( item[ info[0].toLowerCase() ] ? item[info[0].toLowerCase()] : " " );
  622. break;
  623. default:
  624. outputValue = item[ info[0].toLowerCase() ] ?
  625. typeof item[info[0].toLowerCase()] === 'function' ?
  626. item[info[0].toLowerCase()].call(item) :
  627. item[info[0].toLowerCase()] :
  628. " ";
  629. break;
  630. }
  631.  
  632. for( var y=1,ylen=info.length;y<ylen;y++){
  633. option = info[y].toLowerCase();
  634. switch( option ){
  635. case "image":
  636. case "img":
  637. outputValue = me.valueToImageString( outputValue );
  638. break;
  639. case "input":
  640. outputValue = me.valueToTextInput( outputValue , "onchange=\"simpleCart.items[\'" + item.id + "\'].set(\'" + info[0].toLowerCase() + "\' , this.value);\"" );
  641. break;
  642. case "div":
  643. case "span":
  644. case "h1":
  645. case "h2":
  646. case "h3":
  647. case "h4":
  648. case "p":
  649. outputValue = me.valueToElement( option , outputValue , "" );
  650. break;
  651. case "noheader":
  652. break;
  653. default:
  654. error( "unkown header option: " + option );
  655. break;
  656. }
  657.  
  658. }
  659. return outputValue;
  660. };
  661.  
  662. me.addEventToArray = function ( array , functionCall , theEvent ) {
  663. var outlet,
  664. element;
  665.  
  666. for(var x=0,xlen=array.length; x<xlen; x++ ){
  667. element = array[x];
  668. if( element.addEventListener ) {
  669. element.addEventListener(theEvent, functionCall , false );
  670. } else if( element.attachEvent ) {
  671. element.attachEvent( "on" + theEvent, functionCall );
  672. }
  673. }
  674. };
  675.  
  676.  
  677. me.createHiddenElement = function ( name , value ){
  678. var element = document.createElement("input");
  679. element.type = "hidden";
  680. element.name = name;
  681. element.value = value;
  682. return element;
  683. };
  684.  
  685.  
  686. /******************************************************
  687. Event Management
  688. ******************************************************/
  689.  
  690. // bind a callback to a simpleCart event
  691. me.bind = function( name , callback ){
  692. if( typeof callback !== 'function' ){
  693. return me;
  694. }
  695.  
  696.  
  697. if (me.events[name] === true ){
  698. callback.apply( me );
  699. } else if( typeof me.events[name] !== 'undefined' ){
  700. me.events[name].push( callback );
  701. } else {
  702. me.events[name] = [ callback ];
  703. }
  704. return me;
  705. };
  706.  
  707.  
  708. // trigger event
  709. me.trigger = function( name , options ){
  710. var returnval = true;
  711. if( typeof me.events[name] !== 'undefined' && typeof me.events[name][0] === 'function'){
  712. for( var x=0,xlen=me.events[name].length; x<xlen; x++ ){
  713. returnval = me.events[name][x].apply( me , (options ? options : [] ) );
  714. }
  715. }
  716. if( returnval === false ){
  717. return false;
  718. } else {
  719. return true;
  720. }
  721. };
  722.  
  723. // shortcut for ready function
  724. me.ready = function( callback ){
  725. if( !callback ){
  726. me.trigger( 'ready' );
  727. me.events['ready'] = true;
  728. } else {
  729. me.bind( 'ready' , callback );
  730. }
  731. return me;
  732. };
  733.  
  734.  
  735.  
  736.  
  737. /******************************************************
  738. Currency management
  739. ******************************************************/
  740.  
  741. me.currencySymbol = function() {
  742. switch(me.currency){
  743. case IDR:
  744. return "Rp&nbsp;";
  745. case CHF:
  746. return "CHF&nbsp;";
  747. case CZK:
  748. return "CZK&nbsp;";
  749. case DKK:
  750. return "DKK&nbsp;";
  751. case HUF:
  752. return "HUF&nbsp;";
  753. case NOK:
  754. return "NOK&nbsp;";
  755. case PLN:
  756. return "PLN&nbsp;";
  757. case SEK:
  758. return "SEK&nbsp;";
  759. case JPY:
  760. return "&yen;";
  761. case EUR:
  762. return "&euro;";
  763. case GBP:
  764. return "&pound;";
  765. case CHF:
  766. return "CHF&nbsp;";
  767. case THB:
  768. return "&#3647;";
  769. case USD:
  770. case CAD:
  771. case AUD:
  772. case NZD:
  773. case HKD:
  774. case SGD:
  775. return "&#36;";
  776. default:
  777. return "";
  778. }
  779. };
  780.  
  781.  
  782. me.currencyStringForPaypalCheckout = function( value ){
  783. if( me.currencySymbol() == "&#36;" ){
  784. return "$" + parseFloat( value ).toFixed(2);
  785. } else {
  786. return "" + parseFloat(value ).toFixed(2);
  787. }
  788. };
  789.  
  790. /******************************************************
  791. Formatting
  792. ******************************************************/
  793.  
  794.  
  795. me.valueToCurrencyString = function( value ) {
  796. var val = parseFloat( value );
  797. if( isNaN(val))
  798. val = 0;
  799.  
  800. return val.toCurrency( me.currencySymbol() );
  801. };
  802.  
  803. me.valueToPercentageString = function( value ){
  804. return parseFloat( 100*value ) + "%";
  805. };
  806.  
  807. me.valueToImageString = function( value ){
  808. if( value.match(/<\s*img.*src\=/) ){
  809. return value;
  810. } else {
  811. return "<img src=\"" + value + "\" />";
  812. }
  813. };
  814.  
  815. me.valueToTextInput = function( value , html ){
  816. return "<input type=\"text\" value=\"" + value + "\" " + html + " />";
  817. };
  818.  
  819. me.valueToLink = function( value, link, html){
  820. return "<a href=\"" + link + "\" " + html + " >" + value + "</a>";
  821. };
  822.  
  823. me.valueToElement = function( type , value , html ){
  824. return "<" + type + " " + html + " > " + value + "</" + type + ">";
  825. };
  826.  
  827. /******************************************************
  828. Duplicate management
  829. ******************************************************/
  830.  
  831. me.hasItem = function ( item ) {
  832. var current,
  833. matches,
  834. field,
  835. match=false;
  836.  
  837. me.each(function(testItem){
  838.  
  839. matches = true;
  840.  
  841. me.each( item , function( value , x , field ){
  842.  
  843. if( field !== "quantity" && field !== "id" && item[field] !== testItem[field] ){
  844. matches = false;
  845. }
  846. });
  847.  
  848. if( matches ){
  849. match = testItem;
  850. }
  851.  
  852. });
  853. return match;
  854. };
  855.  
  856. /******************************************************
  857. Language managment
  858. ******************************************************/
  859. me.ln = {
  860. "en_us": {
  861. quantity: "Quantity"
  862. , price: "Price"
  863. , total: "Total"
  864. , decrement: "Decrement"
  865. , increment: "Increment"
  866. , remove: "Remove"
  867. , tax: "Tax"
  868. , shipping: "Shipping"
  869. , image: "Image"
  870. }
  871. };
  872.  
  873. me.language = "en_us";
  874.  
  875. me.print = function( input ) {
  876. var me = this;
  877. return me.ln[me.language] && me.ln[me.language][input.toLowerCase()] ? me.ln[me.language][input.toLowerCase()] : input;
  878.  
  879. };
  880.  
  881.  
  882. /******************************************************
  883. Cart Update managment
  884. ******************************************************/
  885.  
  886. me.update = function() {
  887. if( !simpleCart.isLoaded ){
  888. simpleCart.load();
  889. }
  890. if( !simpleCart.pageIsReady ){
  891. simpleCart.initializeView();
  892. }
  893. me.updateTotals();
  894. me.updateView();
  895. me.save();
  896. };
  897.  
  898. me.updateTotals = function() {
  899.  
  900. me.total = 0 ;
  901. me.quantity = 0;
  902. me.each(function(item){
  903.  
  904. if( item.quantity < 1 ){
  905. item.remove();
  906. } else if( item.quantity !== null && item.quantity !== "undefined" ){
  907. me.quantity = parseInt(me.quantity,10) + parseInt(item.quantity,10);
  908. }
  909. if( item.price ){
  910. me.total = parseFloat(me.total) + parseInt(item.quantity,10)*parseFloat(item.price);
  911. }
  912.  
  913. });
  914. me.shippingCost = me.shipping();
  915. me.taxCost = parseFloat(me.total)*me.taxRate;
  916. me.finalTotal = me.shippingCost + me.taxCost + me.total;
  917. };
  918.  
  919. me.shipping = function(){
  920. if( parseInt(me.quantity,10)===0 )
  921. return 0;
  922. var shipping = parseFloat(me.shippingFlatRate) +
  923. parseFloat(me.shippingTotalRate)*parseFloat(me.total) +
  924. parseFloat(me.shippingQuantityRate)*parseInt(me.quantity,10),
  925. next;
  926.  
  927. me.each(function(nextItem){
  928. if( nextItem.shipping ){
  929. if( typeof nextItem.shipping == 'function' ){
  930. shipping += parseFloat(nextItem.shipping());
  931. } else {
  932. shipping += parseFloat(nextItem.shipping);
  933. }
  934. }
  935. });
  936.  
  937. return shipping;
  938. }
  939.  
  940. me.initialize = function() {
  941. me.initializeView();
  942. me.load();
  943. me.update();
  944. me.ready();
  945. };
  946.  
  947. }
  948.  
  949. /********************************************************************************************************
  950.  * Cart Item Object
  951.  ********************************************************************************************************/
  952.  
  953. function CartItem() {
  954. while( simpleCart.items["c" + simpleCart.nextId] )
  955. simpleCart.nextId++;
  956.  
  957. this.id = "c" + simpleCart.nextId;
  958. }
  959.  
  960.  
  961. CartItem.prototype = {
  962.  
  963. set : function ( field , value ){
  964. field = field.toLowerCase();
  965. if( typeof( this[field] ) !== "function" && field !== "id" ){
  966. value = "" + value;
  967. if( field == "quantity"){
  968. value = value.replace( /[^(\d|\.)]*/gi , "" );
  969. value = value.replace(/,*/gi, "");
  970. value = parseInt(value,10);
  971. } else if( field == "price" ){
  972. value = value.replace( /[^(\d|\.)]*/gi, "");
  973. value = value.replace(/,*/gi , "");
  974. value = parseFloat( value );
  975. }
  976. if( typeof(value) == "number" && isNaN( value ) ){
  977. error( "Improperly formatted input.");
  978. } else {
  979. if( typeof( value ) === "string" ){
  980. if( value.match(/\~|\=/) ){
  981. error("Special character ~ or = not allowed: " + value);
  982. }
  983. value = value.replace(/\~|\=/g, "");
  984. }
  985. this[field] = value;
  986. this.checkQuantityAndPrice();
  987. }
  988. } else {
  989. error( "Cannot change " + field + ", this is a reserved field.");
  990. }
  991. simpleCart.update();
  992. },
  993.  
  994. increment : function(){
  995. this.quantity = parseInt(this.quantity,10) + 1;
  996. simpleCart.update();
  997. },
  998.  
  999. decrement : function(){
  1000. if( parseInt(this.quantity,10) < 2 ){
  1001. this.remove();
  1002. } else {
  1003. this.quantity = parseInt(this.quantity,10) - 1;
  1004. simpleCart.update();
  1005. }
  1006. },
  1007.  
  1008. print : function () {
  1009. var returnString = '',
  1010. field;
  1011. simpleCart.each(this ,function(item,x,name){
  1012. returnString+= escape(name) + "=" + escape(item) + "||";
  1013. });
  1014. return returnString.substring(0,returnString.length-2);
  1015. },
  1016.  
  1017.  
  1018. checkQuantityAndPrice : function() {
  1019.  
  1020. if( !this.quantity || this.quantity == null || this.quantity == 'undefined'){
  1021. this.quantity = 1;
  1022. error('No quantity for item.');
  1023. } else {
  1024. this.quantity = ("" + this.quantity).replace(/,*/gi, "" );
  1025. this.quantity = parseInt( ("" + this.quantity).replace( /[^(\d|\.)]*/gi, "") , 10);
  1026. if( isNaN(this.quantity) ){
  1027. error('Quantity is not a number.');
  1028. this.quantity = 1;
  1029. }
  1030. }
  1031.  
  1032. if( !this.price || this.price == null || this.price == 'undefined'){
  1033. this.price=0.00;
  1034. error('No price for item or price not properly formatted.');
  1035. } else {
  1036. this.price = ("" + this.price).replace(/,*/gi, "" );
  1037. this.price = parseFloat( ("" + this.price).replace( /[^(\d|\.)]*/gi, "") );
  1038. if( isNaN(this.price) ){
  1039. error('Price is not a number.');
  1040. this.price = 0.00;
  1041. }
  1042. }
  1043. },
  1044.  
  1045.  
  1046. parseValuesFromArray : function( array ) {
  1047. if( array && array.length && array.length > 0) {
  1048. for(var x=0, xlen=array.length; x<xlen;x++ ){
  1049.  
  1050. /* ensure the pair does not have key delimeters */
  1051. array[x] = array[x].replace(/\|\|/g, "| |");
  1052. array[x] = array[x].replace(/\+\+/g, "+ +");
  1053. if( array[x].match(/\~/) ){
  1054. error("Special character ~ not allowed: " + array[x]);
  1055. }
  1056. array[x] = array[x].replace(/\~/g, "");
  1057.  
  1058.  
  1059. /* split the pair and save the unescaped values to the item */
  1060. var value = array[x].split('=');
  1061. if( value.length>1 ){
  1062. if( value.length>2 ){
  1063. for(var j=2, jlen=value.length;j<jlen;j++){
  1064. value[1] = value[1] + "=" + value[j];
  1065. }
  1066. }
  1067. this[ unescape(value[0]).toLowerCase() ] = unescape(value[1]);
  1068. }
  1069. }
  1070. return true;
  1071. } else {
  1072. return false;
  1073. }
  1074. },
  1075.  
  1076. remove : function() {
  1077. simpleCart.remove(this.id);
  1078. simpleCart.update();
  1079. }
  1080. };
  1081.  
  1082.  
  1083.  
  1084. /********************************************************************************************************
  1085.  * Shelf Object for managing items on shelf that can be added to cart
  1086.  ********************************************************************************************************/
  1087.  
  1088. function Shelf(){
  1089. this.items = {};
  1090. }
  1091. Shelf.prototype = {
  1092.  
  1093. readPage : function () {
  1094. this.items = {};
  1095. var newItems = getElementsByClassName( "simpleCart_shelfItem" ),
  1096. newItem;
  1097. me = this;
  1098.  
  1099. for( var x = 0, xlen = newItems.length; x<xlen; x++){
  1100. newItem = new ShelfItem();
  1101. me.checkChildren( newItems[x] , newItem );
  1102. me.items[newItem.id] = newItem;
  1103. }
  1104. },
  1105.  
  1106. checkChildren : function ( item , newItem) {
  1107. if( !item.childNodes )
  1108. return;
  1109. for(var x=0;item.childNodes[x];x++){
  1110.  
  1111. var node = item.childNodes[x];
  1112. if( node.className && node.className.match(/item_[^ ]+/) ){
  1113.  
  1114. var data = /item_[^ ]+/.exec(node.className)[0].split("_");
  1115.  
  1116. if( data[1] == "add" || data[1] == "Add" ){
  1117. var tempArray = [];
  1118. tempArray.push( node );
  1119. var addFunction = simpleCart.Shelf.addToCart(newItem.id);
  1120. simpleCart.addEventToArray( tempArray , addFunction , "click");
  1121. node.id = newItem.id;
  1122. } else {
  1123. newItem[data[1]] = node;
  1124. }
  1125. }
  1126. if( node.childNodes[0] ){
  1127. this.checkChildren( node , newItem );
  1128. }
  1129. }
  1130. },
  1131.  
  1132. empty : function () {
  1133. this.items = {};
  1134. },
  1135.  
  1136.  
  1137. addToCart : function ( id ) {
  1138. return function(){
  1139. if( simpleCart.Shelf.items[id]){
  1140. simpleCart.Shelf.items[id].addToCart();
  1141. } else {
  1142. error( "Shelf item with id of " + id + " does not exist.");
  1143. }
  1144. };
  1145. }
  1146. };
  1147.  
  1148.  
  1149. /********************************************************************************************************
  1150.  * Shelf Item Object
  1151.  ********************************************************************************************************/
  1152.  
  1153.  
  1154. function ShelfItem(){
  1155. this.id = "s" + simpleCart.nextId++;
  1156. }
  1157.  
  1158. ShelfItem.prototype = {
  1159.  
  1160. remove : function () {
  1161. simpleCart.Shelf.items[this.id] = null;
  1162. },
  1163.  
  1164. addToCart : function () {
  1165. var outStrings = [],
  1166. valueString,
  1167. field;
  1168.  
  1169. for( field in this ){
  1170. if( typeof( this[field] ) !== "function" && field !== "id" ){
  1171. valueString = "";
  1172.  
  1173. switch(field){
  1174. case "price":
  1175. if( this[field].value ){
  1176. valueString = this[field].value;
  1177. } else if( this[field].innerHTML ) {
  1178. valueString = this[field].innerHTML;
  1179. }
  1180. /* remove all characters from price except digits and a period */
  1181. valueString = valueString.replace( /[^(\d|\.)]*/gi , "" );
  1182. valueString = valueString.replace( /,*/ , "" );
  1183. break;
  1184. case "image":
  1185. valueString = this[field].src;
  1186. break;
  1187. default:
  1188. if( this[field].value ){
  1189. valueString = this[field].value;
  1190. } else if( this[field].innerHTML ) {
  1191. valueString = this[field].innerHTML;
  1192. } else if( this[field].src ){
  1193. valueString = this[field].src;
  1194. } else {
  1195. valueString = this[field];
  1196. }
  1197. break;
  1198. }
  1199. outStrings.push( field + "=" + valueString );
  1200. }
  1201. }
  1202.  
  1203. simpleCart.add( outStrings );
  1204. }
  1205. };
  1206.  
  1207.  
  1208.  
  1209. /********************************************************************************************************
  1210.  * Thanks to Peter-Paul Koch for these cookie functions (http://www.quirksmode.org/js/cookies.html)
  1211.  ********************************************************************************************************/
  1212. function createCookie(name,value,days) {
  1213. if (days) {
  1214. var date = new Date();
  1215. date.setTime(date.getTime()+(days*24*60*60*1000));
  1216. var expires = "; expires="+date.toGMTString();
  1217. }
  1218. else var expires = "";
  1219. value = value.replace(/\=/g, '~');
  1220. document.cookie = name + "=" + escape(value) + expires + "; path=/";
  1221. }
  1222.  
  1223. function readCookie(name) {
  1224. var nameEQ = name + "=";
  1225. var ca = document.cookie.split(';');
  1226. for(var i=0;i < ca.length;i++) {
  1227. var c = ca[i];
  1228. while (c.charAt(0)==' ') c = c.substring(1,c.length);
  1229. if (c.indexOf(nameEQ) === 0){
  1230. var value = unescape(c.substring(nameEQ.length, c.length));
  1231. return value.replace(/\~/g, '=');
  1232. }
  1233. }
  1234. return null;
  1235. }
  1236.  
  1237. function eraseCookie(name) {
  1238. createCookie(name,"",-1);
  1239. }
  1240.  
  1241.  
  1242. //*************************************************************************************************
  1243. /*
  1244. Developed by Robert Nyman, http://www.robertnyman.com
  1245. Code/licensing: http://code.google.com/p/getelementsbyclassname/
  1246. */
  1247. var getElementsByClassName = function (className, tag, elm){
  1248. if (document.getElementsByClassName) {
  1249. getElementsByClassName = function (className, tag, elm) {
  1250. elm = elm || document;
  1251. var elements = elm.getElementsByClassName(className),
  1252. nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
  1253. returnElements = [],
  1254. current;
  1255. for(var i=0, il=elements.length; i<il; i+=1){
  1256. current = elements[i];
  1257. if(!nodeName || nodeName.test(current.nodeName)) {
  1258. returnElements.push(current);
  1259. }
  1260. }
  1261. return returnElements;
  1262. };
  1263. }
  1264. else if (document.evaluate) {
  1265. getElementsByClassName = function (className, tag, elm) {
  1266. tag = tag || "*";
  1267. elm = elm || document;
  1268. var classes = className.split(" "),
  1269. classesToCheck = "",
  1270. xhtmlNamespace = "http://www.w3.org/1999/xhtml",
  1271. namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
  1272. returnElements = [],
  1273. elements,
  1274. node;
  1275. for(var j=0, jl=classes.length; j<jl; j+=1){
  1276. classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
  1277. }
  1278. try {
  1279. elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
  1280. }
  1281. catch (e) {
  1282. elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
  1283. }
  1284. while ((node = elements.iterateNext())) {
  1285. returnElements.push(node);
  1286. }
  1287. return returnElements;
  1288. };
  1289. }
  1290. else {
  1291. getElementsByClassName = function (className, tag, elm) {
  1292. tag = tag || "*";
  1293. elm = elm || document;
  1294. var classes = className.split(" "),
  1295. classesToCheck = [],
  1296. elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
  1297. current,
  1298. returnElements = [],
  1299. match;
  1300. for(var k=0, kl=classes.length; k<kl; k+=1){
  1301. classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
  1302. }
  1303. for(var l=0, ll=elements.length; l<ll; l+=1){
  1304. current = elements[l];
  1305. match = false;
  1306. for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
  1307. match = classesToCheck[m].test(current.className);
  1308. if (!match) {
  1309. break;
  1310. }
  1311. }
  1312. if (match) {
  1313. returnElements.push(current);
  1314. }
  1315. }
  1316. return returnElements;
  1317. };
  1318. }
  1319. return getElementsByClassName(className, tag, elm);
  1320. };
  1321.  
  1322.  
  1323. /********************************************************************************************************
  1324.  * Helpers
  1325.  ********************************************************************************************************/
  1326.  
  1327.  
  1328. String.prototype.reverse=function(){return this.split("").reverse().join("");};
  1329. Number.prototype.withCommas=function(){var x=6,y=parseFloat(this).toFixed(2).toString().reverse();while(x<y.length){y=y.substring(0,x)+","+y.substring(x);x+=4;}return y.reverse();};
  1330. Number.prototype.toCurrency=function(){return(arguments[0]?arguments[0]:"$")+this.withCommas();};
  1331.  
  1332.  
  1333. /********************************************************************************************************
  1334.  * error management
  1335.  ********************************************************************************************************/
  1336.  
  1337. function error( message ){
  1338. try{
  1339. console.log( message );
  1340. }catch(err){
  1341. // alert( message );
  1342. }
  1343. }
  1344.  
  1345.  
  1346. var simpleCart = new Cart();
  1347.  
  1348. if( typeof jQuery !== 'undefined' ) $(document).ready(function(){simpleCart.initialize();});
  1349. else if( typeof Prototype !== 'undefined') Event.observe( window, 'load', function(){simpleCart.initialize();});
  1350. else window.onload = simpleCart.initialize;

Report this snippet  

You need to login to post a comment.