PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.9.9
Tutor LMS – eLearning and online course solution v1.9.9
4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / assets / js / tutor-front.js
tutor / assets / js Last commit date
Chart.bundle.min.js 4 years ago gutenberg_blocks.js 5 years ago mce-button.js 4 years ago tutor-admin.js 4 years ago tutor-front.js 4 years ago tutor-setup.js 5 years ago tutor.js 4 years ago
tutor-front.js
2398 lines
1
2 jQuery(document).ready(function ($) {
3 'use strict';
4 /**
5 * wp.i18n translateable functions
6 * @since 1.9.0
7 */
8 const { __, _x, _n, _nx } = wp.i18n;
9 /**
10 * Initiate Select2
11 * @since v.1.3.4
12 */
13 if (jQuery().select2) {
14 $('.tutor_select2').select2({
15 escapeMarkup: function (markup) {
16 return markup;
17 }
18 });
19 }
20 //END: select2
21
22
23 /*!
24 * jQuery UI Touch Punch 0.2.3
25 *
26 * Copyright 2011–2014, Dave Furfero
27 * Dual licensed under the MIT or GPL Version 2 licenses.
28 *
29 * Depends:
30 * jquery.ui.widget.js
31 * jquery.ui.mouse.js
32 */
33 !function (a) { function f(a, b) { if (!(a.originalEvent.touches.length > 1)) { a.preventDefault(); var c = a.originalEvent.changedTouches[0], d = document.createEvent("MouseEvents"); d.initMouseEvent(b, !0, !0, window, 1, c.screenX, c.screenY, c.clientX, c.clientY, !1, !1, !1, !1, 0, null), a.target.dispatchEvent(d) } } if (a.support.touch = "ontouchend" in document, a.support.touch) { var e, b = a.ui.mouse.prototype, c = b._mouseInit, d = b._mouseDestroy; b._touchStart = function (a) { var b = this; !e && b._mouseCapture(a.originalEvent.changedTouches[0]) && (e = !0, b._touchMoved = !1, f(a, "mouseover"), f(a, "mousemove"), f(a, "mousedown")) }, b._touchMove = function (a) { e && (this._touchMoved = !0, f(a, "mousemove")) }, b._touchEnd = function (a) { e && (f(a, "mouseup"), f(a, "mouseout"), this._touchMoved || f(a, "click"), e = !1) }, b._mouseInit = function () { var b = this; b.element.bind({ touchstart: a.proxy(b, "_touchStart"), touchmove: a.proxy(b, "_touchMove"), touchend: a.proxy(b, "_touchEnd") }), c.call(b) }, b._mouseDestroy = function () { var b = this; b.element.unbind({ touchstart: a.proxy(b, "_touchStart"), touchmove: a.proxy(b, "_touchMove"), touchend: a.proxy(b, "_touchEnd") }), d.call(b) } } }(jQuery);
34
35 /**
36 * END jQuery UI Touch Punch
37 */
38
39 const videoPlayer = {
40 ajaxurl: window._tutorobject.ajaxurl,
41 nonce_key: window._tutorobject.nonce_key,
42 video_data: function () {
43 const video_track_data = $('#tutor_video_tracking_information').val();
44 return video_track_data ? JSON.parse(video_track_data) : {};
45 },
46 track_player: function () {
47 const that = this;
48 if (typeof Plyr !== 'undefined') {
49 const player = new Plyr('#tutorPlayer');
50 const video_data = that.video_data();
51 player.on('ready', function (event) {
52 const instance = event.detail.plyr;
53 const { best_watch_time } = video_data;
54 if (best_watch_time > 0 && instance.duration > Math.round(best_watch_time)) {
55 instance.media.currentTime = best_watch_time;
56 }
57 that.sync_time(instance);
58 });
59
60 let tempTimeNow = 0;
61 let intervalSeconds = 30; //Send to tutor backend about video playing time in this interval
62 player.on('timeupdate', function (event) {
63 const instance = event.detail.plyr;
64 const tempTimeNowInSec = (tempTimeNow / 4); //timeupdate firing 250ms interval
65 if (tempTimeNowInSec >= intervalSeconds) {
66 that.sync_time(instance);
67 tempTimeNow = 0;
68 }
69 tempTimeNow++;
70 });
71
72 player.on('ended', function (event) {
73 const video_data = that.video_data();
74 const instance = event.detail.plyr;
75 const data = { is_ended: true };
76 that.sync_time(instance, data);
77 if (video_data.autoload_next_course_content) {
78 that.autoload_content();
79 }
80 });
81 }
82 },
83 sync_time: function (instance, options) {
84 const post_id = this.video_data().post_id;
85 //TUTOR is sending about video playback information to server.
86 let data = { action: 'sync_video_playback', currentTime: instance.currentTime, duration: instance.duration, post_id };
87 data[this.nonce_key] = _tutorobject[this.nonce_key];
88 let data_send = data;
89 if (options) {
90 data_send = Object.assign(data, options);
91 }
92 $.post(this.ajaxurl, data_send);
93 },
94 autoload_content: function () {
95 const post_id = this.video_data().post_id;
96 const data = { action: 'autoload_next_course_content', post_id };
97 data[this.nonce_key] = _tutorobject[this.nonce_key];
98 $.post(this.ajaxurl, data).done(function (response) {
99 if (response.success && response.data.next_url) {
100 location.href = response.data.next_url;
101 }
102 });
103 },
104 init: function () {
105 this.track_player();
106 }
107 };
108
109 /**
110 * Fire TUTOR video
111 * @since v.1.0.0
112 */
113 if ($('#tutorPlayer').length) {
114 videoPlayer.init();
115 }
116
117 $(document).on('change keyup paste', '.tutor_user_name', function () {
118 $(this).val(tutor_slugify($(this).val()));
119 });
120
121 function tutor_slugify(text) {
122 return text.toString().toLowerCase()
123 .replace(/\s+/g, '-') // Replace spaces with -
124 .replace(/[^\w\-]+/g, '') // Remove all non-word chars
125 .replace(/\-\-+/g, '-') // Replace multiple - with single -
126 .replace(/^-+/, '') // Trim - from start of text
127 .replace(/-+$/, ''); // Trim - from end of text
128 }
129
130 function toggle_star_(star){
131 star.add(star.prevAll()).filter('i').addClass('tutor-icon-star-full').removeClass('tutor-icon-star-line');
132 star.nextAll().filter('i').removeClass('tutor-icon-star-full').addClass('tutor-icon-star-line');
133 }
134
135 /**
136 * Hover tutor rating and set value
137 */
138 $(document).on('mouseover', '.tutor-star-rating-container .tutor-star-rating-group i', function () {
139 toggle_star_($(this));
140 });
141
142 $(document).on('click', '.tutor-star-rating-container .tutor-star-rating-group i', function () {
143 var rating = $(this).attr('data-rating-value');
144 $(this).closest('.tutor-star-rating-group').find('input[name="tutor_rating_gen_input"]').val(rating);
145
146 toggle_star_($(this));
147 });
148
149 $(document).on('mouseout', '.tutor-star-rating-container .tutor-star-rating-group', function(){
150 var value = $(this).find('input[name="tutor_rating_gen_input"]').val();
151 var rating = parseInt(value);
152
153 var selected = $(this).find('[data-rating-value="'+rating+'"]');
154 (rating && selected && selected.length>0) ? toggle_star_(selected) : $(this).find('i').removeClass('tutor-icon-star-full').addClass('tutor-icon-star-line');
155 });
156
157 $(document).on('click', '.tutor_submit_review_btn', function (e) {
158 e.preventDefault();
159 var $that = $(this);
160 var rating = $that.closest('form').find('input[name="tutor_rating_gen_input"]').val();
161 var review = $that.closest('form').find('textarea[name="review"]').val();
162 review = review.trim();
163
164 var course_id = $('input[name="tutor_course_id"]').val();
165 var data = { course_id: course_id, rating: rating, review: review, action: 'tutor_place_rating' };
166
167 if(!rating || rating==0 || !review) {
168 alert(__('Rating and review required', 'tutor'));
169 return;
170 }
171
172 if (review) {
173 $.ajax({
174 url: _tutorobject.ajaxurl,
175 type: 'POST',
176 data: data,
177 beforeSend: function () {
178 $that.addClass('updating-icon');
179 },
180 success: function (data) {
181 var review_id = data.data.review_id;
182 var review = data.data.review;
183 $('.tutor-review-' + review_id + ' .review-content').html(review);
184
185 // Show thank you
186 new window.tutor_popup($, 'icon-rating', 40).popup({
187 title: __('Thank You for Rating This Course!', 'tutor'),
188 description : __('Your rating will now be visible in the course page', 'tutor'),
189 });
190
191 setTimeout(function(){
192 location.reload();
193 }, 3000);
194 }
195 });
196 }
197 }).on('click', '.tutor_cancel_review_btn', function() {
198 // Hide the pop up review form on cancel click
199 $(this).closest('form').hide();
200 });
201
202 $(document).on('click', '.write-course-review-link-btn', function (e) {
203 e.preventDefault();
204 $(this).siblings('.tutor-write-review-form').slideToggle();
205 });
206
207 $(document).on('click', '.tutor-ask-question-btn', function (e) {
208 e.preventDefault();
209 $('.tutor-add-question-wrap').slideToggle();
210 });
211 $(document).on('click', '.tutor_question_cancel', function (e) {
212 e.preventDefault();
213 $('.tutor-add-question-wrap').toggle();
214 });
215
216 $(document).on('submit', '#tutor-ask-question-form', function (e) {
217 e.preventDefault();
218
219 var $form = $(this);
220
221 var data = $(this).serializeObject();
222 data.action = 'tutor_ask_question';
223
224 $.ajax({
225 url: _tutorobject.ajaxurl,
226 type: 'POST',
227 data: data,
228 beforeSend: function () {
229 $form.find('.tutor_ask_question_btn').addClass('updating-icon');
230 },
231 success: function (data) {
232 if (data.success) {
233 $('.tutor-add-question-wrap').hide();
234 window.location.reload();
235 }
236 },
237 complete: function () {
238 $form.find('.tutor_ask_question_btn').removeClass('updating-icon');
239 }
240 });
241 });
242
243 $(document).on('submit', '.tutor-add-answer-form', function (e) {
244 e.preventDefault();
245
246 var $form = $(this);
247 var data = $(this).serializeObject();
248 data.action = 'tutor_add_answer';
249
250 $.ajax({
251 url: _tutorobject.ajaxurl,
252 type: 'POST',
253 data: data,
254 beforeSend: function () {
255 $form.find('.tutor_add_answer_btn').addClass('updating-icon');
256 },
257 success: function (data) {
258 if (data.success) {
259 window.location.reload();
260 }
261 },
262 complete: function () {
263 $form.find('.tutor_add_answer_btn').removeClass('updating-icon');
264 }
265 });
266 });
267
268 $(document).on('focus', '.tutor_add_answer_textarea', function (e) {
269 e.preventDefault();
270
271 var question_id = $(this).closest('.tutor_add_answer_wrap').attr('data-question-id');
272 var conf = {
273 tinymce: {
274 wpautop: true,
275 //plugins : 'charmap colorpicker compat3x directionality fullscreen hr image lists media paste tabfocus textcolor wordpress wpautoresize wpdialogs wpeditimage wpemoji wpgallery wplink wptextpattern wpview',
276 toolbar1: 'bold italic underline bullist strikethrough numlist blockquote alignleft aligncenter alignright undo redo link unlink spellchecker fullscreen'
277 },
278 };
279 wp.editor.initialize('tutor_answer_' + question_id, conf);
280 });
281
282 $(document).on('click', '.tutor_cancel_wp_editor', function (e) {
283 e.preventDefault();
284 $(this).closest('.tutor_wp_editor_wrap').toggle();
285 $(this).closest('.tutor_add_answer_wrap').find('.tutor_wp_editor_show_btn_wrap').toggle();
286 var question_id = $(this).closest('.tutor_add_answer_wrap').attr('data-question-id');
287 wp.editor.remove('tutor_answer_' + question_id);
288 });
289
290 $(document).on('click', '.tutor_wp_editor_show_btn', function (e) {
291 e.preventDefault();
292 $(this).closest('.tutor_add_answer_wrap').find('.tutor_wp_editor_wrap').toggle();
293 $(this).closest('.tutor_wp_editor_show_btn_wrap').toggle();
294 });
295
296 /**
297 * Quiz attempt
298 */
299
300 var $tutor_quiz_time_update = $('#tutor-quiz-time-update');
301 var attempt_settings = null;
302 if ($tutor_quiz_time_update.length) {
303 attempt_settings = JSON.parse($tutor_quiz_time_update.attr('data-attempt-settings'));
304 var attempt_meta = JSON.parse($tutor_quiz_time_update.attr('data-attempt-meta'));
305
306 if (attempt_meta.time_limit.time_limit_seconds > 0) {
307 //No time Zero limit for
308 var countDownDate = new Date(attempt_settings.attempt_started_at).getTime() + (attempt_meta.time_limit.time_limit_seconds * 1000);
309 var time_now = new Date(attempt_meta.date_time_now).getTime();
310
311 var tutor_quiz_interval = setInterval(function () {
312 var distance = countDownDate - time_now;
313
314 var days = Math.floor(distance / (1000 * 60 * 60 * 24));
315 var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
316 var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
317 var seconds = Math.floor((distance % (1000 * 60)) / 1000);
318
319 var countdown_human = '';
320
321 if (days) {
322 countdown_human += days + "d ";
323 }
324 if (hours) {
325 countdown_human += hours + "h ";
326 }
327 if (minutes) {
328 countdown_human += minutes + "m ";
329 }
330 if (seconds) {
331 countdown_human += seconds + "s ";
332 }
333
334 if (distance < 0) {
335 clearInterval(tutor_quiz_interval);
336 countdown_human = "EXPIRED";
337 //Set the quiz attempt to timeout in ajax
338 if (_tutorobject.quiz_options.quiz_when_time_expires === 'autosubmit') {
339 /**
340 * Auto Submit
341 */
342 $('form#tutor-answering-quiz').submit();
343
344 } else if (_tutorobject.quiz_options.quiz_when_time_expires === 'autoabandon') {
345
346 /**
347 *
348 * @type {jQuery}
349 *
350 * Current attempt will be cancel with attempt status attempt_timeout
351 */
352
353 var quiz_id = $('#tutor_quiz_id').val();
354 var tutor_quiz_remaining_time_secs = $('#tutor_quiz_remaining_time_secs').val();
355 var quiz_timeout_data = { quiz_id: quiz_id, action: 'tutor_quiz_timeout' };
356
357 var att = $("#tutor-quiz-time-expire-wrapper").attr('data-attempt-remaining');
358
359 //disable buttons
360 $(".tutor-quiz-answer-next-btn, .tutor-quiz-submit-btn, .tutor-quiz-answer-previous-btn").prop('disabled', true);
361
362 //add alert text
363 $(".time-remaining span").css('color', '#F44337');
364
365 $.ajax({
366 url: _tutorobject.ajaxurl,
367 type: 'POST',
368 data: quiz_timeout_data,
369 success: function (data) {
370
371 var attemptAllowed = $("#tutor-quiz-time-expire-wrapper").data('attempt-allowed');
372 var attemptRemaining = $("#tutor-quiz-time-expire-wrapper").data('attempt-remaining');
373
374 var alertDiv = "#tutor-quiz-time-expire-wrapper .tutor-alert";
375 $(alertDiv).addClass('show');
376 if ( att > 0 ) {
377 $(`${alertDiv} .text`).html(
378 __( 'Your time limit for this quiz has expired, please reattempt the quiz. Attempts remaining: '+ attemptRemaining+'/'+attemptAllowed, 'tutor' )
379 );
380 } else {
381 $(alertDiv).addClass('tutor-alert-danger');
382 $("#tutor-start-quiz").hide();
383 $(`${alertDiv} .text`).html(
384 `${__( 'Unfortunately, you are out of time and quiz attempts. ', 'tutor' )}`
385 );
386 }
387
388 },
389 complete: function () {
390
391 }
392 });
393 }
394
395 }
396 time_now = time_now + 1000;
397 $tutor_quiz_time_update.html(countdown_human);
398 }, 1000);
399 } else {
400 $tutor_quiz_time_update.closest('.time-remaining').remove();
401 }
402 }
403
404 var $quiz_start_form = $('#tutor-quiz-body form#tutor-start-quiz');
405 if ($quiz_start_form.length) {
406 if (_tutorobject.quiz_options.quiz_auto_start === '1') {
407 $quiz_start_form.submit();
408 }
409 }
410
411 /**
412 * Quiz Frontend Review Action
413 * @since 1.4.0
414 */
415 $(document).on('click', '.quiz-manual-review-action', function (e) {
416 e.preventDefault();
417 var $that = $(this),
418 attempt_id = $that.attr('data-attempt-id'),
419 attempt_answer_id = $that.attr('data-attempt-answer-id'),
420 mark_as = $that.attr('data-mark-as');
421
422 $.ajax({
423 url: _tutorobject.ajaxurl,
424 type: 'GET',
425 data: { action: 'review_quiz_answer', attempt_id: attempt_id, attempt_answer_id: attempt_answer_id, mark_as: mark_as },
426 beforeSend: function () {
427 $that.find('i').addClass('updating-icon');
428 },
429 success: function (data) {
430 location.reload();
431 },
432 complete: function () {
433 $that.find('i').removeClass('updating-icon');
434 }
435 });
436 });
437
438 // Quiz Review : Tooltip
439 $(".tooltip-btn").on("hover", function (e) {
440 $(this).toggleClass("active");
441 });
442
443 // tutor course content accordion
444
445 /**
446 * Toggle topic summery
447 * @since v.1.6.9
448 */
449 $('.tutor-course-title h4 .toggle-information-icon').on('click', function (e) {
450 $(this).closest('.tutor-topics-in-single-lesson').find('.tutor-topics-summery').slideToggle();
451 e.stopPropagation();
452 });
453
454 $('.tutor-course-topic.tutor-active').find('.tutor-course-lessons').slideDown();
455 $('.tutor-course-title').on('click', function () {
456 var lesson = $(this).siblings('.tutor-course-lessons');
457 $(this).closest('.tutor-course-topic').toggleClass('tutor-active');
458 lesson.slideToggle();
459 });
460
461 $(document).on('click', '.tutor-topics-title h3 .toggle-information-icon', function (e) {
462 $(this).closest('.tutor-topics-in-single-lesson').find('.tutor-topics-summery').slideToggle();
463 e.stopPropagation();
464 });
465
466 $(document).on('click', '.tutor-course-wishlist-btn', function (e) {
467 e.preventDefault();
468
469 var $that = $(this);
470 var course_id = $that.attr('data-course-id');
471
472 $.ajax({
473 url: _tutorobject.ajaxurl,
474 type: 'POST',
475 data: { course_id: course_id, 'action': 'tutor_course_add_to_wishlist' },
476 beforeSend: function () {
477 $that.addClass('updating-icon');
478 },
479 success: function (data) {
480 if (data.success) {
481 if (data.data.status === 'added') {
482 $that.addClass('has-wish-listed');
483 } else {
484 $that.removeClass('has-wish-listed');
485 }
486 } else {
487 window.location = data.data.redirect_to;
488 }
489 },
490 complete: function () {
491 $that.removeClass('updating-icon');
492 }
493 });
494 });
495
496 /**
497 * Check if lesson has classic editor support
498 * If classic editor support, stop ajax load on the lesson page.
499 *
500 * @since v.1.0.0
501 *
502 * @updated v.1.4.0
503 */
504 if (!_tutorobject.enable_lesson_classic_editor) {
505
506 $(document).on('click', '.tutor-single-lesson-a', function (e) {
507 e.preventDefault();
508
509 var $that = $(this);
510 var lesson_id = $that.attr('data-lesson-id');
511 var $wrap = $('#tutor-single-entry-content');
512
513 $.ajax({
514 url: _tutorobject.ajaxurl,
515 type: 'POST',
516 data: { lesson_id: lesson_id, 'action': 'tutor_render_lesson_content' },
517 beforeSend: function () {
518 var page_title = $that.find('.lesson_title').text();
519 $('head title').text(page_title);
520 window.history.pushState('obj', page_title, $that.attr('href'));
521 $wrap.addClass('loading-lesson');
522 $('.tutor-single-lesson-items').removeClass('active');
523 $that.closest('.tutor-single-lesson-items').addClass('active');
524 },
525 success: function (data) {
526 $wrap.html(data.data.html);
527 videoPlayer.init();
528 $('.tutor-lesson-sidebar').css('display', '');
529 window.dispatchEvent(new window.Event('tutor_ajax_lesson_loaded')); // Some plugins like h5p needs notification on ajax load
530 },
531 complete: function () {
532 $wrap.removeClass('loading-lesson');
533 }
534 });
535 });
536
537 $(document).on('click', '.sidebar-single-quiz-a', function (e) {
538 e.preventDefault();
539
540 var $that = $(this);
541 var quiz_id = $that.attr('data-quiz-id');
542 var page_title = $that.find('.lesson_title').text();
543 var $wrap = $('#tutor-single-entry-content');
544
545 $.ajax({
546 url: _tutorobject.ajaxurl,
547 type: 'POST',
548 data: { quiz_id: quiz_id, 'action': 'tutor_render_quiz_content' },
549 beforeSend: function () {
550 $('head title').text(page_title);
551 window.history.pushState('obj', page_title, $that.attr('href'));
552 $wrap.addClass('loading-lesson');
553 $('.tutor-single-lesson-items').removeClass('active');
554 $that.closest('.tutor-single-lesson-items').addClass('active');
555 },
556 success: function (data) {
557 $wrap.html(data.data.html);
558 init_quiz_builder();
559 $('.tutor-lesson-sidebar').css('display', '');
560 },
561 complete: function () {
562 $wrap.removeClass('loading-lesson');
563 }
564 });
565 });
566 }
567
568 /**
569 * @date 05 Feb, 2019
570 */
571
572 $(document).on('click', '.tutor-lesson-sidebar-hide-bar', function (e) {
573 e.preventDefault();
574 $('.tutor-lesson-sidebar').toggle();
575 $('#tutor-single-entry-content').toggleClass("sidebar-hidden");
576
577 });
578
579 $(".tutor-tabs-btn-group a").on('click touchstart', function (e) {
580 e.preventDefault();
581 var $that = $(this);
582 var tabSelector = $that.attr('href');
583 $('.tutor-lesson-sidebar-tab-item').hide();
584 $(tabSelector).show();
585
586 $('.tutor-tabs-btn-group a').removeClass('active');
587 $that.addClass('active');
588 });
589 /**
590 * @date 18 Feb, 2019
591 * @since v.1.0.0
592 */
593
594 function init_quiz_builder() {
595 if (jQuery().sortable) {
596 $(".tutor-quiz-answers-wrap").sortable({
597 handle: ".answer-sorting-bar",
598 start: function (e, ui) {
599 ui.placeholder.css('visibility', 'visible');
600 },
601 stop: function (e, ui) {
602 //Sorting Stopped...
603 },
604 }).disableSelection();
605
606 $(".quiz-draggable-rand-answers, .quiz-answer-matching-droppable").sortable({
607 connectWith: ".quiz-answer-matching-droppable",
608 placeholder: "drop-hover",
609 }).disableSelection();
610 }
611 }
612 init_quiz_builder();
613 /**
614 * Quiz view
615 * @date 22 Feb, 2019
616 * @since v.1.0.0
617 */
618
619 $(document).on('click', '.tutor-quiz-answer-next-btn, .tutor-quiz-answer-previous-btn', function (e) {
620 e.preventDefault();
621
622 // Show previous quiz if press previous button
623 if($(this).hasClass('tutor-quiz-answer-previous-btn')) {
624 $(this).closest('.quiz-attempt-single-question').hide().prev().show();
625 return;
626 }
627
628 var $that = $(this);
629 var $question_wrap = $that.closest('.quiz-attempt-single-question');
630 /**
631 * Validating required answer
632 * @type {jQuery}
633 *
634 * @since v.1.6.1
635 */
636
637 var validated = tutor_quiz_validation($question_wrap);
638 if (!validated) {
639 return;
640 }
641
642 var feedBackNext = feedback_response($question_wrap);
643 if (!feedBackNext) {
644 return;
645 }
646
647 var question_id = parseInt($that.closest('.quiz-attempt-single-question').attr('id').match(/\d+/)[0], 10);
648
649 var next_question_id = $that.closest('.quiz-attempt-single-question').attr('data-next-question-id');
650
651 if (next_question_id) {
652 var $nextQuestion = $(next_question_id);
653 if ($nextQuestion && $nextQuestion.length) {
654 /**
655 * check if reveal mode wait for 500ms then
656 * hide question so that correct answer reveal
657 * @since 1.8.10
658 */
659
660 var feedBackMode = $question_wrap.attr('data-quiz-feedback-mode');
661 if(feedBackMode === 'reveal') {
662 setTimeout(()=>{
663 $('.quiz-attempt-single-question').hide();
664 $nextQuestion.show();
665 },
666 800);
667 } else {
668 $('.quiz-attempt-single-question').hide();
669 $nextQuestion.show();
670 }
671
672
673
674 /**
675 * If pagination exists, set active class
676 */
677
678 if ($('.tutor-quiz-questions-pagination').length) {
679 $('.tutor-quiz-question-paginate-item').removeClass('active');
680 $('.tutor-quiz-questions-pagination a[href="' + next_question_id + '"]').addClass('active');
681 }
682
683 }
684 }
685 });
686
687 $(document).on('submit', '#tutor-answering-quiz', function (e) {
688 var $questions_wrap = $('.quiz-attempt-single-question');
689 var validated = true;
690 if ($questions_wrap.length) {
691 $questions_wrap.each(function (index, question) {
692 // !tutor_quiz_validation( $(question) ) ? validated = false : 0;
693 // !feedback_response( $(question) ) ? validated = false : 0;
694 validated = tutor_quiz_validation($(question));
695 validated = feedback_response($(question));
696
697 });
698 }
699
700 if (!validated) {
701 e.preventDefault();
702 }
703 });
704
705
706 $(document).on('click', '.tutor-quiz-question-paginate-item', function (e) {
707 e.preventDefault();
708 var $that = $(this);
709 var $question = $($that.attr('href'));
710 $('.quiz-attempt-single-question').hide();
711 $question.show();
712
713 //Active Class
714 $('.tutor-quiz-question-paginate-item').removeClass('active');
715 $that.addClass('active');
716 });
717
718 /**
719 * Limit Short Answer Question Type
720 */
721 $(document).on('keyup', 'textarea.question_type_short_answer, textarea.question_type_open_ended', function (e) {
722 var $that = $(this);
723 var value = $that.val();
724 var limit = $that.hasClass('question_type_short_answer') ? _tutorobject.quiz_options.short_answer_characters_limit : _tutorobject.quiz_options.open_ended_answer_characters_limit;
725 var remaining = limit - value.length;
726
727 if (remaining < 1) {
728 $that.val(value.substr(0, limit));
729 remaining = 0;
730 }
731 $that.closest('.tutor-quiz-answers-wrap').find('.characters_remaining').html(remaining);
732 });
733
734 /**
735 *
736 * @type {jQuery}
737 *
738 * Improved Quiz draggable answers drop accessibility
739 * Answers draggable wrap will be now same height.
740 *
741 * @since v.1.4.4
742 */
743 var countDraggableAnswers = $('.quiz-draggable-rand-answers').length;
744 if (countDraggableAnswers) {
745 $('.quiz-draggable-rand-answers').each(function () {
746 var $that = $(this);
747 var draggableDivHeight = $that.height();
748
749 $that.css({ "height": draggableDivHeight });
750 });
751 }
752
753
754 /**
755 * Quiz Validation Helper
756 *
757 * @since v.1.6.1
758 */
759
760 function tutor_quiz_validation($question_wrap) {
761 var validated = true;
762
763 var $required_answer_wrap = $question_wrap.find('.quiz-answer-required');
764
765 if ($required_answer_wrap.length) {
766 /**
767 * Radio field validation
768 *
769 * @type {jQuery}
770 *
771 * @since v.1.6.1
772 */
773 var $inputs = $required_answer_wrap.find('input');
774 if ($inputs.length) {
775 var $type = $inputs.attr('type');
776 if ($type === 'radio') {
777 if ($required_answer_wrap.find('input[type="radio"]:checked').length == 0) {
778 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('Please select an option to answer', 'tutor')}</p>`);
779 validated = false;
780 }
781 } else if ($type === 'checkbox') {
782 if ($required_answer_wrap.find('input[type="checkbox"]:checked').length == 0) {
783 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('Please select at least one option to answer.', 'tutor')}</p>`);
784 validated = false;
785 }
786 } else if ($type === 'text') {
787 //Fill in the gaps if many, validation all
788 $inputs.each(function (index, input) {
789 if (!$(input).val().trim().length) {
790 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('The answer for this question is required', 'tutor')}</p>`);
791 validated = false;
792 }
793 });
794 }
795
796 }
797 if ($required_answer_wrap.find('textarea').length) {
798 if ($required_answer_wrap.find('textarea').val().trim().length < 1) {
799 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('The answer for this question is required', 'tutor')}</p>`);
800 validated = false;
801 }
802 }
803
804 /**
805 * Matching Question
806 */
807 var $matchingDropable = $required_answer_wrap.find('.quiz-answer-matching-droppable');
808 if ($matchingDropable.length) {
809
810 $matchingDropable.each(function (index, matching) {
811 if (!$(matching).find('.quiz-draggable-answer-item').length) {
812 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('Please match all the items', 'tutor')}</p>`);
813 validated = false;
814 }
815 });
816 }
817 }
818
819 return validated;
820 }
821
822 function feedback_response($question_wrap) {
823 var goNext = false;
824
825 // Prepare answer array
826 var quiz_answers = JSON.parse(atob(window.tutor_quiz_context.split('').reverse().join('')));
827 !Array.isArray(quiz_answers) ? quiz_answers=[] : 0;
828
829 // Evaluate result
830 var feedBackMode = $question_wrap.attr('data-quiz-feedback-mode');
831 $('.wrong-right-text').remove();
832 $('.quiz-answer-input-bottom').removeClass('wrong-answer right-answer');
833
834 var validatedTrue = true;
835 var $inputs = $question_wrap.find('input');
836 var $checkedInputs = $question_wrap.find('input[type="radio"]:checked, input[type="checkbox"]:checked');
837
838 if (feedBackMode === 'retry') {
839 $checkedInputs.each(function () {
840 var $input = $(this);
841
842 var $type = $input.attr('type');
843 if ($type === 'radio' || $type === 'checkbox') {
844 var isTrue = quiz_answers.indexOf($input.val())>-1; // $input.attr('data-is-correct') == '1';
845 if ( !isTrue) {
846 if ($input.prop("checked")) {
847 $input.closest('.quiz-answer-input-bottom').addClass('wrong-answer').append(`<span class="wrong-right-text"><i class="tutor-icon-line-cross"></i> ${__('Incorrect, Please try again', 'tutor')}</span>`);
848 }
849 validatedTrue = false;
850 }
851 }
852 });
853
854 $inputs.each(function () {
855 var $input = $(this);
856 var $type = $input.attr('type');
857 if ($type === 'checkbox') {
858 var isTrue = quiz_answers.indexOf($input.val())>-1; // $input.attr('data-is-correct') == '1';
859 var checked = $input.is(':checked');
860
861 if (isTrue && !checked) {
862 $question_wrap.find('.answer-help-block').html(`<p style="color: #dc3545">${__('More answer for this question is required', 'tutor')}</p>`);
863 validatedTrue = false;
864 }
865 }
866 });
867
868 } else if (feedBackMode === 'reveal') {
869 $checkedInputs.each(function () {
870 var $input = $(this);
871 var isTrue = quiz_answers.indexOf($input.val())>-1; // $input.attr('data-is-correct') == '1';
872 if (!isTrue) {
873 validatedTrue = false;
874 }
875 });
876
877 $inputs.each(function () {
878 var $input = $(this);
879
880 var $type = $input.attr('type');
881 if ($type === 'radio' || $type === 'checkbox') {
882 var isTrue = quiz_answers.indexOf($input.val())>-1; // $input.attr('data-is-correct') == '1';
883 var checked = $input.is(':checked');
884
885 if (isTrue) {
886 $input.closest('.quiz-answer-input-bottom').addClass('right-answer').append(`<span class="wrong-right-text"><i class="tutor-icon-checkbox-pen-outline"></i>${__('Correct Answer', 'tutor')}</span>`);
887 } else {
888 if ($input.prop("checked")) {
889 $input.closest('.quiz-answer-input-bottom').addClass('wrong-answer');
890 }
891 }
892
893 if (isTrue && !checked) {
894 $input.attr('disabled','disabled');
895 validatedTrue = false;
896 goNext = true;
897 }
898 }
899 });
900 }
901
902 if (validatedTrue) {
903 goNext = true;
904 }
905
906 return goNext;
907 }
908
909
910 /**
911 * Add to cart in guest mode, show login form
912 *
913 * @since v.1.0.4
914 */
915
916 $(document).on('submit click', '.cart-required-login, .cart-required-login a, .cart-required-login form', function (e) {
917 e.preventDefault();
918
919 var login_url = $(this).data('login_page_url');
920 login_url ? window.location.assign(login_url) : $('.tutor-cart-box-login-form').fadeIn(100);
921 });
922
923 $('.tutor-popup-form-close, .login-overlay-close').on('click', function () {
924 $('.tutor-cart-box-login-form').fadeOut(100);
925 });
926
927 $(document).on('keyup', function (e) {
928 if (e.keyCode === 27) {
929 $('.tutor-frontend-modal').hide();
930 $('.tutor-cart-box-login-form').fadeOut(100);
931 }
932 });
933 /**
934 * Share Link enable
935 *
936 * @since v.1.0.4
937 */
938 if ($.fn.ShareLink) {
939 var $social_share_wrap = $('.tutor-social-share-wrap');
940 if ($social_share_wrap.length) {
941 var share_config = JSON.parse($social_share_wrap.attr('data-social-share-config'));
942
943 $('.tutor_share').ShareLink({
944 title: share_config.title,
945 text: share_config.text,
946 image: share_config.image,
947 class_prefix: 's_',
948 width: 640,
949 height: 480,
950 });
951 }
952 }
953
954 /**
955 * Datepicker initiate
956 *
957 * @since v.1.1.2
958 */
959 if (jQuery.datepicker) {
960 $(".tutor_report_datepicker").datepicker({ "dateFormat": 'yy-mm-dd' });
961 }
962
963
964 /**
965 * Withdraw Form Tab/Toggle
966 *
967 * @since v.1.1.2
968 */
969
970 $(".withdraw-method-select-input").on('change', function (e) {
971 var $that = $(this);
972 $('.withdraw-method-form').hide();
973 $('#withdraw-method-form-' + $that.closest('.withdraw-method-select').attr('data-withdraw-method')).show();
974 });
975
976 $('.withdraw-method-select-input').each(function () {
977 var $that = $(this);
978 if ($that.is(":checked")) {
979 $('.withdraw-method-form').hide();
980 $('#withdraw-method-form-' + $that.closest('.withdraw-method-select').attr('data-withdraw-method')).show();
981 }
982 });
983
984
985
986 /**
987 * Setting account for withdraw earning
988 *
989 * @since v.1.2.0
990 */
991 $(document).on('submit', '#tutor-withdraw-account-set-form', function (e) {
992 e.preventDefault();
993
994 var $form = $(this);
995 var $btn = $form.find('.tutor_set_withdraw_account_btn');
996 var data = $form.serializeObject();
997
998 $.ajax({
999 url: _tutorobject.ajaxurl,
1000 type: 'POST',
1001 data: data,
1002 beforeSend: function () {
1003 $form.find('.tutor-success-msg').remove();
1004 $btn.addClass('updating-icon');
1005 },
1006 success: function (data) {
1007 if (data.success) {
1008 var successMsg = '<div class="tutor-success-msg" style="display: none;"><i class="tutor-icon-mark"></i> ' + data.data.msg + ' </div>';
1009 $btn.closest('.withdraw-account-save-btn-wrap').append(successMsg);
1010 if ($form.find('.tutor-success-msg').length) {
1011 $form.find('.tutor-success-msg').slideDown();
1012 }
1013 setTimeout(function () {
1014 $form.find('.tutor-success-msg').slideUp();
1015 }, 5000)
1016 }
1017 },
1018 complete: function () {
1019 $btn.removeClass('updating-icon');
1020 }
1021 });
1022 });
1023
1024 /**
1025 * Make Withdraw Form
1026 *
1027 * @since v.1.2.0
1028 */
1029
1030 $(document).on('click', '.open-withdraw-form-btn, .close-withdraw-form-btn', function (e) {
1031 e.preventDefault();
1032
1033 if($(this).data('reload')=='yes'){
1034 window.location.reload();
1035 return;
1036 }
1037
1038 $('.tutor-earning-withdraw-form-wrap').toggle().find('[name="tutor_withdraw_amount"]').val('');
1039 $('.tutor-withdrawal-pop-up-success').hide().next().show();
1040 $('html, body').css('overflow', ($('.tutor-earning-withdraw-form-wrap').is(':visible') ? 'hidden' : 'auto'));
1041 });
1042
1043 $(document).on('submit', '#tutor-earning-withdraw-form', function (e) {
1044 e.preventDefault();
1045
1046 var $form = $(this);
1047 var $btn = $('#tutor-earning-withdraw-btn');
1048 var $responseDiv = $('.tutor-withdraw-form-response');
1049 var data = $form.serializeObject();
1050
1051 $.ajax({
1052 url: _tutorobject.ajaxurl,
1053 type: 'POST',
1054 data: data,
1055 beforeSend: function () {
1056 $form.find('.tutor-success-msg').remove();
1057 $btn.addClass('updating-icon');
1058 },
1059 success: function (data) {
1060 var Msg;
1061 if (data.success) {
1062
1063 if (data.data.available_balance !== 'undefined') {
1064 $('.withdraw-balance-col .available_balance').html(data.data.available_balance);
1065 }
1066
1067 $('.tutor-withdrawal-pop-up-success').show().next().hide();
1068
1069 } else {
1070 Msg = '<div class="tutor-error-msg inline-image-text is-inline-block">\
1071 <img src="'+window._tutorobject.tutor_url+'assets/images/icon-cross.svg"/> \
1072 <div>\
1073 <b>Error</b><br/>\
1074 <span>'+ data.data.msg + '</span>\
1075 </div>\
1076 </div>';
1077
1078 $responseDiv.html(Msg);
1079 setTimeout(function () {
1080 $responseDiv.html('');
1081 }, 5000)
1082 }
1083 },
1084 complete: function () {
1085 $btn.removeClass('updating-icon');
1086 }
1087 });
1088 });
1089
1090 var frontEndModal = $('.tutor-frontend-modal');
1091 frontEndModal.each(function () {
1092 var modal = $(this),
1093 action = $(this).data('popup-rel');
1094 $('[href="' + action + '"]').on('click', function (e) {
1095 modal.fadeIn();
1096 e.preventDefault();
1097 });
1098 });
1099 $(document).on('click', '.tm-close, .tutor-frontend-modal-overlay, .tutor-modal-btn-cancel', function () {
1100 frontEndModal.fadeOut();
1101 });
1102
1103 /**
1104 * Delete Course
1105 */
1106 $(document).on('click', '.tutor-dashboard-element-delete-btn', function (e) {
1107 e.preventDefault();
1108 var element_id = $(this).attr('data-id');
1109 $('#tutor-dashboard-delete-element-id').val(element_id);
1110 });
1111 $(document).on('submit', '#tutor-dashboard-delete-element-form', function (e) {
1112 e.preventDefault();
1113
1114 var element_id = $('#tutor-dashboard-delete-element-id').val();
1115 var $btn = $('.tutor-modal-element-delete-btn');
1116 var data = $(this).serializeObject();
1117
1118 $.ajax({
1119 url: _tutorobject.ajaxurl,
1120 type: 'POST',
1121 data: data,
1122 beforeSend: function () {
1123 $btn.addClass('updating-icon');
1124 },
1125 success: function (res) {
1126 if (res.success) {
1127 $('#tutor-dashboard-' + res.data.element + '-' + element_id).remove();
1128 }
1129 },
1130 complete: function () {
1131 $btn.removeClass('updating-icon');
1132 $('.tutor-frontend-modal').hide();
1133 }
1134 });
1135 });
1136
1137 /**
1138 * Frontend Profile
1139 */
1140
1141 if (!$('#tutor_profile_photo_id').val()) {
1142 $('.tutor-profile-photo-delete-btn').hide();
1143 }
1144
1145 $(document).on('click', '.tutor-profile-photo-delete-btn', function () {
1146 $('.tutor-profile-photo-upload-wrap').find('img').attr('src', _tutorobject.placeholder_img_src);
1147 $('#tutor_profile_photo_id').val('');
1148 $('.tutor-profile-photo-delete-btn').hide();
1149
1150 $.ajax({
1151 url: _tutorobject.ajaxurl,
1152 type: 'POST',
1153 data: { 'action': 'tutor_profile_photo_remove' },
1154 });
1155
1156 return false;
1157 });
1158
1159 /**
1160 * Assignment
1161 *
1162 * @since v.1.3.3
1163 */
1164 $(document).on('submit', '#tutor_assignment_start_form', function (e) {
1165 e.preventDefault();
1166
1167 var $that = $(this);
1168 var form_data = $that.serializeObject();
1169 form_data.action = 'tutor_start_assignment';
1170
1171 $.ajax({
1172 url: _tutorobject.ajaxurl,
1173 type: 'POST',
1174 data: form_data,
1175 beforeSend: function () {
1176 $('#tutor_assignment_start_btn').addClass('updating-icon');
1177 },
1178 success: function (data) {
1179 if (data.success) {
1180 location.reload();
1181 }
1182 },
1183 complete: function () {
1184 $('#tutor_assignment_start_btn').removeClass('updating-icon');
1185 }
1186 });
1187 });
1188
1189 /**
1190 * Assignment answer validation
1191 */
1192 $(document).on('submit', '#tutor_assignment_submit_form', function (e) {
1193 var assignment_answer = $('textarea[name="assignment_answer"]').val();
1194 if (assignment_answer.trim().length < 1) {
1195 $('#form_validation_response').html('<div class="tutor-error-msg">' + __('Assignment answer can not be empty', 'tutor') + '</div>');
1196 e.preventDefault();
1197 }
1198 });
1199
1200 /**
1201 * Course builder video
1202 * @since v.1.3.4
1203 */
1204
1205
1206 $(document).on('click', '.video_source_upload_wrap_html5 .video_upload_btn', function (event) {
1207 event.preventDefault();
1208
1209 var $that = $(this);
1210 var frame;
1211 // If the media frame already exists, reopen it.
1212 if (frame) {
1213 frame.open();
1214 return;
1215 }
1216 frame = wp.media({
1217 title: __( 'Select / Upload Media Of Your Chosen Persuasion', 'tutor' ),
1218 button: {
1219 text: __( 'Use media', 'tutor' )
1220 },
1221 library: { type: 'video' },
1222 multiple: false // Set to true to allow multiple files to be selected
1223 });
1224 frame.on('select', function () {
1225 // Get media attachment details from the frame state
1226 var attachment = frame.state().get('selection').first().toJSON();
1227 $that.closest('.video_source_upload_wrap_html5').find('span.video_media_id').data('video_url', attachment.url).text(attachment.id).trigger('paste').closest('p').show();
1228 $that.closest('.video_source_upload_wrap_html5').find('input').val(attachment.id);
1229 });
1230 frame.open();
1231 });
1232
1233
1234 /**
1235 * Course and lesson sorting
1236 */
1237
1238 function enable_sorting_topic_lesson() {
1239 if (jQuery().sortable) {
1240 $(".course-contents").sortable({
1241 handle: ".course-move-handle",
1242 start: function (e, ui) {
1243 ui.placeholder.css('visibility', 'visible');
1244 },
1245 stop: function (e, ui) {
1246 tutor_sorting_topics_and_lesson();
1247 },
1248 });
1249 $(".tutor-lessons:not(.drop-lessons)").sortable({
1250 connectWith: ".tutor-lessons",
1251 items: "div.course-content-item",
1252 start: function (e, ui) {
1253 ui.placeholder.css('visibility', 'visible');
1254 },
1255 stop: function (e, ui) {
1256 tutor_sorting_topics_and_lesson();
1257 },
1258 });
1259 }
1260 }
1261 enable_sorting_topic_lesson();
1262 function tutor_sorting_topics_and_lesson() {
1263 var topics = {};
1264 $('.tutor-topics-wrap').each(function (index, item) {
1265 var $topic = $(this);
1266 var topics_id = parseInt($topic.attr('id').match(/\d+/)[0], 10);
1267 var lessons = {};
1268
1269 $topic.find('.course-content-item').each(function (lessonIndex, lessonItem) {
1270 var $lesson = $(this);
1271 var lesson_id = parseInt($lesson.attr('id').match(/\d+/)[0], 10);
1272
1273 lessons[lessonIndex] = lesson_id;
1274 });
1275 topics[index] = { 'topic_id': topics_id, 'lesson_ids': lessons };
1276 });
1277 $('#tutor_topics_lessons_sorting').val(JSON.stringify(topics));
1278 }
1279
1280 /**
1281 * Lesson Update or Create Modal
1282 */
1283 $(document).on('click', '.update_lesson_modal_btn', function (event) {
1284 event.preventDefault();
1285
1286 var $that = $(this);
1287 var content;
1288 var editor = tinyMCE.get('tutor_lesson_modal_editor');
1289 if (editor) {
1290 content = editor.getContent();
1291 } else {
1292 content = $('#' + inputid).val();
1293 }
1294
1295 var form_data = $(this).closest('form').serializeObject();
1296 form_data.lesson_content = content;
1297
1298 $.ajax({
1299 url: window._tutorobject.ajaxurl,
1300 type: 'POST',
1301 data: form_data,
1302 beforeSend: function () {
1303 $that.addClass('tutor-updating-message');
1304 },
1305 success: function (data) {
1306 if (data.success) {
1307 $('#tutor-course-content-wrap').html(data.data.course_contents);
1308 enable_sorting_topic_lesson();
1309
1310 //Close the modal
1311 $('.tutor-lesson-modal-wrap').removeClass('show');
1312
1313 tutor_toast(__('Done', 'tutor'), $that.data('toast_success_message'), 'success');
1314 }
1315 else {
1316 tutor_toast(__('Failed', 'tutor'), __('Lesson Update Failed', 'tutor'), 'error');
1317 }
1318 },
1319 error: function() {
1320 tutor_toast(__('Failed', 'tutor'), __('Lesson Update Failed', 'tutor'), 'error');
1321 },
1322 complete: function () {
1323 $that.removeClass('tutor-updating-message');
1324 }
1325 });
1326 });
1327
1328 /**
1329 * END: Tutor Course builder JS
1330 */
1331
1332 /**
1333 * Attachment in forntend course builder
1334 * @since v.1.3.4
1335 */
1336 $(document).on('click', 'a.tutor-delete-attachment', function (e) {
1337 e.preventDefault();
1338 $(this).closest('.tutor-added-attachment').remove();
1339 });
1340 $(document).on('click', '.tutorUploadAttachmentBtn', function (e) {
1341 e.preventDefault();
1342
1343 var $that = $(this);
1344 var frame;
1345 if (frame) {
1346 frame.open();
1347 return;
1348 }
1349 frame = wp.media({
1350 title: __( 'Select / Upload Media Of Your Chosen Persuasion', 'tutor' ),
1351 button: {
1352 text: __( 'Use media', 'tutor' )
1353 },
1354 multiple: true // Set to true to allow multiple files to be selected
1355 });
1356 frame.on('select', function () {
1357 var attachments = frame.state().get('selection').toJSON();
1358 if (attachments.length) {
1359 for (var i = 0; i < attachments.length; i++) {
1360 var attachment = attachments[i];
1361
1362 var inputHtml = '<div class="tutor-added-attachment"><i class="tutor-icon-archive"></i><a href="javascript:;" class="tutor-delete-attachment tutor-icon-line-cross"></a> <span> <a href="' + attachment.url + '">' + attachment.filename + '</a> </span> <input type="hidden" name="tutor_attachments[]" value="' + attachment.id + '"></div>';
1363 $that.closest('.tutor-lesson-attachments-metabox').find('.tutor-added-attachments-wrap').append(inputHtml);
1364 }
1365 }
1366 });
1367 frame.open();
1368 });
1369
1370
1371 /**
1372 * Single Assignment Upload Button
1373 * @since v.1.3.4
1374 */
1375 $('form').on('change', '.tutor-assignment-file-upload', function () {
1376 $(this).siblings("label").find('span').html($(this).val().replace(/.*(\/|\\)/, ''));
1377 });
1378
1379 /**
1380 * Lesson Sidebar Topic Toggle
1381 * @since v.1.3.4
1382 */
1383
1384 $(document).on('click', '.tutor-topics-in-single-lesson .tutor-topics-title h3, .tutor-single-lesson-topic-toggle', function (e) {
1385 var $that = $(this);
1386 var $parent = $that.closest('.tutor-topics-in-single-lesson');
1387 $parent.toggleClass('tutor-topic-active');
1388 $parent.find('.tutor-lessons-under-topic').slideToggle();
1389 });
1390
1391 $('.tutor-single-lesson-items.active').closest('.tutor-lessons-under-topic').show();
1392 $('.tutor-single-lesson-items.active').closest('.tutor-topics-in-single-lesson').addClass('tutor-topic-active');
1393 $('.tutor-course-lesson.active').closest('.tutor-lessons-under-topic').show();
1394
1395
1396 /**
1397 * Assignments Addons
1398 * @backend Support
1399 *
1400 */
1401
1402
1403 /**
1404 * Tutor Assignments JS
1405 * @since v.1.3.3
1406 */
1407 $(document).on('click', '.tutor-create-assignments-btn', function (e) {
1408 e.preventDefault();
1409
1410 var $that = $(this);
1411 var topic_id = $(this).attr('data-topic-id');
1412 var course_id = $('#post_ID').val();
1413
1414 $.ajax({
1415 url: window._tutorobject.ajaxurl,
1416 type: 'POST',
1417 data: { topic_id: topic_id, course_id: course_id, action: 'tutor_load_assignments_builder_modal' },
1418 beforeSend: function () {
1419 $that.addClass('tutor-updating-message');
1420 },
1421 success: function (data) {
1422 $('.tutor-lesson-modal-wrap .modal-container').html(data.data.output);
1423 $('.tutor-lesson-modal-wrap').attr('data-topic-id', topic_id).addClass('show');
1424
1425 $(document).trigger('assignment_modal_loaded', { topic_id: topic_id, course_id: course_id });
1426
1427 tinymce.init(tinyMCEPreInit.mceInit.course_description);
1428 tinymce.execCommand('mceRemoveEditor', false, 'tutor_assignments_modal_editor');
1429 tinyMCE.execCommand('mceAddEditor', false, "tutor_assignments_modal_editor");
1430 },
1431 complete: function () {
1432 quicktags({ id: "tutor_assignments_modal_editor" });
1433 $that.removeClass('tutor-updating-message');
1434 }
1435 });
1436 });
1437
1438 $(document).on('click', '.open-tutor-assignment-modal', function (e) {
1439 e.preventDefault();
1440
1441 var $that = $(this);
1442 var assignment_id = $that.attr('data-assignment-id');
1443 var topic_id = $that.attr('data-topic-id');
1444 var course_id = $('#post_ID').val();
1445
1446 $.ajax({
1447 url: window._tutorobject.ajaxurl,
1448 type: 'POST',
1449 data: { assignment_id: assignment_id, topic_id: topic_id, course_id: course_id, action: 'tutor_load_assignments_builder_modal' },
1450 beforeSend: function () {
1451 $that.addClass('tutor-updating-message');
1452 },
1453 success: function (data) {
1454 $('.tutor-lesson-modal-wrap .modal-container').html(data.data.output);
1455 $('.tutor-lesson-modal-wrap').attr({ 'data-assignment-id': assignment_id, 'data-topic-id': topic_id }).addClass('show');
1456
1457 $(document).trigger('assignment_modal_loaded', { assignment_id: assignment_id, topic_id: topic_id, course_id: course_id });
1458
1459 tinymce.init(tinyMCEPreInit.mceInit.course_description);
1460 tinymce.execCommand('mceRemoveEditor', false, 'tutor_assignments_modal_editor');
1461 tinyMCE.execCommand('mceAddEditor', false, "tutor_assignments_modal_editor");
1462 },
1463 complete: function () {
1464 quicktags({ id: "tutor_assignments_modal_editor" });
1465 $that.removeClass('tutor-updating-message');
1466 }
1467 });
1468 });
1469
1470 /**
1471 * Update Assignment Data
1472 */
1473 $(document).on('click', '.update_assignment_modal_btn', function (event) {
1474 event.preventDefault();
1475
1476 var $that = $(this);
1477 var content;
1478 var editor = tinyMCE.get('tutor_assignments_modal_editor');
1479 if (editor) {
1480 content = editor.getContent();
1481 } else {
1482 content = $('#' + inputid).val();
1483 }
1484
1485 var form_data = $(this).closest('form').serializeObject();
1486 form_data.assignment_content = content;
1487
1488 $.ajax({
1489 url: window._tutorobject.ajaxurl,
1490 type: 'POST',
1491 data: form_data,
1492 beforeSend: function () {
1493 $that.addClass('tutor-updating-message');
1494 },
1495 success: function (data) {
1496 if (data.success) {
1497 $('#tutor-course-content-wrap').html(data.data.course_contents);
1498 enable_sorting_topic_lesson();
1499
1500 //Close the modal
1501 $('.tutor-lesson-modal-wrap').removeClass('show');
1502
1503 tutor_toast(__('Done', 'tutor'), $that.data('toast_success_message'), 'success');
1504 }
1505 else {
1506 tutor_toast(__('Failed', 'tutor'), __('Assignment Update Failed', 'tutor'), 'error');
1507 }
1508 },
1509 error: function() {
1510 tutor_toast(__('Failed', 'tutor'), __('Assignment Update Failed', 'tutor'), 'error');
1511 },
1512 complete: function () {
1513 $that.removeClass('tutor-updating-message');
1514 }
1515 });
1516 });
1517
1518 /**
1519 * Add Assignment
1520 */
1521 $(document).on('click', '.add-assignment-attachments', function (event) {
1522 event.preventDefault();
1523
1524 var $that = $(this);
1525 var frame;
1526 // If the media frame already exists, reopen it.
1527 if (frame) {
1528 frame.open();
1529 return;
1530 }
1531
1532 // Create a new media frame
1533 frame = wp.media({
1534 title: __( 'Select / Upload Media Of Your Chosen Persuasion', 'tutor' ),
1535 button: {
1536 text: __( 'Use media', 'tutor' )
1537 },
1538 multiple: false // Set to true to allow multiple files to be selected
1539 });
1540
1541 // When an image is selected in the media frame...
1542 frame.on('select', function () {
1543 // Get media attachment details from the frame state
1544 var attachment = frame.state().get('selection').first().toJSON();
1545
1546 var field_markup = '<div class="tutor-individual-attachment-file"><p class="attachment-file-name">' + attachment.filename + '</p><input type="hidden" name="tutor_assignment_attachments[]" value="' + attachment.id + '"><a href="javascript:;" class="remove-assignment-attachment-a text-muted"> &times; Remove</a></div>';
1547
1548 $('#assignment-attached-file').append(field_markup);
1549 $that.closest('.video_source_upload_wrap_html5').find('input').val(attachment.id);
1550 });
1551 // Finally, open the modal on click
1552 frame.open();
1553 });
1554
1555 $(document).on('click', '.remove-assignment-attachment-a', function (event) {
1556 event.preventDefault();
1557 $(this).closest('.tutor-individual-attachment-file').remove();
1558 });
1559
1560
1561 /**
1562 *
1563 * @type {jQuery}
1564 *
1565 * Course builder auto draft save
1566 *
1567 * @since v.1.3.4
1568 */
1569 var tutor_course_builder = $('input[name="tutor_action"]').val();
1570 if (tutor_course_builder === 'tutor_add_course_builder') {
1571 setInterval(auto_draft_save_course_builder, 30000);
1572 }
1573
1574 function auto_draft_save_course_builder() {
1575
1576 var form_data = $('form#tutor-frontend-course-builder').serializeObject();
1577 form_data.tutor_ajax_action = 'tutor_course_builder_draft_save';
1578
1579 $.ajax({
1580 //url : _tutorobject.ajaxurl,
1581 type: 'POST',
1582 data: form_data,
1583 beforeSend: function () {
1584 $('.tutor-dashboard-builder-draft-btn span').text( __( 'Saving...', 'tutor' ) );
1585 },
1586 success: function (data) {
1587
1588 },
1589 complete: function () {
1590 $('.tutor-dashboard-builder-draft-btn span').text( __( 'Save', 'tutor' ) );
1591 }
1592 });
1593 }
1594
1595 /**
1596 *
1597 * @type {jQuery}
1598 *
1599 * Course builder section toggle
1600 *
1601 * @since v.1.3.5
1602 */
1603
1604 $('.tutor-course-builder-section-title').on('click', function () {
1605 if ($(this).find('i').hasClass("tutor-icon-up")) {
1606 $(this).find('i').removeClass('tutor-icon-up').addClass('tutor-icon-down');
1607 } else {
1608 $(this).find('i').removeClass('tutor-icon-down').addClass('tutor-icon-up');
1609 }
1610 $(this).next('div').slideToggle();
1611 });
1612
1613 /**
1614 * Open Tutor Modal to edit review
1615 * @since v.1.4.0
1616 */
1617 $(document).on('click', '.open-tutor-edit-review-modal', function (e) {
1618 e.preventDefault();
1619
1620 var $that = $(this);
1621 var review_id = $that.attr('data-review-id');
1622
1623 var nonce_key = _tutorobject.nonce_key;
1624
1625 var json_data = { review_id: review_id, action: 'tutor_load_edit_review_modal' };
1626 json_data[nonce_key] = _tutorobject[nonce_key];
1627
1628 $.ajax({
1629 url: _tutorobject.ajaxurl,
1630 type: 'POST',
1631 data: json_data,
1632 beforeSend: function () {
1633 $that.addClass('tutor-updating-message');
1634 },
1635 success: function (data) {
1636 if (typeof data.data !== 'undefined') {
1637 $('.tutor-edit-review-modal-wrap .modal-container').html(data.data.output);
1638 $('.tutor-edit-review-modal-wrap').attr('data-review-id', review_id).addClass('show');
1639 }
1640 },
1641 complete: function () {
1642 $that.removeClass('tutor-updating-message');
1643 }
1644 });
1645 });
1646
1647 /**
1648 * Update the rating
1649 * @since v.1.4.0
1650 */
1651 $(document).on('submit', '#tutor_update_review_form', function (e) {
1652 e.preventDefault();
1653
1654 var $that = $(this);
1655 var review_id = $that.closest('.tutor-edit-review-modal-wrap ').attr('data-review-id');
1656
1657 var nonce_key = _tutorobject.nonce_key;
1658
1659 var rating = $that.find('input[name="tutor_rating_gen_input"]').val();
1660 var review = $that.find('textarea[name="review"]').val();
1661 review = review.trim();
1662
1663 var json_data = { review_id: review_id, rating: rating, review: review, action: 'tutor_update_review_modal' };
1664 json_data[nonce_key] = _tutorobject[nonce_key];
1665
1666 $.ajax({
1667 url: _tutorobject.ajaxurl,
1668 type: 'POST',
1669 data: json_data,
1670 beforeSend: function () {
1671 $that.find('button[type="submit"]').addClass('tutor-updating-message');
1672 },
1673 success: function (data) {
1674 if (data.success) {
1675 //Close the modal
1676 $('.tutor-edit-review-modal-wrap').removeClass('show');
1677 location.reload(true);
1678 }
1679 },
1680 complete: function () {
1681 $that.find('button[type="submit"]').removeClass('tutor-updating-message');
1682 }
1683 });
1684 });
1685
1686 /**
1687 * Profile photo upload
1688 * @since v.1.4.5
1689 */
1690
1691 $(document).on('click', '#tutor_profile_photo_button', function (e) {
1692 e.preventDefault();
1693
1694 $('#tutor_profile_photo_file').trigger('click');
1695 });
1696
1697 $(document).on('change', '#tutor_profile_photo_file', function (event) {
1698 event.preventDefault();
1699
1700 var $file = this;
1701 if ($file.files && $file.files[0]) {
1702 var reader = new FileReader();
1703 reader.onload = function (e) {
1704 $('.tutor-profile-photo-upload-wrap').find('img').attr('src', e.target.result);
1705 }
1706 reader.readAsDataURL($file.files[0]);
1707 }
1708 });
1709
1710 /**
1711 * Addon, Tutor BuddyPress
1712 * Retrieve MetaInformation on BuddyPress message system
1713 * @for TutorLMS Pro
1714 * @since v.1.4.8
1715 */
1716
1717 $(document).on('click', '.thread-content .subject', function (e) {
1718 var $btn = $(this);
1719
1720 var thread_id = parseInt($btn.closest('.thread-content').attr('data-thread-id'));
1721
1722 var nonce_key = _tutorobject.nonce_key;
1723 var json_data = { thread_id: thread_id, action: 'tutor_bp_retrieve_user_records_for_thread' };
1724 json_data[nonce_key] = _tutorobject[nonce_key];
1725
1726 $.ajax({
1727 type: 'POST',
1728 url: window._tutorobject.ajaxurl,
1729 data: json_data,
1730 beforeSend: function () {
1731 $('#tutor-bp-thread-wrap').html('');
1732 },
1733 success: function (data) {
1734 if (data.success) {
1735 $('#tutor-bp-thread-wrap').html(data.data.thread_head_html);
1736 tutor_bp_setting_enrolled_courses_list();
1737 }
1738 }
1739 });
1740
1741 });
1742
1743
1744 function tutor_bp_setting_enrolled_courses_list() {
1745 $('ul.tutor-bp-enrolled-course-list').each(function () {
1746 var $that = $(this);
1747 var $li = $that.find(' > li');
1748 var itemShow = 3;
1749
1750 if ($li.length > itemShow) {
1751 var plusCourseCount = $li.length - itemShow;
1752 $li.each(function (liIndex, liItem) {
1753 var $liItem = $(this);
1754
1755 if (liIndex >= itemShow) {
1756 $liItem.hide();
1757 }
1758 });
1759
1760 var infoHtml = '<a href="javascript:;" class="tutor_bp_plus_courses"><strong>+' + plusCourseCount + ' More </strong></a> Courses';
1761 $that.closest('.tutor-bp-enrolled-courses-wrap').find('.thread-participant-enrolled-info').html(infoHtml);
1762 }
1763
1764 $that.show();
1765 });
1766 }
1767 tutor_bp_setting_enrolled_courses_list();
1768
1769 $(document).on('click', 'a.tutor_bp_plus_courses', function (e) {
1770 e.preventDefault();
1771
1772 var $btn = $(this);
1773 $btn.closest('.tutor-bp-enrolled-courses-wrap').find('.tutor-bp-enrolled-course-list li').show();
1774 $btn.closest('.thread-participant-enrolled-info').html('');
1775 });
1776
1777
1778 /**
1779 * Addon, Tutor Certificate
1780 * Certificate dropdown content and copy link
1781 * @for TutorLMS Pro
1782 * @since v.1.5.1
1783 */
1784 //$(document).on('click', '.tutor-dropbtn', function (e) {
1785 $('.tutor-dropbtn').click(function(){
1786
1787 var $content = $(this).parent().find(".tutor-dropdown-content");
1788 $content.slideToggle(100);
1789 })
1790
1791
1792 //$(document).on('click', '.tutor-copy-link', function (e) {
1793 $('.tutor-copy-link').click(function (e) {
1794 var $btn = $(this);
1795 var copy = '<i class="tutor-icon-copy"></i> Copy Link';
1796 var copied = '<i class="tutor-icon-mark"></i> Copied';
1797 var dummy = document.createElement('input'),
1798 text = window.location.href;
1799 document.body.appendChild(dummy);
1800 dummy.value = text;
1801 dummy.select();
1802 document.execCommand('copy');
1803 document.body.removeChild(dummy);
1804 $btn.html(copied);
1805 setTimeout(function () {
1806 $btn.html(copy);
1807 }, 2500);
1808 });
1809
1810 $(document).on('click', function (e) {
1811 var container = $(".tutor-dropdown");
1812 var $content = container.find('.tutor-dropdown-content');
1813 // if the target of the click isn't the container nor a descendant of the container
1814 if (!container.is(e.target) && container.has(e.target).length === 0) {
1815 $content.slideUp(100);
1816 }
1817 });
1818
1819
1820 /**
1821 * Tutor ajax login
1822 *
1823 * @since v.1.6.3
1824 */
1825 $(document).on('submit', '.tutor-login-form-wrap #loginform', function (e) {
1826 e.preventDefault();
1827
1828 var $that = $(this);
1829 var $form_wrapper = $('.tutor-login-form-wrap');
1830
1831 var form_data = $that.serializeObject();
1832 form_data.action = 'tutor_user_login';
1833 $.ajax({
1834 url: _tutorobject.ajaxurl,
1835 type: 'POST',
1836 data: form_data,
1837 success: function (response) {
1838 if (response.success) {
1839 location.assign(response.data.redirect);
1840 location.reload();
1841 } else {
1842 var error_message = response.data || __('Invalid username or password!', 'tutor');
1843 if ($form_wrapper.find('.tutor-alert').length) {
1844 $form_wrapper.find('.tutor-alert').html(error_message);
1845 } else {
1846 $form_wrapper.prepend('<div class="tutor-alert tutor-alert-warning">' + error_message + '</div>');
1847 }
1848 }
1849 },
1850 });
1851 });
1852
1853 /**
1854 * Show hide is course public checkbox (frontend dashboard editor)
1855 *
1856 * @since v.1.7.2
1857 */
1858 var price_type = $('.tutor-frontend-builder-course-price [name="tutor_course_price_type"]');
1859 if(price_type.length==0){
1860 $('#_tutor_is_course_public_meta_checkbox').show();
1861 }
1862 else{
1863 price_type.change(function(){
1864 if($(this).prop('checked')){
1865 var method = $(this).val()=='paid' ? 'hide' : 'show';
1866 $('#_tutor_is_course_public_meta_checkbox')[method]();
1867 }
1868 }).trigger('change');
1869 }
1870
1871 /**
1872 * Withdrawal page tooltip
1873 *
1874 * @since v.1.7.4
1875 */
1876 // Fully accessible tooltip jQuery plugin with delegation.
1877 // Ideal for view containers that may re-render content.
1878 (function ($) {
1879 $.fn.tutor_tooltip = function () {
1880 this
1881
1882 // Delegate to tooltip, Hide if tooltip receives mouse or is clicked (tooltip may stick if parent has focus)
1883 .on('mouseenter click', '.tooltip', function (e) {
1884 e.stopPropagation();
1885 $(this).removeClass('isVisible');
1886 })
1887 // Delegate to parent of tooltip, Show tooltip if parent receives mouse or focus
1888 .on('mouseenter focus', ':has(>.tooltip)', function (e) {
1889 if (!$(this).prop('disabled')) { // IE 8 fix to prevent tooltip on `disabled` elements
1890 $(this)
1891 .find('.tooltip')
1892 .addClass('isVisible');
1893 }
1894 })
1895 // Delegate to parent of tooltip, Hide tooltip if parent loses mouse or focus
1896 .on('mouseleave blur keydown', ':has(>.tooltip)', function (e) {
1897 if (e.type === 'keydown') {
1898 if(e.which === 27) {
1899 $(this)
1900 .find('.tooltip')
1901 .removeClass('isVisible');
1902 }
1903 } else {
1904 $(this)
1905 .find('.tooltip')
1906 .removeClass('isVisible');
1907 }
1908 });
1909 return this;
1910 };
1911 }(jQuery));
1912
1913 // Bind event listener to container element
1914 jQuery('.tutor-tooltip-inside').tutor_tooltip();
1915
1916
1917
1918 /**
1919 * Manage course filter
1920 *
1921 * @since v.1.7.2
1922 */
1923 var filter_container = $('.tutor-course-filter-container form');
1924 var loop_container = $('.tutor-course-filter-loop-container');
1925 var filter_modifier = {};
1926
1927 // Sidebar checkbox value change
1928 filter_container.on('submit', function(e) {
1929 e.preventDefault();
1930 })
1931 .find('input').change(function(e){
1932
1933 var filter_criteria = Object.assign( filter_container.serializeObject(), filter_modifier);
1934 filter_criteria.action = 'tutor_course_filter_ajax';
1935
1936 loop_container.html('<center><img src="'+window._tutorobject.loading_icon_url+'"/></center>');
1937 $(this).closest('form').find('.tutor-clear-all-filter').show();
1938
1939 $.ajax({
1940 url:window._tutorobject.ajaxurl,
1941 type:'POST',
1942 data:filter_criteria,
1943 success:function(r) {
1944 loop_container.html(r).find('.tutor-pagination-wrap a').each(function(){
1945 $(this).attr('data-href', $(this).attr('href')).attr('href', '#');
1946 });
1947 }
1948 })
1949 });
1950
1951 // Alter pagination
1952 loop_container.on('click', '.tutor-pagination-wrap a', function(e){
1953 var url = $(this).data('href') || $(this).attr('href');
1954
1955 if(url){
1956 url = new URL(url);
1957 var page = url.searchParams.get("paged");
1958
1959 if(page){
1960 e.preventDefault();
1961 filter_modifier.page = page;
1962 filter_container.find('input:first').trigger('change');
1963 }
1964 }
1965 });
1966
1967 // Alter sort filter
1968 loop_container.on('change', 'select[name="tutor_course_filter"]', function() {
1969 filter_modifier.tutor_course_filter = $(this).val();
1970 filter_container.find('input:first').trigger('change');
1971 });
1972
1973 // Refresh page after coming back to course archive page from cart
1974 var archive_loop = $('.tutor-course-loop');
1975 if(archive_loop.length>0){
1976 window.sessionStorage.getItem('tutor_refresh_archive')==='yes' ? window.location.reload() : 0;
1977 window.sessionStorage.removeItem('tutor_refresh_archive');
1978 archive_loop.on('click', '.tutor-loop-cart-btn-wrap', function(){
1979 window.sessionStorage.setItem('tutor_refresh_archive', 'yes');
1980 });
1981 }
1982
1983 /**
1984 * Profile Photo and Cover Photo editor
1985 *
1986 * @since v.1.7.5
1987 */
1988 var PhotoEditor=function(photo_editor){
1989
1990 this.dialogue_box = photo_editor.find('#tutor_photo_dialogue_box');
1991
1992
1993 this.open_dialogue_box = function(name){
1994 this.dialogue_box.attr('name', name);
1995 this.dialogue_box.trigger('click');
1996 }
1997
1998 this.validate_image = function(file){
1999 return true;
2000 }
2001
2002 this.upload_selected_image = function(name, file){
2003 if(!file || !this.validate_image(file)){
2004 return;
2005 }
2006
2007 var nonce = tutor_get_nonce_data(true);
2008
2009 var context = this;
2010 context.toggle_loader(name, true);
2011
2012 // Prepare payload to upload
2013 var form_data = new FormData();
2014 form_data.append('action', 'tutor_user_photo_upload');
2015 form_data.append('photo_type', name);
2016 form_data.append('photo_file', file, file.name);
2017 form_data.append(nonce.key, nonce.value);
2018
2019 $.ajax({
2020 url:window._tutorobject.ajaxurl,
2021 data:form_data,
2022 type:'POST',
2023 processData: false,
2024 contentType: false,
2025 error:context.error_alert,
2026 complete:function(){
2027 context.toggle_loader(name, false);
2028 }
2029 })
2030 }
2031
2032 this.accept_upload_image=function(context, e){
2033 var file = e.currentTarget.files[0] || null;
2034 context.update_preview(e.currentTarget.name, file);
2035 context.upload_selected_image(e.currentTarget.name, file);
2036 $(e.currentTarget).val('');
2037 }
2038
2039 this.delete_image=function(name){
2040 var context = this;
2041 context.toggle_loader(name, true);
2042
2043 $.ajax({
2044 url:window._tutorobject.ajaxurl,
2045 data:{action:'tutor_user_photo_remove', photo_type:name},
2046 type:'POST',
2047 error:context.error_alert,
2048 complete:function(){
2049 context.toggle_loader(name, false);
2050 }
2051 });
2052 }
2053
2054 this.update_preview=function(name, file){
2055 var renderer = photo_editor.find(name=='cover_photo' ? '#tutor_cover_area' : '#tutor_profile_area');
2056
2057 if(!file){
2058 renderer.css('background-image', 'url('+renderer.data('fallback')+')');
2059 this.delete_image(name);
2060 return;
2061 }
2062
2063 var reader = new FileReader();
2064 reader.onload = function(e) {
2065 renderer.css('background-image', 'url('+e.target.result+')');
2066 }
2067
2068 reader.readAsDataURL(file);
2069 }
2070
2071 this.toggle_profile_pic_action=function(show){
2072 var method = show===undefined ? 'toggleClass' : (show ? 'addClass' : 'removeClass');
2073 photo_editor[method]('pop-up-opened');
2074 }
2075
2076 this.error_alert=function(){
2077 alert('Something Went Wrong.');
2078 }
2079
2080 this.toggle_loader = function(name, show){
2081 photo_editor.find('#tutor_photo_meta_area .loader-area').css('display', (show ? 'block' : 'none'));
2082 }
2083
2084 this.initialize = function(){
2085 var context = this;
2086
2087 this.dialogue_box.change(function(e){context.accept_upload_image(context, e)});
2088
2089 photo_editor.find('#tutor_profile_area .tutor_overlay, #tutor_pp_option>div:last-child').click(function(){context.toggle_profile_pic_action()});
2090
2091 // Upload new
2092 photo_editor.find('.tutor_cover_uploader').click(function(){context.open_dialogue_box('cover_photo')});
2093 photo_editor.find('.tutor_pp_uploader').click(function(){context.open_dialogue_box('profile_photo')});
2094
2095 // Delete existing
2096 photo_editor.find('.tutor_cover_deleter').click(function(){context.update_preview('cover_photo', null)});
2097 photo_editor.find('.tutor_pp_deleter').click(function(){context.update_preview('profile_photo', null)});
2098 }
2099 }
2100
2101 var photo_editor = $('#tutor_profile_cover_photo_editor');
2102 photo_editor.length>0 ? new PhotoEditor(photo_editor).initialize() : 0;
2103
2104
2105 /**
2106 *
2107 * Instructor list filter
2108 *
2109 * @since v.1.8.4
2110 */
2111 // Get values on course category selection
2112 $('.tutor-instructor-filter').each(function() {
2113
2114 var root = $(this);
2115 var filter_args = {};
2116 var time_out;
2117
2118 function run_instructor_filter(name, value, page_number) {
2119
2120 // Prepare http payload
2121 var result_container = root.find('.filter-result-container');
2122 var html_cache = result_container.html();
2123 var attributes = root.data();
2124 attributes.current_page = page_number || 1;
2125
2126 name ? filter_args[name] = value : filter_args = {};
2127 filter_args.attributes = attributes;
2128 filter_args.action = 'load_filtered_instructor';
2129
2130 // Show loading icon
2131 result_container.html('<div style="text-align:center"><img src="'+window._tutorobject.loading_icon_url+'"/></div>');
2132
2133 $.ajax({
2134 url: window._tutorobject.ajaxurl,
2135 data: filter_args,
2136 type: 'POST',
2137 success: function(r) {
2138 result_container.html(r);
2139 },
2140 error: function() {
2141 result_container.html(html_cache);
2142 tutor_toast('Failed', 'Request Error', 'error');
2143 }
2144 })
2145 }
2146
2147 root.on('change', '.course-category-filter [type="checkbox"]', function() {
2148
2149 var values = {};
2150
2151 $(this).closest('.course-category-filter').find('input:checked').each(function() {
2152 values[$(this).val()] = $(this).parent().text();
2153 });
2154
2155 // Show selected cat list
2156 var cat_parent = root.find('.selected-cate-list').empty();
2157 var cat_ids = Object.keys(values);
2158
2159 cat_ids.forEach(function(value) {
2160 cat_parent.append('<span>'+values[value]+' <span class="tutor-icon-line-cross" data-cat_id="'+value+'"></span></span>');
2161 });
2162
2163 cat_ids.length ? cat_parent.append('<span data-cat_id="0">Clear All</span>') : 0;
2164
2165 run_instructor_filter($(this).attr('name'), cat_ids);
2166 })
2167 .on('click', '.selected-cate-list [data-cat_id]', function() {
2168
2169 var id = $(this).data('cat_id');
2170 var inputs = root.find('.mobile-filter-popup [type="checkbox"]');
2171 id ? inputs = inputs.filter('[value="'+id+'"]') : 0;
2172
2173 inputs.prop('checked', false).trigger('change');
2174 })
2175 .on('input', '.filter-pc [name="keyword"]', function() {
2176 // Get values on search keyword change
2177
2178 var val = $(this).val();
2179
2180 time_out ? window.clearTimeout(time_out) : 0;
2181
2182 time_out = window.setTimeout(function() {
2183
2184 run_instructor_filter('keyword', val);
2185 time_out = null;
2186
2187 }, 500);
2188 })
2189 .on('click', '[data-page_number]', function(e) {
2190
2191 // On pagination click
2192 e.preventDefault();
2193
2194 run_instructor_filter(null, null, $(this).data( 'page_number' ) );
2195
2196 }).on('click', '.clear-instructor-filter', function() {
2197
2198 // Clear filter
2199 var root = $(this).closest('.tutor-instructor-filter');
2200
2201 root.find('input[type="checkbox"]').prop('checked', false);
2202
2203 root.find('[name="keyword"]').val('');
2204
2205 run_instructor_filter();
2206 })
2207 .on('click', '.mobile-filter-container i', function () {
2208 // Open mobile screen filter
2209 $(this).parent().next().addClass('is-opened');
2210 })
2211 .on('click', '.mobile-filter-popup button', function() {
2212
2213 $('.mobile-filter-popup [type="checkbox"]').trigger('change');
2214
2215 // Close mobile screen filter
2216 $(this).closest('.mobile-filter-popup').removeClass('is-opened');
2217
2218 }).on('input', '.filter-mobile [name="keyword"]', function() {
2219
2220 // Sync keyword with two screen
2221
2222 root.find('.filter-pc [name="keyword"]').val($(this).val()).trigger('input');
2223
2224 }).on('change', '.mobile-filter-popup [type="checkbox"]', function(e) {
2225
2226 if(e.originalEvent) {
2227 return;
2228 }
2229
2230 // Sync category with two screen
2231 var name = $(this).attr('name');
2232 var val = $(this).val();
2233 var checked = $(this).prop('checked');
2234
2235 root.find('.course-category-filter [name="'+name+'"]').filter('[value="'+val+'"]').prop('checked', checked).trigger('change');
2236
2237 }).on('mousedown touchstart', '.expand-instructor-filter', function(e) {
2238
2239 var window_height = $(window).height();
2240 var el = root.find('.mobile-filter-popup>div');
2241 var el_top = window_height-el.height();
2242 var plus = ((e.originalEvent.touches || [])[0] || e).clientY - el_top;
2243
2244 root.on('mousemove touchmove', function(e){
2245
2246 var y = ((e.originalEvent.touches || [])[0] || e).clientY;
2247
2248 var height = (window_height-y)+plus;
2249
2250 (height>200 && height<=window_height) ? el.css('height', height+'px') : 0;
2251 });
2252
2253 }).on('mouseup touchend', function(){
2254
2255 root.off('mousemove touchmove');
2256 })
2257 .on('click', '.mobile-filter-popup>div', function(e) {
2258 e.stopImmediatePropagation();
2259 }).on('click', '.mobile-filter-popup', function(e) {
2260 $(this).removeClass('is-opened');;
2261 });
2262 });
2263
2264 /**
2265 * Retake course
2266 *
2267 * @since v1.9.5
2268 */
2269 $('.tutor-course-retake-button').click(function(e) {
2270 e.preventDefault();
2271
2272 var button = $(this);
2273 var url = button.attr('href');
2274 var course_id = button.data('course_id');
2275
2276 var popup;
2277
2278 var data = {
2279 title: __('Override Previous Progress', 'tutor'),
2280 description : __('Before continue, please decide whether to keep progress or reset.', 'tutor'),
2281 buttons : {
2282 reset: {
2283 title: __('Reset Data', 'tutor'),
2284 class: 'secondary',
2285
2286 callback: function() {
2287
2288 var button = popup.find('.tutor-button-secondary');
2289 button.prop('disabled', true).append('<img style="margin-left: 7px" src="'+ window._tutorobject.loading_icon_url +'"/>');
2290
2291 $.ajax({
2292 url: window._tutorobject.ajaxurl,
2293 type: 'POST',
2294 data: {action: 'tutor_reset_course_progress', course_id: course_id},
2295 success: function(response) {
2296 if(response.success) {
2297 window.location.assign(response.data.redirect_to);
2298 } else {
2299 alert((response.data || {}).message || __('Something went wrong', 'tutor'));
2300 }
2301 },
2302 complete: function() {
2303 button.prop('disabled', false).find('img').remove();
2304 }
2305 });
2306 }
2307 },
2308 keep: {
2309 title: __('Keep Data', 'tutor'),
2310 class: 'primary',
2311 callback: function() {
2312 window.location.assign(url);
2313 }
2314 }
2315 }
2316 };
2317
2318 popup = new window.tutor_popup($, 'icon-gear', 40).popup(data);
2319 });
2320
2321
2322 //warn user before leave page if quiz is running
2323 document.body.addEventListener('click', function(event){
2324 const target = event.target;
2325 const targetTag = target.tagName
2326 const parentTag = target.parentElement.tagName;
2327
2328 if ( $tutor_quiz_time_update.length > 0 && $tutor_quiz_time_update.html() != 'EXPIRED' ) {
2329 if ( targetTag === 'A' || parentTag === 'A' ) {
2330 event.preventDefault();
2331 event.stopImmediatePropagation();
2332 let popup;
2333
2334 let data = {
2335 title: __( 'Abandon Quiz?', 'tutor' ),
2336 description : __( 'Do you want to abandon this quiz? The quiz will be submitted partially up to this question if you leave this page.', 'tutor' ),
2337 buttons : {
2338 keep: {
2339 title: __( 'Yes, leave quiz', 'tutor' ),
2340 id: 'leave',
2341 class: 'secondary',
2342 callback: function() {
2343
2344 var formData = $('form#tutor-answering-quiz').serialize()+'&action='+'tutor_quiz_abandon';
2345 $.ajax({
2346 url: window._tutorobject.ajaxurl,
2347 type: 'POST',
2348 data: formData,
2349 beforeSend: function() {
2350 document.querySelector("#tutor-popup-leave").innerHTML = __( 'Leaving...', 'tutor' );
2351 },
2352 success: function(response) {
2353 if(response.success) {
2354 if ( target.href == undefined ) {
2355 location.href = target.parentElement.href
2356 } else {
2357 location.href = target.href
2358 }
2359 } else {
2360 alert( __( 'Something went wrong', 'tutor' ) );
2361 }
2362 },
2363 error: function() {
2364 alert( __( 'Something went wrong', 'tutor' ) );
2365 popup.remove();
2366 }
2367 });
2368 }
2369 },
2370 reset: {
2371 title: __('Stay here', 'tutor'),
2372 id: 'reset',
2373 class: 'primary',
2374 callback: function() {
2375 popup.remove();
2376 }
2377 },
2378 }
2379 };
2380
2381 popup = new window.tutor_popup($, '', 40).popup(data);
2382 }
2383 }
2384 });
2385
2386 /* Disable start quiz button */
2387 $('body').on('submit', 'form#tutor-start-quiz', function() {
2388 $(this).find('button').prop('disabled', true);
2389 });
2390
2391 /** Disable typing on datePicker field */
2392 $('.hasDatepicker, .tutor_date_picker').keydown( function( e ) {
2393 if ( e.keyCode !== 8 ) {
2394 e.preventDefault();
2395 }
2396 });
2397
2398 });