PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/shopp/core/ui/behaviors/catalog.js

https://github.com/sharpmachine/whiteantelopestudio.com
JavaScript | 470 lines | 368 code | 63 blank | 39 comment | 111 complexity | b63d9e9055b15058148fab2da08b8614 MD5 | raw file
  1. /*!
  2. * catalog.js - Shopp catalog behaviors library
  3. * Copyright © 2008-2010 by Ingenesis Limited
  4. * Licensed under the GPLv3 {@see license.txt}
  5. */
  6. /**
  7. * Product variation option menu behaviors
  8. **/
  9. function ProductOptionsMenus (target,settings) {
  10. var $ = jQuery,
  11. i = 0,
  12. previous = false,
  13. current = false,
  14. menucache = new Array(),
  15. menus = $(target),
  16. disabled = 'disabled',
  17. defaults = {
  18. disabled:true,
  19. pricetags:true,
  20. format:'%l (%p)',
  21. taxrate:0,
  22. prices:{}
  23. },
  24. settings = $.extend(defaults,settings);
  25. menus.each(function (id,menu) {
  26. current = menu;
  27. menucache[id] = $(menu).children();
  28. if ($.ua.msie) disabledHandler(menu);
  29. if (id > 0) previous = menus[id-1];
  30. if (menus.length == 1) {
  31. optionPriceTags();
  32. } else if (previous) {
  33. $(previous).change(function () {
  34. if (menus.index(current) == menus.length-1) optionPriceTags();
  35. if (this.selectedIndex == 0 &&
  36. this.options[0].value == "") $(menu).attr(disabled,true);
  37. else $(menu).removeAttr(disabled);
  38. }).change();
  39. }
  40. i++;
  41. });
  42. // Last menu needs pricing
  43. function optionPriceTags () {
  44. // Grab selections
  45. var selected = new Array(),
  46. currentSelection = $(current).val();
  47. menus.not(current).each(function () {
  48. if ($(this).val() != "") selected.push($(this).val());
  49. });
  50. $(current).empty();
  51. menucache[menus.index(current)].each(function (id,option) {
  52. $(option).appendTo($(current));
  53. });
  54. $(current).val(currentSelection);
  55. $(current).children('option').each(function () {
  56. var tax,optiontext,previoustag,pricetag,f = false,
  57. option = $(this),
  58. o = {l:f,p:f,s:f,d:f,r:f,u:f}, // Option object
  59. keys = selected.slice(),
  60. price;
  61. if (option.val() != "") {
  62. if ( ! this._label) this._label = option.text(); // Save label in DOM element property for later reference
  63. o.l = this._label;
  64. keys.push(option.val());
  65. price = settings.prices[xorkey(keys)] || settings.prices[xorkey(keys,'deprecated')];
  66. if (price) {
  67. if (price.p && settings.pricetags) {
  68. pricetag = new Number(price.p);
  69. tax = price.tax?new Number(pricetag*settings.taxrate):0;
  70. o.p = asMoney(new Number(pricetag+tax));
  71. }
  72. if ($.ua.msie) option.css('color','#373737');
  73. if ((price.i && price.s < 1) || price.t == 'N/A') {
  74. if (option.attr('selected'))
  75. option.parent().attr('selectedIndex',0);
  76. if (!settings.disabled) option.remove();
  77. else optionDisable(option);
  78. } else {
  79. option.removeAttr(disabled).show();
  80. }
  81. if (price.i) {
  82. o.s = price.s;
  83. o.u = price.u;
  84. }
  85. if (price.t == 'N/A' && !settings.disabled) option.remove();
  86. option.text( formatlabel(settings.format,o) );
  87. } else {
  88. if (!settings.disabled) option.remove();
  89. else optionDisable(option);
  90. }
  91. }
  92. });
  93. }
  94. // Magic key generator
  95. function xorkey (ids,deprecated) {
  96. if (!(ids instanceof Array)) ids = [ids];
  97. for (var key=0,i=0,mod=deprecated?101:7001; i < ids.length; i++)
  98. key = key ^ (ids[i]*mod);
  99. return key;
  100. }
  101. function optionDisable (option) {
  102. option.attr(disabled,true);
  103. if (!$.browser.msie) return;
  104. option.css('color','#ccc');
  105. }
  106. function disabledHandler (menu) {
  107. $(menu).change(function () {
  108. var _ = this,firstEnabled;
  109. if (!_.options[_.selectedIndex].disabled) {
  110. _.lastSelected = _.selectedIndex;
  111. return true;
  112. }
  113. if (_.lastSelected) _.selectedIndex = _.lastSelected;
  114. else {
  115. firstEnabled = $(_).children('option:not(:disabled)').get(0);
  116. _.selectedIndex = firstEnabled?firstEnabled.index:0;
  117. }
  118. });
  119. }
  120. function formatlabel (f,v) {
  121. var m = '([^ ]*)',
  122. rescape = function (t) { return t.toString().replace(/[$]/g, "$$$$"); };
  123. $.each(v,function (p) {
  124. if (v && v[p] != undefined) {
  125. var pattern = new RegExp('('+m+'%'+p+m+')');
  126. label = "$2"+rescape(v[p])+"$3";
  127. if (v[p] === false) label = "";
  128. if (v[p] === "") label = "";
  129. f = f.replace(pattern,label);
  130. }
  131. });
  132. return f;
  133. }
  134. }
  135. /**
  136. * Toggles catalog grid and list view changes
  137. **/
  138. function catalogViewHandler () {
  139. var $=jQuery,
  140. display = $('#shopp'),
  141. expires = new Date(),
  142. toggles = {'list':'grid','grid':'list'};
  143. expires.setTime(expires.getTime()+(30*86400000));
  144. $.each(toggles,function (view,lastview) {
  145. display.find('ul.views li button.'+view).click(function () {
  146. display.removeClass(lastview).addClass(view);
  147. document.cookie = 'shopp_catalog_view='+view+'; expires='+expires+'; path=/';
  148. }).hover(function () { $(this).toggleClass('hover'); });
  149. });
  150. }
  151. /**
  152. * Create a gallery viewing for a set of images
  153. **/
  154. function ShoppGallery (id,evt,tw) {
  155. var $ = jQuery,
  156. gallery = $(id),
  157. previews = gallery.find('ul.previews'),
  158. thumbnails = gallery.find('ul.thumbnails li');
  159. if (!evt) evt = 'click';
  160. if (tw) gallery.find('ul.thumbnails').css('width',tw+'px');
  161. thumbnails.bind(evt,function () {
  162. var previous,target = $('#'+$(this).attr('class').split(' ')[0]);
  163. if (!target.hasClass('active')) {
  164. previous = gallery.find('ul.previews li.active');
  165. target.addClass('active').hide();
  166. if (previous.length) {
  167. previous.fadeOut(800,function() {
  168. previous.removeClass('active');
  169. });
  170. }
  171. target.appendTo(previews).fadeIn(500);
  172. }
  173. });
  174. }
  175. /**
  176. * Generate a slideshow from a list of images
  177. **/
  178. function ShoppSlideshow (element,duration,delay,fx,order) {
  179. var $ = jQuery,_ = this,effects;
  180. _.element = $(element);
  181. var effects = {
  182. 'fade':[{'display':'none'},{'opacity':'show'}],
  183. 'slide-down':[{'display':'block','top':_.element.height()*-1},{'top':0}],
  184. 'slide-up':[{'display':'block','top':_.element.height()},{'top':0}],
  185. 'slide-left':[{'display':'block','left':_.element.width()*-1},{'left':0}],
  186. 'slide-right':[{'display':'block','left':_.element.width()},{'left':0}],
  187. 'wipe':[{'display':'block','height':0},{'height':_.element.height()}]
  188. },ordering = ['normal','reverse','shuffle'];
  189. _.duration = (!duration)?800:duration;
  190. _.delay = (!delay)?7000:delay;
  191. fx = (!fx)?'fade':fx;
  192. _.effect = (!effects[fx])?effects['fade']:effects[fx];
  193. order = (!order)?'normal':order;
  194. _.order = ($.inArray(order,ordering) != -1)?order:'normal';
  195. _.slides = $(_.element).find('li:not(li.clear)').hide().css('visibility','visible');
  196. _.total = _.slides.length;
  197. _.slide = 0;
  198. _.shuffling = new Array();
  199. _.startTransition = function () {
  200. var index,selected,prev = $(_.slides[_.slide-1]).removeClass('active');
  201. $(_.slides[_.slide]).css(_.effect[0]).appendTo(_.element).animate(
  202. _.effect[1],
  203. _.duration,
  204. function () {
  205. prev.css(_.effect[0]);
  206. }
  207. ).addClass('active');
  208. switch (_.order) {
  209. case "shuffle":
  210. if (_.shuffling.length == 0) {
  211. _.shuffleList();
  212. index = $.inArray(_.slide,_.shuffling);
  213. if (index != -1) _.shuffling.splice(index,1);
  214. }
  215. selected = Math.floor(Math.random()*_.shuffling.length);
  216. _.slide = _.shuffling[selected];
  217. _.shuffling.splice(selected,1);
  218. break;
  219. case "reverse": _.slide = (_.slide-1 < 0)?_.slides.length-1:_.slide-1; break;
  220. default: _.slide = (_.slide+1 == _.total)?0:_.slide+1;
  221. }
  222. if (_.slides.length == 1) return;
  223. setTimeout(_.startTransition,_.delay);
  224. };
  225. _.transitionTo = function (slide) {
  226. _.slide = slide;
  227. _.startTransition();
  228. };
  229. _.shuffleList = function () {
  230. for (var i = 0; i < _.total; i++) _.shuffling.push(i);
  231. };
  232. _.startTransition();
  233. }
  234. /**
  235. * Auto-initialize slideshow behaviors for ul's with a 'slideshow' class
  236. **/
  237. function slideshows () {
  238. var $ = jQuery,classes,options,map;
  239. $('ul.slideshow').each(function () {
  240. classes = $(this).attr('class');
  241. options = {};
  242. map = {
  243. 'fx':new RegExp(/([\w_-]+?)\-fx/),
  244. 'order':new RegExp(/([\w_-]+?)\-order/),
  245. 'duration':new RegExp(/duration\-(\d+)/),
  246. 'delay':new RegExp(/delay\-(\d+)/)
  247. };
  248. $.each(map,function (name,pattern) {
  249. if (option = classes.match(pattern)) options[name] = option[1];
  250. });
  251. new ShoppSlideshow(this,options['duration'],options['delay'],options['fx'],options['order']);
  252. });
  253. }
  254. /**
  255. * Generate a carousel (looping slider) of images
  256. **/
  257. function ShoppCarousel (element,duration) {
  258. var $ = jQuery,spacing,
  259. _ = this,
  260. visible=1,
  261. carousel = $(element),
  262. list = carousel.find('ul'),
  263. items = list.find('> li');
  264. _.duration = (!duration)?800:duration;
  265. _.cframe = carousel.find('div.frame');
  266. visible = Math.round(_.cframe.innerWidth() / items.outerWidth());
  267. if (visible < 1) visible = 1;
  268. spacing = Math.round(((_.cframe.innerWidth() % items.outerWidth())/items.length)/2);
  269. items.css('margin','0 '+spacing+'px');
  270. _.pageWidth = (items.outerWidth()+(spacing*2)) * visible;
  271. _.page = 1;
  272. _.pages = Math.ceil(items.length / visible);
  273. // Fill in empty slots
  274. if ((items.length % visible) != 0) {
  275. list.append( new Array(visible - (items.length % visible)+1).join('<li class="empty" style="width: '+items.outerWidth()+'px; height: 1px; margin: 0 '+spacing+'px"/>') );
  276. items = list.find('> li');
  277. }
  278. items.filter(':first').before(items.slice(-visible).clone().addClass('cloned'));
  279. items.filter(':last').after(items.slice(0,visible).clone().addClass('cloned'));
  280. items = list.find('> li');
  281. _.cframe.scrollLeft(_.pageWidth);
  282. _.scrollLeft = carousel.find('button.left');
  283. _.scrollRight = carousel.find('button.right');
  284. _.scrolltoPage = function (page) {
  285. var dir = page < _.page?-1:1,
  286. delta = Math.abs(_.page-page),
  287. scrollby = _.pageWidth*dir*delta;
  288. _.cframe.filter(':not(:animated)').animate({
  289. 'scrollLeft':'+='+scrollby
  290. },_.duration,function() {
  291. if (page == 0) {
  292. _.cframe.scrollLeft(_.pageWidth*_.pages);
  293. page = _.pages;
  294. } else if (page > _.pages) {
  295. _.cframe.scrollLeft(_.pageWidth);
  296. page = 1;
  297. }
  298. _.page = page;
  299. });
  300. };
  301. _.scrollLeft.click(function () {
  302. return _.scrolltoPage(_.page-1);
  303. });
  304. _.scrollRight.click(function () {
  305. return _.scrolltoPage(_.page+1);
  306. });
  307. }
  308. /**
  309. * Auto-initialize carousel behaviors for divs with a 'carousel' class
  310. **/
  311. function carousels () {
  312. var $ = jQuery,classes,options,map;
  313. $('div.carousel').each(function () {
  314. classes = $(this).attr('class');
  315. options = {};
  316. map = { 'duration':new RegExp(/duration\-(\d+)/) };
  317. $.each(map,function (name,pattern) {
  318. if (option = classes.match(pattern)) options[name] = option[1];
  319. });
  320. new ShoppCarousel(this,options['duration']);
  321. });
  322. }
  323. /**
  324. * Form validation
  325. **/
  326. function validate (form) {
  327. if (!form) return false;
  328. var $ = jQuery,
  329. $form = $(form),
  330. passed = true,
  331. passwords = [],
  332. error = [],
  333. inputs = $(form).find('input,select,textarea').not(":hidden"),
  334. required = 'required',
  335. title = 'title';
  336. $.fn.reverse = (typeof []._reverse == 'undefined') ? [].reverse : []._reverse; // For Prototype-compatibility #1854
  337. $.each(inputs.reverse(),function (id,field) {
  338. input = $(field).removeClass('error');
  339. label = $('label[for=' + input.attr('id') + ']').removeClass('error');
  340. if (true === input.attr('disabled') || 'disabled' == input.attr('disabled')) return;
  341. if (input.hasClass(required) && input.val() == "")
  342. error = new Array($cv.field.replace(/%s/,input.attr(title)),field);
  343. if (input.hasClass(required) && input.attr('type') == "checkbox" && !input.attr('checked'))
  344. error = new Array($cv.chkbox.replace(/%s/,input.attr(title)),field);
  345. if (input.hasClass('email') && !input.val().match( // RFC822 & RFC5322 Email validation
  346. new RegExp(/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.([a-z][a-z0-9]+)|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i)))
  347. error = new Array($cv.email,field);
  348. if ( input.attr('class') && ( chars = input.attr('class').match( new RegExp('min(\\d+)') ) ) ) {
  349. if (input.val() != "" && input.val().length < chars[1])
  350. error = new Array($cv.minlen.replace(/%s/,input.attr(title)).replace(/%d/,chars[1]),field);
  351. }
  352. if (input.hasClass('passwords')) {
  353. passwords.push(field);
  354. if (passwords.length == 2 && passwords[0].value != passwords[1].value)
  355. error = new Array($cv.pwdmm,passwords[1]);
  356. }
  357. if (error[1] && error[1].id == input.attr('id')) {
  358. input.addClass('error');
  359. label.addClass('error');
  360. }
  361. });
  362. $form.data('error', error).trigger('shopp_validate');
  363. if ( 'undefined' != form.shopp_validation )
  364. $form.data('error', form.shopp_validation);
  365. if ( $form.data('error') ) {
  366. error = $form.data('error');
  367. if (error[1] && $('#'+error[1].id).length > 0) {
  368. $('#'+error[1].id).addClass('error');
  369. $('label[for=' + error[1].id + ']').addClass('error');
  370. }
  371. }
  372. if (error.length > 0) {
  373. if ( error[1] instanceof jQuery )
  374. error[1].focus();
  375. if ($(form).hasClass('validation-alerts')) alert(error[0]);
  376. passed = false;
  377. }
  378. return passed;
  379. }
  380. /**
  381. * Auto-initialize form validation forms with a 'validate' class
  382. **/
  383. function validateForms () {
  384. jQuery('form.validate').on('submit.validate',function (e) {
  385. return validate(this);
  386. });
  387. }
  388. /**
  389. * DOM-ready initializations
  390. **/
  391. jQuery(document).ready(function($) {
  392. validateForms();
  393. catalogViewHandler();
  394. slideshows();
  395. carousels();
  396. if ($.fn.colorbox) {
  397. $('a.shopp-zoom').colorbox({photo:true});
  398. $('a.shopp-zoom.gallery').each(function () {
  399. var id = $(this).attr('class').match(/product\_(\d+)/)[1];
  400. if (typeof(cbo) != "undefined") $(this).attr('rel','gallery-'+id).colorbox(cbo);
  401. else $(this).attr('rel','gallery-'+id).colorbox({slideshow:true,slideshowSpeed:3500});
  402. });
  403. }
  404. $('select.shopp-orderby-menu').change(function () { this.form.submit(); });
  405. $('select.shopp-categories-menu').change(function () { document.location.href = $(this).val(); });
  406. if ($s.nocache) $(window).unload(function () { return; });
  407. });