PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / assets / src / js / frontend / courses.js

courses.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at assets/src/js/frontend/courses.js

588 lines 17.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * @deprecated 4.2.5.8
3 * But still support for theme has html old, override.
4 * Todo: if want remove file, need to check theme override file archive, can via remove hook override file.
5 */
6
7 import API from '../api';
8 import { lpAddQueryArgs, lpFetchAPI, lpGetCurrentURLNoParam } from '../utils';
9 import Cookies from '../utils/cookies';
10
11 const elListCoursesIdNewDefault = '.lp-list-courses-default';
12
13 if ( 'undefined' === typeof lpData || 'undefined' === typeof lpSettingCourses ) {
14 console.log( 'lpData || lpSettingCourses is undefined' );
15 }
16
17 // Call API load courses.
18 // When LP v4.2.3.3 release a long time, we will remove this function on theme Eduma.
19 // assets/js/thim-course-filter-v2.js
20 window.lpArchiveRequestCourse = ( args ) => {
21 window.lpCourseList.updateEventTypeBeforeFetch( 'filter' );
22 window.lpCourseList.triggerFetchAPI( args );
23 };
24
25 // Events
26 document.addEventListener( 'change', function( e ) {
27 const target = e.target;
28 if ( window.lpCourseList.checkIsNewListCourses() ) {
29 return;
30 }
31
32 window.lpCourseList.onChangeSortBy( e, target );
33 window.lpCourseList.onChangeTypeLayout( e, target );
34 } );
35 document.addEventListener( 'click', function( e ) {
36 const target = e.target;
37
38 if ( window.lpCourseList.checkIsNewListCourses() ) {
39 return;
40 }
41
42 window.lpCourseList.clickLoadMore( e, target );
43 window.lpCourseList.clickNumberPage( e, target );
44 } );
45 document.addEventListener( 'scroll', function( e ) {
46 const target = e.target;
47
48 if ( window.lpCourseList.checkIsNewListCourses() ) {
49 return;
50 }
51
52 window.lpCourseList.scrollInfinite( e, target );
53 } );
54 document.addEventListener( 'keyup', function( e ) {
55 const target = e.target;
56
57 if ( window.lpCourseList.checkIsNewListCourses() ) {
58 return;
59 }
60
61 window.lpCourseList.searchCourse( e, target );
62 } );
63 document.addEventListener( 'submit', function( e ) {
64 const target = e.target;
65
66 if ( window.lpCourseList.checkIsNewListCourses() ) {
67 return;
68 }
69
70 window.lpCourseList.searchCourse( e, target );
71 } );
72
73 window.lpCourseList = ( () => {
74 const classArchiveCourse = 'lp-archive-courses';
75 const classListCourse = 'learn-press-courses';
76 const classPaginationCourse = 'learn-press-pagination';
77 const classSkeletonArchiveCourse = 'lp-archive-course-skeleton';
78 const classCoursesPageResult = 'courses-page-result';
79 const lpArchiveLoadAjax = parseInt( lpSettingCourses.lpArchiveLoadAjax || 0 );
80 const lpArchiveNoLoadAjaxFirst = parseInt( lpSettingCourses.lpArchiveNoLoadAjaxFirst ) === 1;
81 const lpArchiveSkeletonParam = lpData.urlParams || [];
82 const currentUrl = lpGetCurrentURLNoParam();
83 let filterCourses = {};
84 const typePagination = lpSettingCourses.lpArchivePaginationType || 'number';
85 let typeEventBeforeFetch;
86 let timeOutSearch;
87 let isLoadingInfinite = false;
88 const fetchAPI = ( args, callBack = {} ) => {
89 //console.log( 'Fetch API Courses' );
90 const url = lpAddQueryArgs( API.frontend.apiCourses, args );
91 let paramsFetch = {};
92
93 if ( 0 !== parseInt( lpData.user_id ) ) {
94 paramsFetch = {
95 headers: {
96 'X-WP-Nonce': lpData.nonce,
97 },
98 };
99 }
100
101 lpFetchAPI( url, paramsFetch, callBack );
102 };
103 return {
104 init: () => {
105 const urlParams = {};
106 const urlQueryString = window.location.search;
107 const urlSearchParams = new URLSearchParams( urlQueryString );
108 for ( const [ key, val ] of urlSearchParams.entries() ) {
109 urlParams[ key ] = val;
110 }
111
112 filterCourses = { ...lpArchiveSkeletonParam, ...urlParams };
113 filterCourses.paged = parseInt( filterCourses.paged || 1 );
114 if ( isNaN( filterCourses.paged ) ) {
115 filterCourses.paged = 1;
116 }
117 if ( lpArchiveNoLoadAjaxFirst && typePagination !== 'number' ) {
118 filterCourses.paged = 1;
119 }
120 window.localStorage.setItem( 'lp_filter_courses', JSON.stringify( filterCourses ) );
121 },
122 updateEventTypeBeforeFetch: ( type ) => {
123 typeEventBeforeFetch = type;
124 },
125 onChangeSortBy: ( e, target ) => {
126 if ( ! target.classList.contains( 'courses-order-by' ) ) {
127 return;
128 }
129
130 e.preventDefault();
131
132 const filterCourses = JSON.parse( window.localStorage.getItem( 'lp_filter_courses' ) ) || {};
133 filterCourses.order_by = target.value || '';
134
135 if ( 'undefined' !== typeof lpSettingCourses &&
136 lpData.is_course_archive &&
137 lpSettingCourses.lpArchiveLoadAjax ) {
138 window.lpCourseList.triggerFetchAPI( filterCourses );
139 } else {
140 window.location.href = lpAddQueryArgs( currentUrl, filterCourses );
141 }
142 },
143 onChangeTypeLayout: ( e, target ) => {
144 if ( 'lp-switch-layout-btn' !== target.getAttribute( 'name' ) ) {
145 return;
146 }
147 const elArchive = target.closest( `.${ classArchiveCourse }` );
148 if ( ! elArchive ) {
149 return;
150 }
151 const elListCourse = elArchive.querySelector( `.${ classListCourse }` );
152 if ( ! elListCourse ) {
153 return;
154 }
155 e.preventDefault();
156 const layout = target.value;
157 if ( layout ) {
158 elListCourse.dataset.layout = layout;
159 Cookies.set( 'courses-layout', layout );
160 }
161 },
162 clickNumberPage: ( e, target ) => {
163 if ( ! lpArchiveLoadAjax || parseInt( lpSettingCourses.noLoadCoursesJs ) ) {
164 return;
165 }
166
167 if ( target.classList.contains( 'page-numbers' ) ) {
168 const parentArchive = target.closest( `.${ classArchiveCourse }` );
169 if ( ! parentArchive ) {
170 return;
171 }
172
173 e.preventDefault();
174 const pageCurrent = filterCourses.paged;
175 if ( target.classList.contains( 'prev' ) ) {
176 filterCourses.paged = pageCurrent - 1;
177 } else if ( target.classList.contains( 'next' ) ) {
178 filterCourses.paged = pageCurrent + 1;
179 } else {
180 filterCourses.paged = parseInt( target.textContent );
181 }
182
183 typeEventBeforeFetch = 'number';
184 window.lpCourseList.triggerFetchAPI( filterCourses );
185 return;
186 }
187
188 const parent = target.closest( '.page-numbers' );
189 if ( parent ) {
190 e.preventDefault();
191 parent.click();
192 }
193 },
194 clickLoadMore: ( e, target ) => {
195 if ( ! target.classList.contains( 'courses-btn-load-more' ) ) {
196 return;
197 }
198 const elArchive = target.closest( `.${ classArchiveCourse }` );
199 if ( ! elArchive ) {
200 return;
201 }
202 const elListCourse = elArchive.querySelector( `.${ classListCourse }` );
203 if ( ! elListCourse ) {
204 return;
205 }
206
207 e.preventDefault();
208 ++filterCourses.paged;
209 typeEventBeforeFetch = 'load-more';
210 window.lpCourseList.triggerFetchAPI( filterCourses );
211 },
212 scrollInfinite: ( e, target ) => {
213 const elArchive = document.querySelector( `.${ classArchiveCourse }` );
214 if ( ! elArchive ) {
215 return;
216 }
217 const elInfinite = elArchive.querySelector( '.courses-load-infinite' );
218 if ( ! elInfinite ) {
219 return;
220 }
221
222 // Create an IntersectionObserver object.
223 const observer = new IntersectionObserver( function( entries ) {
224 for ( const entry of entries ) {
225 // If the entry is intersecting, load the image.
226 if ( entry.isIntersecting ) {
227 if ( isLoadingInfinite ) {
228 return;
229 }
230
231 ++filterCourses.paged;
232 typeEventBeforeFetch = 'infinite';
233 window.lpCourseList.triggerFetchAPI( filterCourses );
234
235 //observer.unobserve( entry.target );
236 }
237 }
238 } );
239
240 observer.observe( elInfinite );
241 },
242 triggerFetchAPI: ( args ) => { // For case, click on pagination, filter.
243 const elArchive = document.querySelector( `.${ classArchiveCourse }` );
244 if ( ! elArchive ) {
245 return;
246 }
247 const elListCourse = elArchive.querySelector( `.${ classListCourse }` );
248 if ( ! elListCourse ) {
249 return;
250 }
251
252 filterCourses = args;
253 let callBack;
254 switch ( typeEventBeforeFetch ) {
255 case 'load-more':
256 callBack = window.lpCourseList.callBackPaginationTypeLoadMore( elArchive, elListCourse );
257 break;
258 case 'infinite':
259 callBack = window.lpCourseList.callBackPaginationTypeInfinite( elArchive, elListCourse );
260 break;
261 case 'custom':
262 callBack = args.customCallBack || false;
263 break;
264 case 'filter':
265 default: // number
266 // Change url by params filter courses
267 //callBack = window.lpCourseList.callBackPaginationTypeNumber( elListCourse );
268 callBack = window.lpCourseList.callBackFilter( args, elArchive, elListCourse );
269 break;
270 }
271
272 if ( ! callBack ) {
273 return;
274 }
275
276 //console.log( 'Args', args );
277
278 fetchAPI( args, callBack );
279 },
280 callBackFilter: ( args, elArchive, elListCourse ) => {
281 if ( ! elListCourse ) {
282 return;
283 }
284 const skeleton = elListCourse.querySelector( `.${ classSkeletonArchiveCourse }` );
285
286 return {
287 before: () => {
288 window.history.pushState( '', '', lpAddQueryArgs( currentUrl, args ) );
289 window.localStorage.setItem( 'lp_filter_courses', JSON.stringify( args ) );
290 if ( skeleton ) {
291 skeleton.style.display = 'block';
292 }
293 },
294 success: ( res ) => {
295 // Remove all items before insert new items.
296 const elLis = elListCourse.querySelectorAll( `:not(.${ classSkeletonArchiveCourse })` );
297 elLis.forEach( ( elLi ) => {
298 const parent = elLi.closest( `.${ classSkeletonArchiveCourse }` );
299 if ( parent ) {
300 return;
301 }
302 elLi.remove();
303 } );
304
305 // Insert new items.
306 elListCourse.insertAdjacentHTML( 'afterbegin', res.data.content || '' );
307
308 // Check if Pagination exists will remove.
309 const elPagination = document.querySelector( `.${ classPaginationCourse }` );
310 if ( elPagination ) {
311 elPagination.remove();
312 }
313
314 // Insert Pagination.
315 const pagination = res.data.pagination || '';
316 elListCourse.insertAdjacentHTML( 'afterend', pagination );
317
318 // Set showing results page.
319 const elCoursesPageResult = document.querySelector( `.${ classCoursesPageResult }` );
320 if ( elCoursesPageResult ) {
321 elCoursesPageResult.innerHTML = res.data.from_to || '';
322 }
323 },
324 error: ( error ) => {
325 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${ error.message || 'Error' }</div>`;
326 },
327 completed: () => {
328 if ( skeleton ) {
329 skeleton.style.display = 'none';
330 }
331 // Scroll to archive element
332 const optionScroll = { behavior: 'smooth' };
333 elListCourse.closest( `.${ classArchiveCourse }` ).scrollIntoView( optionScroll );
334 },
335 };
336 },
337 /*callBackPaginationTypeNumber: ( elListCourse ) => {
338 if ( ! elListCourse ) {
339 return;
340 }
341 const skeleton = elListCourse.querySelector( `.${ classSkeletonArchiveCourse }` );
342
343 return {
344 before: () => {
345 const urlPush = lpAddQueryArgs( currentUrl, args );
346 window.history.pushState( '', '', urlPush );
347 // Save filter courses to Storage
348 window.localStorage.setItem( 'lp_filter_courses', JSON.stringify( args ) );
349 if ( skeleton ) {
350 skeleton.style.display = 'block';
351 }
352 },
353 success: ( res ) => {
354 // Remove all items before insert new items.
355 const elLis = elListCourse.querySelectorAll( `:not(.${ classSkeletonArchiveCourse })` );
356 elLis.forEach( ( elLi ) => {
357 const parent = elLi.closest( `.${ classSkeletonArchiveCourse }` );
358 if ( parent ) {
359 return;
360 }
361 elLi.remove();
362 } );
363
364 // Insert new items.
365 elListCourse.insertAdjacentHTML( 'afterbegin', res.data.content || '' );
366
367 // Check if Pagination exists will remove.
368 const elPagination = document.querySelector( `.${ classPaginationCourse }` );
369 if ( elPagination ) {
370 elPagination.remove();
371 }
372
373 // Insert Pagination.
374 const pagination = res.data.pagination || '';
375 elListCourse.insertAdjacentHTML( 'afterend', pagination );
376 },
377 error: ( error ) => {
378 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${ error.message || 'Error' }</div>`;
379 },
380 completed: () => {
381 if ( skeleton ) {
382 skeleton.style.display = 'none';
383 }
384
385 // Scroll to archive element
386 const optionScroll = { behavior: 'smooth' };
387 elListCourse.closest( '.lp-archive-courses' ).scrollIntoView( optionScroll );
388 },
389 };
390 },*/
391 callBackPaginationTypeLoadMore: ( elArchive, elListCourse ) => {
392 //console.log( 'callBackPaginationTypeLoadMore' );
393 if ( ! elListCourse || ! elArchive ) {
394 return false;
395 }
396 const btnLoadMore = elArchive.querySelector( '.courses-btn-load-more' );
397 let elLoading;
398 if ( btnLoadMore ) {
399 elLoading = btnLoadMore.querySelector( '.lp-loading-circle' );
400 }
401 //const skeleton = document.querySelector( `.${ classSkeletonArchiveCourse }` );
402
403 return {
404 before: () => {
405 if ( btnLoadMore ) {
406 elLoading.classList.remove( 'hide' );
407 btnLoadMore.setAttribute( 'disabled', 'disabled' );
408 }
409
410 /*if ( skeleton ) {
411 skeleton.style.display = 'block';
412 }*/
413 },
414 success: ( res ) => {
415 elListCourse.insertAdjacentHTML( 'beforeend', res.data.content || '' );
416 elListCourse.insertAdjacentHTML( 'afterend', res.data.pagination || '' );
417
418 // Set showing results page.
419 const elCoursesPageResult = document.querySelector( `.${ classCoursesPageResult }` );
420 if ( elCoursesPageResult ) {
421 elCoursesPageResult.innerHTML = res.data.from_to || '';
422 }
423 },
424 error: ( error ) => {
425 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${ error.message || 'Error' }</div>`;
426 },
427 completed: () => {
428 if ( btnLoadMore ) {
429 elLoading.classList.add( 'hide' );
430 btnLoadMore.remove();
431 }
432
433 /*if ( skeleton ) {
434 skeleton.style.display = 'none';
435 }*/
436 },
437 };
438 },
439 callBackPaginationTypeInfinite: ( elArchive, elListCourse ) => {
440 //console.log( 'callBackPaginationTypeInfinite' );
441 if ( ! elListCourse || ! elListCourse ) {
442 return;
443 }
444
445 const elInfinite = elArchive.querySelector( '.courses-load-infinite' );
446 if ( ! elInfinite ) {
447 return;
448 }
449 const loading = elInfinite.querySelector( '.lp-loading-circle' );
450
451 isLoadingInfinite = true;
452
453 elInfinite.classList.remove( 'courses-load-infinite' );
454
455 return {
456 before: () => {
457 loading.classList.remove( 'hide' );
458 },
459 success: ( res ) => {
460 elListCourse.insertAdjacentHTML( 'beforeend', res.data.content || '' );
461
462 if ( res.data.pagination ) {
463 elListCourse.insertAdjacentHTML( 'afterend', res.data.pagination || '' );
464 }
465
466 // Set showing results page.
467 const elCoursesPageResult = document.querySelector( `.${ classCoursesPageResult }` );
468 if ( elCoursesPageResult ) {
469 elCoursesPageResult.innerHTML = res.data.from_to || '';
470 }
471 },
472 error: ( error ) => {
473 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${ error.message || 'Error' }</div>`;
474 },
475 completed: () => {
476 elInfinite.remove();
477 isLoadingInfinite = false;
478 },
479 };
480 },
481 searchCourse: ( e, target ) => {
482 if ( 'c_search' === target.name ) {
483 e.preventDefault();
484
485 const parentFormSearch = target.closest( 'form.search-courses' );
486 if ( ! parentFormSearch ) {
487 return;
488 }
489
490 const btnSearch = parentFormSearch.querySelector( 'button[type="submit"]' );
491 btnSearch.click();
492 return;
493 }
494
495 if ( ! target.classList.contains( 'search-courses' ) ) {
496 return;
497 }
498 const formSearchCourses = target;
499 e.preventDefault();
500 const elArchive = formSearchCourses.closest( `.${ classArchiveCourse }` );
501 if ( ! elArchive ) {
502 return;
503 }
504 const elListCourse = elArchive.querySelector( `.${ classListCourse }` );
505 if ( ! elListCourse ) {
506 return;
507 }
508
509 const elInputSearch = formSearchCourses.querySelector( 'input[name=c_search]' );
510 const keyword = elInputSearch.value;
511
512 if ( ! keyword || ( keyword && keyword.length > 2 ) ) {
513 if ( undefined !== timeOutSearch ) {
514 clearTimeout( timeOutSearch );
515 }
516
517 timeOutSearch = setTimeout( function() {
518 typeEventBeforeFetch = 'filter';
519 filterCourses.c_search = keyword;
520 filterCourses.paged = 1;
521
522 window.lpCourseList.triggerFetchAPI( filterCourses );
523 }, 800 );
524 }
525 },
526 ajaxEnableLoadPage: () => { // For case enable AJAX when load page.
527 let countTime = 0;
528 if ( ! lpArchiveNoLoadAjaxFirst ) {
529 let detectedElArchive;
530 const callBack = {
531 success: ( res ) => {
532 detectedElArchive = setInterval( function() {
533 const skeleton = document.querySelector( `.${ classSkeletonArchiveCourse }` );
534 const elArchive = document.querySelector( `.${ classArchiveCourse }` );
535 let elListCourse;
536 if ( elArchive ) {
537 elListCourse = elArchive.querySelector( `.${ classListCourse }` );
538 }
539
540 ++countTime;
541 if ( countTime > 5000 ) {
542 clearInterval( detectedElArchive );
543 }
544
545 if ( elListCourse && skeleton ) {
546 clearInterval( detectedElArchive );
547 elListCourse.insertAdjacentHTML( 'afterbegin', res.data.content || '' );
548 skeleton.style.display = 'none';
549
550 const pagination = res.data.pagination || '';
551 elListCourse.insertAdjacentHTML( 'afterend', pagination );
552
553 // Set showing results page.
554 const elCoursesPageResult = document.querySelector( `.${ classCoursesPageResult }` );
555 if ( elCoursesPageResult ) {
556 elCoursesPageResult.innerHTML = res.data.from_to || '';
557 }
558 }
559 }, 1 );
560 },
561 };
562
563 if ( 'number' !== typePagination ) {
564 filterCourses.paged = 1;
565 }
566 fetchAPI( filterCourses, callBack );
567 }
568 },
569 getFilterParams: () => {
570 return filterCourses;
571 },
572 // Check has exists new list courses.
573 checkIsNewListCourses: () => {
574 const elListCoursesNew = document.querySelector( elListCoursesIdNewDefault );
575 return !! elListCoursesNew;
576 },
577 };
578 } )();
579
580 document.addEventListener( 'DOMContentLoaded', function() {
581 if ( window.lpCourseList.checkIsNewListCourses() ) {
582 return;
583 }
584
585 window.lpCourseList.init();
586 window.lpCourseList.ajaxEnableLoadPage();
587 } );
588