1(function($, $$, undefined){ 2 3 /** 4 * options: { 5 * 'dialog-id': string, // id of link or button that when it is clicked, it will make the quickview dialog open 6 * 'dialog-url': string, // url to load dialog's content 7 * 'dialog-class': string, // this is for styling, the dialog will have the class of "product-dialog product-dialog-{options[dialog-class']}" 8 * 'product-id': number, // id of the product 9 * 'product-url-target': string, // the target (e.g: _blank, _self, _parent, ...) of the product-url when users click on the product image or "VIEW FULL PRODUCT" button 10 * 'product-url': string, // the url of the product page 11 * 'qty-id': string, // the id of quantity field in parent page. The value of the field will be copied the quantity field in the dialog 12 * 'force_reload-id': string, // the id of the force_reload field of each "Add to Cart" button. If it is true, the page will be reloaded after the product is added to cart. 13 * }; 14 */ 15 var productquickview_initQuickviewDialog = function(options) 16 { 17 var old_body_width = false; 18 var old_body_overflow = false; 19 20 var old_dialog_height = false; 21 var old_dialog_width = false; 22 23 jQuery('#' + options['dialog-id']).click(function() { 24 var dlg_min_width = 300; 25 var dlg_max_width = 992; //700; 26 var dlg_width = 992; //'auto'; 27 var dlg_height = 'auto'; 28 var dlg_min_height = 300; 29 var dlg_max_height = 700; 30 31 var quickview_dialog = jQuery('<div></div>') 32 .dialog({ 33 autoOpen: false, 34 modal: true, 35 title: '', 36 minWidth: dlg_min_width, 37 maxWidth: dlg_max_width, 38 minHeight: dlg_min_height, 39 maxHeight: dlg_max_height, 40 draggable: false, 41 resizable: false, 42 width: dlg_width, 43 height: dlg_height, 44 /*position: { my: "center", at: "center", of: event },*/ 45 close: function() 46 { 47 var $body = jQuery('body'); 48 $body.css('overflow', old_body_overflow); 49 //$body.width(old_body_width); 50 $body.width('100%'); 51 52 old_body_overflow = false; 53 old_body_width = false; 54 55 $body.off('wheel.modal mousewheel.modal'); 56 57 jQuery(this).remove(); 58 }, 59 resizeStop: function() 60 { 61 if (dialog.options.maxWidth) 62 { 63 var wWidth = jQuery(window).width(); 64 65 // check window width against dialog width 66 if (wWidth < dialog.options.maxWidth + 50) 67 { 68 // keep dialog from filling entire screen 69 $this.parent('.ui-dialog').css("width", "90%"); 70 } 71 72 //reposition dialog 73 dialog.option("position", dialog.options.position); 74 } 75 }, 76 open: function() 77 { 78 var $this = jQuery(this); 79 80 var $self = $this; 81 82 var dialog = $this.data('ui-dialog'); 83 84 var requires_postioning = false; 85 86 var $body = jQuery('body'); 87 var inner_width = $body.innerWidth(); 88 89 if (false == old_body_width) 90 { 91 old_body_width = $body.width(); 92 } 93 94 if (false == old_body_overflow) 95 { 96 old_body_overflow = $body.css('overflow'); 97 } 98 99 $body.css('overflow', 'hidden'); 100 $body.width(inner_width); 101
102 $body.on('wheel.modal mousewheel.modal', 103 function () 104 { 105 dialog.option("position", dialog.options.position); 106 } 107 ); 108 109 if (dialog.options.maxWidth && dialog.options.width) 110 { 111 // fix maxWidth bug 112 $this.parent('.ui-dialog').css("max-width", dialog.options.maxWidth + "px"); 113 114 requires_postioning = true; 115 } 116 117 if (dialog.options.maxWidth) 118 { 119 var wWidth = jQuery(window).width(); 120 121 // check window width against dialog width 122 if (wWidth < dialog.options.maxWidth + 50) 123 { 124 if (false == old_dialog_width) 125 { 126 old_dialog_width = dialog.options.width; 127 } 128 129 // keep dialog from filling entire screen 130 $this.dialog('option', 'width', (wWidth - 30)); 131 132 requires_postioning = true; 133 } 134 else if (true == old_dialog_width) 135 { 136 $this.dialog('option', 'width', old_dialog_width); 137 old_dialog_width = false; 138 139 requires_postioning = true; 140 } 141 } 142 143 if (dialog.options.maxHeight) 144 { 145 var wHeight = jQuery(window).height(); 146 147 // check window width against dialog width 148 if (wHeight < dialog.options.maxHeight + 50) 149 { 150 if (false == old_dialog_height) 151 { 152 old_dialog_height = dialog.options.height; 153 } 154 155 // keep dialog from filling entire screen 156 $this.dialog('option', 'height', (wHeight - 30)); 157 158 requires_postioning = true; 159 } 160 else if (true == old_dialog_height) 161 { 162 $this.dialog('option', 'height', old_dialog_height); 163 old_dialog_height = false; 164 165 requires_postioning = true; 166 } 167 } 168 169 if (true === requires_postioning) 170 { 171 //reposition dialog 172 dialog.option("position", dialog.options.position); 173 } 174 175 // namespace window resize 176 jQuery(window).on("resize.responsive", 177 function () 178 { 179 var resize_requires_postioning = false; 180 181 var wWidth = jQuery(window).width(); 182 183 // check window width against dialog width 184 if (wWidth < dialog.options.maxWidth + 50) 185 { 186 if (true != old_dialog_width) 187 { 188 old_dialog_width = dialog.options.width; 189 } 190 191 // keep dialog from filling entire screen 192 $self.dialog('option', 'width', (wWidth - 30)); 193 194 requires_postioning = true; 195 } 196 else if (true == old_dialog_width) 197 { 198 $self.dialog('option', 'width', old_dialog_width); 199 old_dialog_width = null; 200 } 201 202 var wHeight = jQuery(window).height(); 203 204 // check window width against dialog width 205 if (wHeight < dialog.options.maxHeight + 50) 206 { 207 if (true != old_dialog_height) 208 { 209 old_dialog_height = dialog.options.height; 210 } 211 // keep dialog from filling entire screen 212 $self.dialog('option', 'height', (wHeight - 30)); 213 214 requires_postioning = true; 215 } 216 else if (true == old_dialog_height) 217 { 218 $self.dialog('option', 'height', old_dialog_height); 219 old_dialog_height = null; 220 } 221 222 if (true === resize_requires_postioning) 223 { 224 //reposition dialog 225 dialog.option("position", dialog.options.position); 226 } 227 } 228 ); 229 230 requires_postioning = false;
231 }, 232 buttons: [ 233 { 234 text: 'View Full Product', 235 class: 'button-view-product', 236 }, 237 { 238 text: 'Close', 239 click: function() { jQuery(this).dialog('close'); }, 240 class: 'button-close-dialog', 241 } 242 ], 243 show: 100 /*{ effect: 'scale', duration: 150 }*/, 244 hide: 100 /*{ effect: 'scale', duration: 100 }*/ 245 }) 246 .load(options['dialog-url'], function(response, status, xhr) { 247 // check for server errors 248 if (status == 'error') { 249 console.error('Dialog error: ' + xhr.status + ' ' + xhr.statusText); 250 //quickview_dialog.dialog('close'); 251 return; 252 } 253 254 // add product link 255 var target_html = ''; 256 if (options['product-url-target']) 257 { 258 quickview_dialog.parent().find('.category-product-image > a').attr('target', options['product-url-target']); 259 target_html = ' target="' + options['product-url-target'] + '"'; 260 } 261 quickview_dialog.parent().find('.button-view-product').wrap('<a href="' + options['product-url'] + '"' + target_html + '></a>'); 262 263 // show dialog 264 quickview_dialog.dialog('open'); 265 quickview_dialog.parent().css('visibility', 'visible'); 266 //quickview_dialog.parent().addClass('product-category fullwidth'); 267 quickview_dialog.parent().addClass('product-dialog product-dialog-' + options['dialog-class']); 268 quickview_dialog.prepend('<input type="hidden" autofocus="autofocus" />'); 269 270 // copy quantity from parent page 271 if (jQuery('#' + options['qty-id']).length && jQuery(this).find('.add_to_cart-qty').length) { 272 jQuery(this).find('.add_to_cart-qty').val(jQuery('#' + options['qty-id']).val()).trigger('input'); 273 } 274 275 // on add to cart copy message to parent page 276 jQuery(this).find('.add_to_cart-form a').click(function() { 277 var $add_to_cart = jQuery(this).closest('.add_to_cart-form'); 278 var key = $add_to_cart.data('add_to_cart-key'); 279 280 var msg = jQuery(this).siblings('.add_to_cart-message'); 281 var msg_parent = jQuery('#' + options['dialog-id']) 282 .parents('.list-item-product').find('.add_to_cart-message'); 283// .siblings('.add_to_cart-message'); 284 var close_dialog = true; 285 286 var add_to_cart_success_fn = function(){ 287 msg.css('display', 'none'); 288 289 //jQuery('#{$params['dialog-id']}').parent().append(msg.clone()/*.css('display', 'block')*/); 290 if (true === close_dialog) 291 { 292 quickview_dialog.dialog('close'); 293 } 294 295 msg_parent.html(msg.html()); 296 }; 297 var add_to_cart_failure_fn = function(){ 298 msg.get(0).scrollIntoView(); 299 }; 300 301 msg_parent.html(''); 302 303 var is_adding = $add_to_cart.hasClass('add_to_cart-form--adding'); 304 var is_successful = $add_to_cart.hasClass('add_to_cart-form--success'); 305 var is_failed = $add_to_cart.hasClass('add_to_cart-form--failed'); 306 307 if (is_adding) 308 { 309 var timeout = 1000 * 60; // how long should wait for add to cart button to finish 310 var now = Date.now(); 311 var until = now + timeout; 312 313 if (window.MutationObserver) 314 { 315 var observer_config = { 316 attributes: true, 317 attributeFilter: ['class'], 318 }; 319 var observer_targetNode = $add_to_cart.get(0); 320 var observer_callback = function(mutations) { 321 mutations.forEach((mutation) => { 322 if (mutation.attributeName === 'class') 323 { 324 var is_adding = $add_to_cart.hasClass('add_to_cart-form--adding'); 325 var is_successful = $add_to_cart.hasClass('add_to_cart-form--success'); 326 var is_failed = $add_to_cart.hasClass('add_to_cart-form--failed'); 327 328 if (!is_adding && Date.now() > now+1000) 329 { 330 observer.disconnect(); 331 } 332 333 if (is_failed) 334 { 335 observer.disconnect(); 336 add_to_cart_failure_fn(); 337 } 338 339 if (is_successful) 340 { 341 observer.disconnect(); 342 add_to_cart_success_fn(); 343 } 344 } 345 }); 346 }; 347 348 var observer = new MutationObserver(observer_callback); 349 350 if (observer_targetNode) 351 { 352 observer.observe(observer_targetNode, observer_config); 353 } 354 } 355 else 356 { 357 var interval = setInterval(function() { 358 if (Date.now() > until) 359 { 360 var show_interval_timeout_error = false;
361 if (show_interval_timeout_error) 362 { 363 var m = "<div class=\"errorText add_to_cart_message add_to_cart_message--error add_to_cart_message--add_to_cart_timeout\">add to cart timed out.</div>"; 364 cart_Message(m, key) 365 cart_ButtonUpdate('failed', key) 366 } 367 368 clearInterval(interval); 369 return; 370 } 371 372 var is_adding = $add_to_cart.hasClass('add_to_cart-form--adding'); 373 var is_successful = $add_to_cart.hasClass('add_to_cart-form--success'); 374 var is_failed = $add_to_cart.hasClass('add_to_cart-form--failed'); 375 376 if (!is_adding) 377 { 378 clearInterval(interval); 379 } 380 381 if (is_failed) 382 { 383 clearInterval(interval); 384 add_to_cart_failure_fn(); 385 } 386 387 if (is_successful) 388 { 389 clearInterval(interval); 390 add_to_cart_success_fn(); 391 } 392 }, 100); 393 } 394 } 395 else if (is_failed) 396 { 397 add_to_cart_failure_fn(); 398 } 399 else if (is_successful) 400 { 401 add_to_cart_success_fn(); 402 } 403 }); 404 405 // reload page on add to cart 406 if ((jQuery('#' + options['force_reload-id']).length) && 407 (jQuery('#' + options['force_reload-id']).val() == 1)) { 408 top.jQuery(top.document).on('shoutcms_cart_changed', function() { 409 top.location.reload(true); 410 }); 411 } 412 }); 413 }); 414 }; 415 416 417 $$.helpers.productquickview = { 418 initQuickviewDialog: productquickview_initQuickviewDialog 419 }; 420 421})(jQuery, Shout);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.