1 | jQuery(function($) {
|
---|
2 |
|
---|
3 | // Mobile sidebars
|
---|
4 | $.fn.expandableSidebar = function(expandedClass) {
|
---|
5 | var $me = this;
|
---|
6 |
|
---|
7 | $me.on('click', function() {
|
---|
8 | if(!$me.hasClass(expandedClass)) {
|
---|
9 | $me.addClass(expandedClass);
|
---|
10 | } else {
|
---|
11 | $me.removeClass(expandedClass);
|
---|
12 | }
|
---|
13 | });
|
---|
14 | }
|
---|
15 |
|
---|
16 | // Interval loop
|
---|
17 | $.fn.intervalLoop = function(condition, action, duration, limit) {
|
---|
18 | var counter = 0;
|
---|
19 | var looper = setInterval(function(){
|
---|
20 | if (counter >= limit || $.fn.checkIfElementExists(condition)) {
|
---|
21 | clearInterval(looper);
|
---|
22 | } else {
|
---|
23 | action();
|
---|
24 | counter++;
|
---|
25 | }
|
---|
26 | }, duration);
|
---|
27 | }
|
---|
28 |
|
---|
29 | // Check if element exists
|
---|
30 | $.fn.checkIfElementExists = function(selector) {
|
---|
31 | return $(selector).length;
|
---|
32 | }
|
---|
33 |
|
---|
34 | var duskController = {
|
---|
35 |
|
---|
36 | init: function(opts) {
|
---|
37 | var base = this;
|
---|
38 |
|
---|
39 | // Add classes to elements
|
---|
40 | base._addClasses();
|
---|
41 |
|
---|
42 | base._headerSetup();
|
---|
43 | base._searchSetup();
|
---|
44 | base._miniCartSetup();
|
---|
45 | // base._loginSetup(false);
|
---|
46 | base._breadcrumbs();
|
---|
47 | base._mobileNav();
|
---|
48 | base._quantityInput();
|
---|
49 |
|
---|
50 | setTimeout(function() {
|
---|
51 | base._checkCartItems();
|
---|
52 | base._attachEvents();
|
---|
53 | base._loginSetup(true);
|
---|
54 | }, 1000);
|
---|
55 | },
|
---|
56 |
|
---|
57 | _utils: {
|
---|
58 | onEscKey: function(callback) {
|
---|
59 | $(document).on('keyup', function(event) {
|
---|
60 | if (event.keyCode === 27) callback();
|
---|
61 | });
|
---|
62 | },
|
---|
63 | },
|
---|
64 |
|
---|
65 | _addClasses: function() {
|
---|
66 | var base = this;
|
---|
67 |
|
---|
68 | // Add class to nav items with subnav
|
---|
69 | $('.wsite-menu-default').find('li.wsite-menu-item-wrap').each(function(){
|
---|
70 | var $me = $(this);
|
---|
71 |
|
---|
72 | if($me.children('.wsite-menu-wrap').length > 0) {
|
---|
73 |
|
---|
74 | $me.addClass('has-submenu');
|
---|
75 | $('<span class="icon-caret"></span>').insertAfter($me.children('a.wsite-menu-item'));
|
---|
76 | }
|
---|
77 | });
|
---|
78 |
|
---|
79 | // Add class to subnav items with subnav
|
---|
80 | $('.wsite-menu').find('li.wsite-menu-subitem-wrap').each(function(){
|
---|
81 | var $me = $(this);
|
---|
82 |
|
---|
83 | if($me.children('.wsite-menu-wrap').length > 0) {
|
---|
84 |
|
---|
85 | $me.addClass('has-submenu');
|
---|
86 | $('<span class="icon-caret"></span>').insertAfter($me.children('a.wsite-menu-subitem'));
|
---|
87 | }
|
---|
88 | });
|
---|
89 |
|
---|
90 | // Keep subnav open if submenu item is active
|
---|
91 | $('li.wsite-menu-subitem-wrap.wsite-nav-current').parents('.wsite-menu-wrap').addClass('open');
|
---|
92 |
|
---|
93 | // Add placeholder text to inputs
|
---|
94 | $.fn.intervalLoop('', function() {
|
---|
95 | $('.wsite-form-sublabel').each(function(){
|
---|
96 | var sublabel = $(this).text();
|
---|
97 | $(this).prev('.wsite-form-input').attr('placeholder', sublabel);
|
---|
98 | });
|
---|
99 | }, 1000, 5);
|
---|
100 |
|
---|
101 | // Add fullwidth class to gallery thumbs if less than 6
|
---|
102 | $('.imageGallery').each(function(){
|
---|
103 | if ($(this).children('div').length <= 6) {
|
---|
104 | $(this).children('div').addClass('fullwidth-mobile');
|
---|
105 | }
|
---|
106 | });
|
---|
107 | },
|
---|
108 |
|
---|
109 | _headerSetup: function() {
|
---|
110 | var $desktopNav = $('.desktop-nav .wsite-menu-default');
|
---|
111 | if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) {
|
---|
112 | $desktopNav.pxuMenu({
|
---|
113 | moreLinkHtml: 'More...',
|
---|
114 | });
|
---|
115 | $.fn.intervalLoop('', function() {
|
---|
116 | if ($desktopNav.data('pxuMenu')) {
|
---|
117 | $desktopNav.data('pxuMenu').update();
|
---|
118 | }
|
---|
119 | }, 500, 10);
|
---|
120 | }
|
---|
121 |
|
---|
122 | $(document.body).addClass('reveal-elements');
|
---|
123 |
|
---|
124 | // Banner
|
---|
125 | $('.banner .wsite-section-elements').each(function() {
|
---|
126 | if (!$.trim($(this).html()).length) {
|
---|
127 | $(this).parent().addClass('banner-empty');
|
---|
128 | }
|
---|
129 | });
|
---|
130 |
|
---|
131 | $(window).scroll(function() {
|
---|
132 | if ($('.sticky-nav-off').length) return;
|
---|
133 | $('body').toggleClass('header-compressed', $(this).scrollTop() > 300);
|
---|
134 | });
|
---|
135 | },
|
---|
136 |
|
---|
137 | _searchSetup: function() {
|
---|
138 | var base = this;
|
---|
139 | var searchBox = '.wsite-search';
|
---|
140 | var searchToggle = '.search-toggle';
|
---|
141 | function toggleSearch(action) {
|
---|
142 | $(searchToggle).toggleClass('is-active', (action === 'toggle' ? '' : false));
|
---|
143 | $(searchBox).revealer(action);
|
---|
144 | };
|
---|
145 | function toggleSearchClass() {
|
---|
146 | $('body').toggleClass('has-site-search', !!$('.wsite-search').length);
|
---|
147 | }
|
---|
148 |
|
---|
149 | toggleSearchClass();
|
---|
150 | $.fn.intervalLoop('', function() {
|
---|
151 | // When search is disabled, the input is in the dom,
|
---|
152 | // but th editor attaches an inline display: none;
|
---|
153 | // so don't toggle the class
|
---|
154 | if ($('.wsite-search').attr('style') === 'display: none;') return;
|
---|
155 | toggleSearchClass();
|
---|
156 | }, 1000, 5);
|
---|
157 |
|
---|
158 | $(searchBox)
|
---|
159 | .on('revealer-show', function(event) {
|
---|
160 | $(event.currentTarget).find('.wsite-search-input').focus();
|
---|
161 | })
|
---|
162 | .find('.wsite-search-input')
|
---|
163 | // .attr('placeholder', 'Type and press enter to search')
|
---|
164 | .on('blur', function() {
|
---|
165 | setTimeout(function() {
|
---|
166 | toggleSearch('hide');
|
---|
167 | }, 300);
|
---|
168 | });
|
---|
169 |
|
---|
170 | $(document).on('click', searchToggle, function(event) {
|
---|
171 | event.preventDefault();
|
---|
172 | if ($(searchToggle).hasClass('is-active')) {
|
---|
173 | toggleSearch('hide');
|
---|
174 | }
|
---|
175 | else {
|
---|
176 | toggleSearch('toggle');
|
---|
177 | }
|
---|
178 | });
|
---|
179 |
|
---|
180 | base._utils.onEscKey(function() {
|
---|
181 | if (!$(searchBox).revealer('isVisible')) return;
|
---|
182 | toggleSearch('hide');
|
---|
183 | });
|
---|
184 | },
|
---|
185 |
|
---|
186 | _miniCartSetup: function() {
|
---|
187 | var base = this;
|
---|
188 | var cartOpenClass = 'minicart-visible';
|
---|
189 |
|
---|
190 | var toggleMinicart = function(state) {
|
---|
191 | $('body').toggleClass(cartOpenClass, state);
|
---|
192 | };
|
---|
193 |
|
---|
194 | // Override the header icon / toggle button
|
---|
195 | var hijackMinicartToggle = function() {
|
---|
196 | var $cartToggle = $('#wsite-nav-cart-a');
|
---|
197 | var subtotal = $('#wsite-mini-cart .wsite-subtotal-wrapper')
|
---|
198 | .clone()
|
---|
199 | .children(':not(.wsite-price)')
|
---|
200 | .remove()
|
---|
201 | .end()
|
---|
202 | .children()
|
---|
203 | .unwrap()
|
---|
204 | .end()
|
---|
205 | .text();
|
---|
206 | var count = 0;
|
---|
207 | $('#wsite-mini-cart .wsite-product-item').each(function() {
|
---|
208 | count += parseInt($(this).find('.wsite-product-price').text(), 10);
|
---|
209 | });
|
---|
210 | var items = count === 1 ? 'item' : 'items';
|
---|
211 | var templateData = {
|
---|
212 | subtotal: $.trim(subtotal),
|
---|
213 | count: count,
|
---|
214 | items: items
|
---|
215 | };
|
---|
216 |
|
---|
217 | $cartToggle
|
---|
218 | .off('click mouseenter mouseover mouseleave mouseout')
|
---|
219 | .empty()
|
---|
220 | .loadTemplate($('#mini-cart-template'), templateData)
|
---|
221 | .addClass('is-visible')
|
---|
222 | .find('.price-wrap')
|
---|
223 | .toggleClass('no-items', !count);
|
---|
224 |
|
---|
225 | $('.mini-cart-toggle').toggleClass('has-mini-cart', !!$('.mini-cart').children().length);
|
---|
226 |
|
---|
227 | // Update responsive menu since site-utils dimesions will change
|
---|
228 | if (typeof DISABLE_NAV_MORE == 'undefined' || !DISABLE_NAV_MORE) {
|
---|
229 | $('.desktop-nav .wsite-menu-default').data('pxuMenu').update();
|
---|
230 | }
|
---|
231 | };
|
---|
232 |
|
---|
233 | // Override the minicart panel
|
---|
234 | var hijackMinicart = function() {
|
---|
235 | $('#wsite-mini-cart')
|
---|
236 | .off('mouseenter mouseover mouseleave mouseout')
|
---|
237 | .removeClass('arrow-top')
|
---|
238 | .removeAttr('style')
|
---|
239 | .prepend($('.mini-cart-header'))
|
---|
240 | .appendTo($('.wrapper'));
|
---|
241 | };
|
---|
242 |
|
---|
243 | // Bind minicart events
|
---|
244 | $(document).on('click', '.wsite-nav-cart', function(event) {
|
---|
245 | event.preventDefault();
|
---|
246 | toggleMinicart('');
|
---|
247 | });
|
---|
248 |
|
---|
249 | $(document).on('click', '.button-mini-cart-close, .mini-cart-screen', function(event) {
|
---|
250 | event.preventDefault();
|
---|
251 | toggleMinicart(false);
|
---|
252 | });
|
---|
253 |
|
---|
254 | base._utils.onEscKey(function() {
|
---|
255 | if ($('body').hasClass(cartOpenClass)) {
|
---|
256 | toggleMinicart(false);
|
---|
257 | }
|
---|
258 | });
|
---|
259 |
|
---|
260 | // Watch for minicart
|
---|
261 |
|
---|
262 | base._observeDom(document, function(docObserver, target, config) {
|
---|
263 | // Bail if minicart & toggle not available yet
|
---|
264 | if (!$('#wsite-mini-cart').length || !$('#wsite-nav-cart-a').length) return;
|
---|
265 | // Watch minicart
|
---|
266 | base._observeDom($('#wsite-mini-cart')[0], function(observer, target, config) {
|
---|
267 | observer.disconnect();
|
---|
268 | hijackMinicart();
|
---|
269 | hijackMinicartToggle();
|
---|
270 | observer.observe(target, config);
|
---|
271 | });
|
---|
272 | // Watch toggle (sometimes default toggle updates after cart)
|
---|
273 | base._observeDom($('#wsite-nav-cart-a')[0], function(observer, target, config) {
|
---|
274 | observer.disconnect();
|
---|
275 | hijackMinicartToggle();
|
---|
276 | observer.observe(target, config);
|
---|
277 | });
|
---|
278 | // minicart available, so stop watching the doc
|
---|
279 | docObserver.disconnect();
|
---|
280 | }, { subtree: true });
|
---|
281 | },
|
---|
282 |
|
---|
283 | _checkCartItems: function() {
|
---|
284 | var base = this;
|
---|
285 |
|
---|
286 | if ($('#wsite-mini-cart').find('li.wsite-product-item').length > 0) {
|
---|
287 | $('body').addClass('cart-full');
|
---|
288 | } else {
|
---|
289 | $('body').removeClass('cart-full');
|
---|
290 | }
|
---|
291 | },
|
---|
292 |
|
---|
293 | _loginSetup: function(editorDisplay) {
|
---|
294 | var linkText = $('#wsite-nav-login-a').text();
|
---|
295 | var mobileLink = $('#member-login').clone(true);
|
---|
296 | function toggleLogin() {
|
---|
297 | $('.header-login').toggle(!!$('#wsite-nav-login-a').length);
|
---|
298 | }
|
---|
299 |
|
---|
300 | toggleLogin();
|
---|
301 | $.fn.intervalLoop('', toggleLogin, 500, 5);
|
---|
302 |
|
---|
303 | $(document).on('click', '.header-login', function() {
|
---|
304 | $('#wsite-nav-login-a').trigger('click');
|
---|
305 | });
|
---|
306 |
|
---|
307 | $('.mobile-login')
|
---|
308 | .appendTo('.mobile-nav .wsite-menu-default');
|
---|
309 |
|
---|
310 | $(mobileLink)
|
---|
311 | .appendTo('.mobile-login').children('a').addClass('wsite-menu-item');
|
---|
312 |
|
---|
313 | // .loadTemplate($('#login-template'), { login: linkText });
|
---|
314 | },
|
---|
315 |
|
---|
316 | _breadcrumbs: function() {
|
---|
317 | var $breadcrumbs = $('#wsite-com-breadcrumbs');
|
---|
318 |
|
---|
319 | $breadcrumbs.insertBefore($breadcrumbs.closest('.container'));
|
---|
320 |
|
---|
321 | $(document.body).toggleClass('page-has-breadcrumbs', !!$breadcrumbs.length);
|
---|
322 | },
|
---|
323 |
|
---|
324 | _mobileNav: function() {
|
---|
325 | $('.hamburger, .mobile-nav-toggle').on('click', function() {
|
---|
326 | $('.mobile-nav').revealer('toggle');
|
---|
327 | $(document.body).toggleClass('mobile-nav-open');
|
---|
328 | });
|
---|
329 |
|
---|
330 | $('.icon-caret').on('click', function() {
|
---|
331 | $(this)
|
---|
332 | .toggleClass('is-active')
|
---|
333 | .next('.wsite-menu-wrap')
|
---|
334 | .revealer('toggle');
|
---|
335 | });
|
---|
336 | },
|
---|
337 |
|
---|
338 | _attachEvents: function() {
|
---|
339 | var base = this;
|
---|
340 |
|
---|
341 | // Store category dropdown
|
---|
342 | $('.wsite-com-sidebar').expandableSidebar('sidebar-expanded');
|
---|
343 |
|
---|
344 | // Search filters dropdown
|
---|
345 | $('#wsite-search-sidebar').expandableSidebar('sidebar-expanded');
|
---|
346 |
|
---|
347 | // Init fancybox swipe on mobile
|
---|
348 | if ('ontouchstart' in window) {
|
---|
349 | $('body').on('click', 'a.w-fancybox', function() {
|
---|
350 | base._initSwipeGallery();
|
---|
351 | });
|
---|
352 | }
|
---|
353 |
|
---|
354 | $("body.wsite-editor .wsite-search").append($(".icon-search").clone());
|
---|
355 | },
|
---|
356 |
|
---|
357 | _initSwipeGallery: function() {
|
---|
358 | var base = this;
|
---|
359 |
|
---|
360 | setTimeout(function(){
|
---|
361 | var touchGallery = document.getElementsByClassName('fancybox-wrap')[0];
|
---|
362 | var mc = new Hammer(touchGallery);
|
---|
363 | mc.on("panleft panright", function(ev) {
|
---|
364 | if (ev.type == "panleft") {
|
---|
365 | $("a.fancybox-next").trigger("click");
|
---|
366 | } else if (ev.type == "panright") {
|
---|
367 | $("a.fancybox-prev").trigger("click");
|
---|
368 | }
|
---|
369 | base._initSwipeGallery();
|
---|
370 | });
|
---|
371 | }, 500);
|
---|
372 | },
|
---|
373 |
|
---|
374 | _quantityInput: function() {
|
---|
375 | var $input = $('#wsite-com-product-quantity-input');
|
---|
376 | var button = 'button-quantity';
|
---|
377 |
|
---|
378 | function setValues($input) {
|
---|
379 | return {
|
---|
380 | value : parseInt($input.val(), 10),
|
---|
381 | min : $input.attr('min') ? parseInt($input.attr('min'), 10) : 0,
|
---|
382 | max : $input.attr('max') ? parseInt($input.attr('max'), 10) : Infinity,
|
---|
383 | }
|
---|
384 | }
|
---|
385 |
|
---|
386 | // Set up controls
|
---|
387 | $input
|
---|
388 | .after('<button class="'+ button +' plus" data-quantity-control="increment" />')
|
---|
389 | .after('<button class="'+ button +' minus" data-quantity-control="decrement" />');
|
---|
390 |
|
---|
391 | // Bind clicks
|
---|
392 | $(document).on('click', '.' + button, function(event) {
|
---|
393 | event.preventDefault();
|
---|
394 |
|
---|
395 | var $target = $(event.target);
|
---|
396 | var action = $target.attr('data-quantity-control');
|
---|
397 | var $quantityInput = $target.siblings($input.selector);
|
---|
398 | var values = setValues($quantityInput);
|
---|
399 |
|
---|
400 | if (action === 'increment' && values.value < values.max) {
|
---|
401 | $quantityInput.val(values.value + 1).trigger('change');
|
---|
402 | } else if (action === 'decrement' && values.value > 0 && values.value > values.min) {
|
---|
403 | $quantityInput.val(values.value - 1).trigger('change');
|
---|
404 | }
|
---|
405 | });
|
---|
406 |
|
---|
407 | // Validate change
|
---|
408 | $input.on('change', function(event) {
|
---|
409 | var $target = $(event.target);
|
---|
410 | var values = setValues($target);
|
---|
411 |
|
---|
412 | if (values.value >= values.max) {
|
---|
413 | $target.val(values.max).addClass('val-max');
|
---|
414 | } else if (values.value <= values.min) {
|
---|
415 | $target.val(values.min).addClass('val-min');
|
---|
416 | } else {
|
---|
417 | $target.removeClass('val-max val-min');
|
---|
418 | }
|
---|
419 | });
|
---|
420 | },
|
---|
421 | _observeDom: function(target, callback, config) {
|
---|
422 | var config = $.extend({
|
---|
423 | attributes: true,
|
---|
424 | childList: true,
|
---|
425 | characterData: true
|
---|
426 | }, config);
|
---|
427 | // create an observer instance & callback
|
---|
428 | var observer = new MutationObserver(function(mutations) {
|
---|
429 | // Using every() instead of forEach() allows us to short-circuit the observer in the callback
|
---|
430 | mutations.every(function(mutation) {
|
---|
431 | callback(observer, target, config, mutation);
|
---|
432 | });
|
---|
433 | });
|
---|
434 | // pass in the target node, as well as the observer options
|
---|
435 | observer.observe(target, config);
|
---|
436 | }
|
---|
437 | }
|
---|
438 |
|
---|
439 | $(document).ready(function(){
|
---|
440 | duskController.init();
|
---|
441 | });
|
---|
442 | });
|
---|