PageSourceSearch

https://www.nirix.com/shout/web/v6.51.1.R20260831/shout/modules/store/resources/js/productquickview.js

js nirix.com collected 2026-09-29 09:33:57 UTC 18,451 bytes, 421 lines download raw bytes

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.