PageSourceSearch

https://fastlikes.fr/wp-content/plugins/woo-ins/js/ins-template.js?ver=1.2.0

js fastlikes.fr collected 2026-10-05 01:21:24 UTC 9,287 bytes, 262 lines download raw bytes

1/**
2 * WooCommerce Instagram Product - Template JavaScript
3 *
4 * Handles image picker initialization, AJAX pagination,
5 * form validation, and selection persistence.
6 *
7 * @package WooInsProduct
8 * @since   1.2.0
9 */
10
11/* global jQuery, wooInsData */
12
13(function ($) {
14    'use strict';
15
16    /**
17     * Update the selection display (counts, per-post amounts, overlays).
18     *
19     * @param {number} insLikes Total likes/views to distribute.
20     */
21    function updateSelectionDisplay(insLikes) {
22        var values = $('.image-picker').val();
23
24        if (values != null && values.length > 0) {
25            var count = values.length;
26            var likesPerPost = Math.round(insLikes / count);
27
28            $('span.ins_selected_posts').text(count);
29            $('span.ins_likes').text(likesPerPost);
30            $('span.append_span').text(' + ' + likesPerPost);
31        } else {
32            $('span.ins_selected_posts').text('0');
33            $('span.ins_likes').text('0');
34            $('span.append_span').text('');
35        }
36    }
37
38    /**
39     * Ensure all thumbnails have an append_span element.
40     * Avoids duplicates by checking if one already exists.
41     */
42    function ensureAppendSpans() {
43        $('.thumbnail p').each(function () {
44            if (!$(this).find('.append_span').length) {
45                $(this).append('<span class="append_span" style="display:none;"></span>');
46            }
47        });
48    }
49
50    /**
51     * Initialize image picker with callbacks for selection tracking.
52     * Called on initial load and after AJAX appends new options.
53     *
54     * Preserves existing selections when reinitializing (load more).
55     */
56    function loadImagePicker() {
57        var insLikes = parseInt($('.image-picker').closest('form').find('input[name="qty"]').val(), 10) || 0;
58        var noLikesMsg = $('.image-picker').data('no-likes-msg') || '';
59
60        // Save current selections before reinitializing
61        var currentSelections = $('select.image-picker').val() || [];
62
63        $('.image-picker').imagepicker({
64            limit_reached: function () {
65                alert(noLikesMsg);
66            },
67            show_label: true,
68            hide_select: true,
69            initialized: function () {
70                $('.loaded_1').fadeOut('slow');
71                $('.s_btn').removeClass('btn-busy');
72
73                // Restore selections after reinitialization
74                if (currentSelections.length > 0) {
75                    $('select.image-picker').val(currentSelections);
76                    // Sync visual state with select value
77                    currentSelections.forEach(function (val) {
78                        $('select.image-picker option').filter(function () {
79                            return $(this).val() === val;
80                        }).prop('selected', true);
81                    });
82                    // Re-trigger image picker to reflect selections
83                    $('select.image-picker').data('picker').sync_picker_with_select();
84                }
85
86                ensureAppendSpans();
87                updateSelectionDisplay(insLikes);
88            },
89            clicked: function () {
90                ensureAppendSpans();
91                updateSelectionDisplay(insLikes);
92            }
93        });
94
95        ensureAppendSpans();
96    }
97
98    /**
99     * Validate form: ensure at least one post is selected.
100     *
101     * @return {boolean} True if valid, false otherwise.
102     */
103    function notifyEmpty() {
104        var form = document.forms['myForm'];
105        if (!form) {
106            return false;
107        }
108
109        var x = form['fname[]'];
110        if (!x || x.value === '' || (x.selectedOptions && x.selectedOptions.length === 0)) {
111            alert(wooInsData.selectPostAlert);
112            return false;
113        }
114
115        document.getElementById('myForm').submit();
116        return true;
117    }
118
119    // Expose globally for form onsubmit attribute
120    window.notifyempty = notifyEmpty;
121    window.loadImagePicker = loadImagePicker;
122
123    $(document).ready(function () {
124        // Initialize image picker if present
125        if ($('.image-picker').length) {
126            loadImagePicker();
127        }
128
129        // Show all thumbnails
130        $('ul.thumbnails.image_picker_selector li').show();
131
132        // Load More button - AJAX pagination
133        $('#loadMore').on('click', function (e) {
134            var that = this;
135            e.preventDefault();
136
137            var offset = $(this).attr('data-offset');
138            var insName = $(this).attr('data-ins-name');
139            var productId = $(this).attr('data-product-id');
140            var isLoading = $(this).attr('data-is-loading');
141
142            if (isLoading === 'true') {
143                return;
144            }
145
146            var formData = {
147                action: 'prismLoadIgPosts',
148                _nonce: wooInsData.nonce,
149                ins_name: insName,
150                product_id: productId,
151                offset: offset
152            };
153
154            $.ajax({
155                dataType: 'json',
156                type: 'POST',
157                data: formData,
158                url: wooInsData.ajaxUrl,
159                beforeSend: function () {
160                    $('.loaded_2').fadeIn('slow');
161                    $(that).addClass('disabled');
162                    $(that).attr('data-is-loading', 'true');
163                },
164                complete: function () {
165                    $('.loaded_2').fadeOut('slow');
166                    $(that).attr('data-is-loading', 'false');
167                    $(that).removeClass('disabled');
168                },
169                success: function (response) {
170                    var items = response.items;
171                    var nextOffset = response.nextOffset;
172
173                    if (items) {
174                        // Save current selections before appending & reinitializing
175                        var savedSelections = $('select.image-picker').val() || [];
176
177                        $('#loadMore').attr('data-offset', nextOffset);
178                        $('select.image-picker').append(items);
179
180                        // Restore selections on the <select> before reinit
181                        $('select.image-picker').val(savedSelections);
182
183                        loadImagePicker();
184                    }
185
186                    if (!nextOffset) {
187                        $('#loadMore').fadeOut('slow');
188                    }
189                }
190            });
191        });
192
193        // Submit button validation and loading state
194        $('.s_btn').on('click', function (e) {
195            e.preventDefault();
196
197            var form = document.forms['myForm'];
198            if (!form) {
199                return false;
200            }
201
202            var x = form['fname[]'];
203            if (!x || x.value === '' || (x.selectedOptions && x.selectedOptions.length === 0)) {
204                alert(wooInsData.selectPostAlert);
205                return false;
206            }
207
208            $(this).addClass('btn-busy');
209            // Double rAF ensures a repaint before navigation (spinner visible on mobile)
210            requestAnimationFrame(function () {
211                requestAnimationFrame(function () {
212                    form.submit();
213                });
214            });
215        });
216
217        // Add to cart button loading state (Step 0 "Suivant" and Step 2 "Procéder au paiement")
218        $(document).on('click', 'button.single_add_to_cart_button', function (e) {
219            e.preventDefault();
220            var form = $(this).closest('form')[0];
221            var $form = $(form);
222
223            // Validate required fields (e.g., speed_of_delivery on Step 2)
224            if (!form.checkValidity()) {
225                form.reportValidity();
226                return;
227            }
228
229            // Step 0: ensure a variation is selected (variation_id must not be 0)
230            var variationInput = $form.find('input.variation_id');
231            if (variationInput.length && (!variationInput.val() || variationInput.val() === '0')) {
232                // Highlight the variation selects to draw attention
233                $form.find('table.variations select').css('border-color', '#c0392b');
234                setTimeout(function () {
235                    $form.find('table.variations select').css('border-color', '');
236                }, 2000);
237                return;
238            }
239
240            var insNameInput = $('input[name="ins_name"]');
241            // If there's an ins_name field, only activate spinner when it has a value
242            if (insNameInput.length === 0 || insNameInput.val() !== '') {
243                $(this).addClass('btn-busy').addClass('disabled');
244                // Double rAF ensures a repaint before navigation (spinner visible on mobile)
245                requestAnimationFrame(function () {
246                    requestAnimationFrame(function () {
247                        form.submit();
248                    });
249                });
250            }
251        });
252    });
253
254    // Show "Prix :" label only when a variation is selected
255    $(document).on('found_variation', '.variations_form', function () {
256        $('.wooins-step0-price-label').show();
257    });
258    $(document).on('hide_variation reset_data', '.variations_form', function () {
259        $('.wooins-step0-price-label').hide();
260    });
261
262})(jQuery);

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.