PageSourceSearch

https://www.cefaly.com/wp-content/plugins/quiz-master-next/renderer/assets/js/qsm-progressbar.js?ver=11.2.6

js cefaly.com collected 2026-09-25 04:30:47 UTC 7,394 bytes, 180 lines download raw bytes

1/**
2 * QSM Progress Bar - Minimized
3 * @package QSM
4 */
5(function($) {
6    QSMPagination.ProgressBar = {
7        quizObjects: {},
8
9        init: function() {
10            const self = this;
11            // Look for quiz containers first (new structure)
12            $('.qsm-quiz-container').each(function() {
13                const $container = $(this);
14                const $form = $container.find('.qsm-quiz-form');
15                const quizId = $container.data('quiz-id');
16                if (quizId && !self.quizObjects[quizId]) {
17                    self.initProgressBar(quizId, $container, $form);
18                }
19            });
20            
21            this.bindEvents();
22        },
23
24        initProgressBar: function(quizId, $container, $form, $initial_page = 1) {
25            const data = qmn_quiz_data && qmn_quiz_data[quizId] ? qmn_quiz_data[quizId] : {};
26            if (!data.progress_bar || Number(data.progress_bar) === 0) return;
27            
28            // Look for progress bar in container first, then form (for new structure)
29            let $bar = jQuery('.qsm-progress-bar-' + quizId);
30
31            if (!$bar.length) return;
32
33            // Determine render mode: 'auto' | 'svg' | 'simple' (provided via data-progress-mode)
34            let mode = $bar.data('progress-mode') || 'auto';
35
36            // Count pages - use same selectors as navigation system
37            const $pages = $container.find('.qsm-page');
38            const totalPages = Math.max($pages.length, 1);
39            
40            // Calculate question pages (exclude first page if present)
41            const hasFirstPage = (Number(data.disable_first_page) !== 1);
42            const questionPages = hasFirstPage ? totalPages - 1 : totalPages;
43            
44            this.quizObjects[quizId] = {
45                $container: $container,
46                $form: $form,
47                $bar: $bar,
48                $fill: $bar.find('.qsm-progress-fill'),
49                $text: $bar.find('.progressbar-text'),
50                totalPages: totalPages,
51                questionPages: questionPages,
52                hasFirstPage: hasFirstPage,
53                currentPage: $initial_page,
54                mode: mode,
55                bar: null
56            };
57			
58            jQuery(document).trigger('qsm_init_progressbar_before', [quizId, qmn_quiz_data]);
59
60            // Initialize ProgressBar.js Line only when library is available
61            if (window.ProgressBar && typeof ProgressBar.Line === 'function') {
62				window.qmn_quiz_data[quizId].bar = new ProgressBar.Line('#qsm_progress_bar_' + quizId, {
63                    strokeWidth: 2,
64                    easing: 'easeInOut',
65                    duration: 1400,
66                    color: '#3498db',
67                    trailColor: '#eee',
68                    trailWidth: 1,
69                    svgStyle: { width: '100%', height: '100%' },
70                    text: {
71                        style: {
72                            'position': 'absolute',
73                            'right': '10px',
74                            'font-size': '13px',
75                            'font-weight': 'bold'
76                        },
77                        autoStyleContainer: false
78                    },
79                    from: { color: '#3498db' },
80                    to: { color: '#ED6A5A' }
81                });
82            }
83			
84            jQuery(document).trigger('qsm_init_progressbar_after', [quizId, qmn_quiz_data]);
85
86            $bar.show();
87            this.updateProgress(quizId, $initial_page);
88        },
89
90        bindEvents: function() {
91            const self = this;
92            $(document).on('qsm_go_to_page_before', function(e, quizId, pageNumber) {
93                self.updateProgress(quizId, pageNumber);
94            });
95            $(document).on('qsm_quiz_initialized', function(e, quizId, instance) {
96                if (!self.quizObjects[quizId]) {
97                    // Use container and form from navigation instance
98                    self.initProgressBar(quizId, instance.quizContainer, instance.$form);
99                }
100            });
101        },
102
103        updateProgress: function(quizId, currentPage) {
104            const currentQuiz = this.quizObjects[quizId];
105            if (!currentQuiz) {
106                return;
107            }
108
109            // If currentPage is not provided, try to get it from navigation system
110            if (typeof currentPage === 'undefined' && QSMPagination && QSMPagination.Navigation) {
111                const navInstance = QSMPagination.Navigation.quizObjects[quizId];
112                if (navInstance) {
113                    currentPage = navInstance.currentPage;
114                }
115            }
116
117            // Fallback to instance currentPage if still undefined
118            if (typeof currentPage === 'undefined') {
119                currentPage = currentQuiz.currentPage;
120            }
121
122            currentQuiz.currentPage = currentPage;
123            
124            // Calculate progress based on question pages only (exclude first page)
125            let effectiveCurrentPage = 0;
126            const effectiveTotalPages = currentQuiz.questionPages;
127            
128            if (currentQuiz.hasFirstPage) {
129                // First page exists - only count progress from page 2 onwards
130                if (Number(currentPage) === 1) {
131                    // On start page (welcome page) - 0% progress
132                    effectiveCurrentPage = 0;
133                } else {
134                    // On question pages - calculate progress
135                    effectiveCurrentPage = currentPage - 1;
136                }
137            } else {
138                // No first page - all pages are question pages
139                effectiveCurrentPage = currentPage;
140            }
141            
142            // Safeguard against division by zero and ensure val
142id percentage
143            let progress = 0;
144            if (effectiveTotalPages > 0) {
145                progress = Math.max(0, Math.min(100, (effectiveCurrentPage / effectiveTotalPages) * 100));
146            }
147            
148            // Ensure progress bar stays visible during all page transitions
149            // This is critical for single-page quizzes where bar might hide on navigation
150            currentQuiz.$bar.show();
151            // Use SVG ProgressBar.js when in svg mode and instance exists, otherwise fallback to simple width animation
152            let animate_value = progress / 100;
153            if (animate_value <= 1 && window.qmn_quiz_data && qmn_quiz_data[quizId] && qmn_quiz_data[quizId].bar) {
154                qmn_quiz_data[quizId].bar.animate(animate_value);
155                let old_text = currentQuiz.$text.text().replace(' %', '');
156                let new_text = Math.round(animate_value * 100);
157                if (!old_text || isNaN(parseInt(old_text, 10))) {
158                    old_text = 0;
159                }
160                jQuery({
161                    Counter: parseInt(old_text, 10)
162                }).animate({
163                    Counter: new_text
164                }, {
165                    duration: 1000,
166                    easing: 'swing',
167                    step: function () {
168                        currentQuiz.$text.text(Math.round(this.Counter) + ' %');
169                    }
170                });
171            }
172        }
173
174    };
175
176    $(document).ready(function() {
177        QSMPagination.ProgressBar.init();
178    });
179
180})(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.