PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 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 All 139 releases
← All changes | assets/src/js/frontend/courses.js +587 -587 4.3.84.4.8 View file →
@@ -1,587 +1,587 @@
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 -} );
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 +} );