PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
4.4.9.1 4.4.9 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 All 141 releases
learnpress / assets / js / dist / frontend / courses.js

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

1,115 lines 35.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ "./assets/src/js/api.js"
6 /*!******************************!*\
7 !*** ./assets/src/js/api.js ***!
8 \******************************/
9 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
14 /* harmony export */ });
15 /**
16 * List API on backend
17 *
18 * @since 4.2.6
19 * @version 1.0.2
20 */
21
22 const lplistAPI = {};
23 let lp_rest_url;
24 if ('undefined' !== typeof lpDataAdmin) {
25 lp_rest_url = lpDataAdmin.lp_rest_url;
26 lplistAPI.admin = {
27 apiAdminNotice: lp_rest_url + 'lp/v1/admin/tools/admin-notices',
28 apiAddons: lp_rest_url + 'lp/v1/addon/all',
29 apiAddonAction: lp_rest_url + 'lp/v1/addon/action-n',
30 apiAddonsPurchase: lp_rest_url + 'lp/v1/addon/info-addons-purchase',
31 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
32 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
33 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
34 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
35 };
36 }
37 if ('undefined' !== typeof lpData) {
38 lp_rest_url = lpData.lp_rest_url;
39 lplistAPI.frontend = {
40 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
41 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
42 // Deprecated API, don't load from v4.3.7
43 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
44 // Deprecated since 4.3.0
45 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
46 };
47 }
48 if (lp_rest_url) {
49 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
50 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
51 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
52 }
53 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
54
55 /***/ },
56
57 /***/ "./assets/src/js/utils.js"
58 /*!********************************!*\
59 !*** ./assets/src/js/utils.js ***!
60 \********************************/
61 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
62
63 __webpack_require__.r(__webpack_exports__);
64 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
65 /* harmony export */ debounce: () => (/* binding */ debounce),
66 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
67 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
68 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
69 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
70 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
71 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
72 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
73 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
74 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
75 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
76 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
77 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
78 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
79 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
80 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
81 /* harmony export */ });
82 /**
83 * Utils functions
84 *
85 * @param url
86 * @param data
87 * @param functions
88 * @since 4.2.5.1
89 * @version 1.0.6
90 */
91 const lpClassName = {
92 hidden: 'lp-hidden',
93 loading: 'loading',
94 elCollapse: 'lp-collapse',
95 elSectionToggle: '.lp-section-toggle',
96 elTriggerToggle: '.lp-trigger-toggle'
97 };
98 const lpFetchAPI = (url, data = {}, functions = {}) => {
99 if ('function' === typeof functions.before) {
100 functions.before();
101 }
102 fetch(url, {
103 method: 'GET',
104 ...data
105 }).then(response => response.json()).then(response => {
106 if ('function' === typeof functions.success) {
107 functions.success(response);
108 }
109 }).catch(err => {
110 if ('function' === typeof functions.error) {
111 functions.error(err);
112 }
113 }).finally(() => {
114 if ('function' === typeof functions.completed) {
115 functions.completed();
116 }
117 });
118 };
119
120 /**
121 * Get current URL without params.
122 *
123 * @since 4.2.5.1
124 */
125 const lpGetCurrentURLNoParam = () => {
126 let currentUrl = window.location.href;
127 const hasParams = currentUrl.includes('?');
128 if (hasParams) {
129 currentUrl = currentUrl.split('?')[0];
130 }
131 return currentUrl;
132 };
133 const lpAddQueryArgs = (endpoint, args) => {
134 const url = new URL(endpoint);
135 Object.keys(args).forEach(arg => {
136 url.searchParams.set(arg, args[arg]);
137 });
138 return url;
139 };
140
141 /**
142 * Listen element viewed.
143 *
144 * @param el
145 * @param callback
146 * @since 4.2.5.8
147 */
148 const listenElementViewed = (el, callback) => {
149 const observerSeeItem = new IntersectionObserver(function (entries) {
150 for (const entry of entries) {
151 if (entry.isIntersecting) {
152 callback(entry);
153 }
154 }
155 });
156 observerSeeItem.observe(el);
157 };
158
159 /**
160 * Listen element created.
161 *
162 * @param callback
163 * @since 4.2.5.8
164 */
165 const listenElementCreated = callback => {
166 const observerCreateItem = new MutationObserver(function (mutations) {
167 mutations.forEach(function (mutation) {
168 if (mutation.addedNodes) {
169 mutation.addedNodes.forEach(function (node) {
170 if (node.nodeType === 1) {
171 callback(node);
172 }
173 });
174 }
175 });
176 });
177 observerCreateItem.observe(document, {
178 childList: true,
179 subtree: true
180 });
181 // End.
182 };
183
184 /**
185 * Listen element created.
186 *
187 * @param selector
188 * @param callback
189 * @since 4.2.7.1
190 */
191 const lpOnElementReady = (selector, callback) => {
192 const element = document.querySelector(selector);
193 if (element) {
194 callback(element);
195 return;
196 }
197 const observer = new MutationObserver((mutations, obs) => {
198 const element = document.querySelector(selector);
199 if (element) {
200 obs.disconnect();
201 callback(element);
202 }
203 });
204 observer.observe(document.documentElement, {
205 childList: true,
206 subtree: true
207 });
208 };
209
210 // Parse JSON from string with content include LP_AJAX_START.
211 const lpAjaxParseJsonOld = data => {
212 if (typeof data !== 'string') {
213 return data;
214 }
215 const m = String.raw({
216 raw: data
217 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
218 try {
219 if (m) {
220 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
221 } else {
222 data = JSON.parse(data);
223 }
224 } catch (e) {
225 data = {};
226 }
227 return data;
228 };
229
230 // status 0: hide, 1: show
231 const lpShowHideEl = (el, status = 0) => {
232 if (!el) {
233 return;
234 }
235 if (!status) {
236 el.classList.add(lpClassName.hidden);
237 } else {
238 el.classList.remove(lpClassName.hidden);
239 }
240 };
241
242 // status 0: hide, 1: show
243 const lpSetLoadingEl = (el, status) => {
244 if (!el) {
245 return;
246 }
247 if (!status) {
248 el.classList.remove(lpClassName.loading);
249 } else {
250 el.classList.add(lpClassName.loading);
251 }
252 };
253
254 // Toggle collapse section
255 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
256 if (!elTriggerClassName) {
257 elTriggerClassName = lpClassName.elTriggerToggle;
258 }
259
260 // Exclude elements, which should not trigger the collapse toggle
261 if (elsExclude && elsExclude.length > 0) {
262 for (const elExclude of elsExclude) {
263 if (target.closest(elExclude)) {
264 return;
265 }
266 }
267 }
268 const elTrigger = target.closest(elTriggerClassName);
269 if (!elTrigger) {
270 return;
271 }
272
273 //console.log( 'elTrigger', elTrigger );
274
275 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
276 if (!elSectionToggle) {
277 return;
278 }
279 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
280 if ('function' === typeof callback) {
281 callback(elSectionToggle);
282 }
283 };
284
285 // Get data of form
286 const getDataOfForm = form => {
287 const dataSend = {};
288 const formData = new FormData(form);
289 for (const pair of formData.entries()) {
290 const key = pair[0];
291 const value = formData.getAll(key);
292 if (!dataSend.hasOwnProperty(key)) {
293 // Convert value array to string.
294 dataSend[key] = value.join(',');
295 }
296 }
297 return dataSend;
298 };
299
300 // Get field keys of form
301 const getFieldKeysOfForm = form => {
302 const keys = [];
303 const elements = form.elements;
304 for (let i = 0; i < elements.length; i++) {
305 const name = elements[i].name;
306 if (name && !keys.includes(name)) {
307 keys.push(name);
308 }
309 }
310 return keys;
311 };
312
313 // Merge data handle with data form.
314 const mergeDataWithDatForm = (elForm, dataHandle) => {
315 const dataForm = getDataOfForm(elForm);
316 const keys = getFieldKeysOfForm(elForm);
317 keys.forEach(key => {
318 if (!dataForm.hasOwnProperty(key)) {
319 delete dataHandle[key];
320 } else if (dataForm[key][0] === '') {
321 delete dataForm[key];
322 delete dataHandle[key];
323 }
324 });
325 dataHandle = {
326 ...dataHandle,
327 ...dataForm
328 };
329 return dataHandle;
330 };
331
332 /**
333 * Event trigger
334 * For each list of event handlers, listen event on document.
335 *
336 * eventName: 'click', 'change', ...
337 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
338 *
339 * @param eventName
340 * @param eventHandlers
341 */
342 const eventHandlers = (eventName, eventHandlers) => {
343 document.addEventListener(eventName, e => {
344 const target = e.target;
345 let args = {
346 e,
347 target
348 };
349 eventHandlers.forEach(eventHandler => {
350 args = {
351 ...args,
352 ...eventHandler
353 };
354
355 //console.log( args );
356
357 // Check condition before call back
358 if (eventHandler.conditionBeforeCallBack) {
359 if (eventHandler.conditionBeforeCallBack(args) !== true) {
360 return;
361 }
362 }
363
364 // Special check for keydown event with checkIsEventEnter = true
365 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
366 if (e.key !== 'Enter') {
367 return;
368 }
369 }
370 if (target.closest(eventHandler.selector)) {
371 if (eventHandler.class) {
372 // Call method of class, function callBack will understand exactly {this} is class object.
373 eventHandler.class[eventHandler.callBack](args);
374 } else {
375 // For send args is objected, {this} is eventHandler object, not class object.
376 eventHandler.callBack(args);
377 }
378 }
379 });
380 });
381 };
382
383 /**
384 * Debounce - delays function execution until after `wait` ms of inactivity.
385 *
386 * Each call resets the timer. Only the last call in a burst executes.
387 *
388 * USE CASES:
389 * - Search inputs, form validation, window resize
390 * - Multiple elements need independent timers
391 * - When you need to call with different arguments
392 *
393 * EXAMPLES:
394 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
395 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
396 *
397 * const debouncedResize = debounce( recalculateLayout, 250 );
398 * window.addEventListener('resize', debouncedResize);
399 *
400 * ⚠️ Create ONCE outside event handlers, not inside.
401 *
402 * @param {Function} func - Function to debounce (can be anonymous)
403 * @param {number} wait - Milliseconds to wait (default: 500)
404 * @return {Function} Debounced wrapper function
405 * @since 4.3.7
406 * @version 1.0.0
407 */
408 const debounce = (func, wait = 500) => {
409 let timer;
410 return args => {
411 clearTimeout(timer);
412 timer = setTimeout(() => func(args), wait);
413 };
414 };
415
416 /***/ },
417
418 /***/ "./assets/src/js/utils/cookies.js"
419 /*!****************************************!*\
420 !*** ./assets/src/js/utils/cookies.js ***!
421 \****************************************/
422 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
423
424 __webpack_require__.r(__webpack_exports__);
425 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
426 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
427 /* harmony export */ });
428 const Cookies = {
429 get: (name, def, global) => {
430 let ret;
431 if (global) {
432 ret = wpCookies.get(name);
433 } else {
434 let ck = wpCookies.get('LP');
435 if (ck) {
436 ck = JSON.parse(ck);
437 ret = name ? ck[name] : ck;
438 }
439 }
440 if (!ret && ret !== def) {
441 ret = def;
442 }
443 return ret;
444 },
445 set(name, value, expires, path, domain, secure) {
446 if (arguments.length > 2) {
447 wpCookies.set(name, value, expires, path, domain, secure);
448 } else if (arguments.length == 2) {
449 let ck = wpCookies.get('LP');
450 if (ck) {
451 ck = JSON.parse(ck);
452 } else {
453 ck = {};
454 }
455 ck[name] = value;
456 wpCookies.set('LP', JSON.stringify(ck), '', '/');
457 } else {
458 wpCookies.set('LP', JSON.stringify(name), '', '/');
459 }
460 },
461 remove(name) {
462 const allCookies = Cookies.get();
463 const reg = new RegExp(name, 'g');
464 const newCookies = {};
465 const useRegExp = name.match(/\*/);
466 for (const i in allCookies) {
467 if (useRegExp) {
468 if (!i.match(reg)) {
469 newCookies[i] = allCookies[i];
470 }
471 } else if (name != i) {
472 newCookies[i] = allCookies[i];
473 }
474 }
475 Cookies.set(newCookies);
476 }
477 };
478 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Cookies);
479
480 /***/ }
481
482 /******/ });
483 /************************************************************************/
484 /******/ // The module cache
485 /******/ const __webpack_module_cache__ = {};
486 /******/
487 /******/ // The require function
488 /******/ function __webpack_require__(moduleId) {
489 /******/ // Check if module is in cache
490 /******/ const cachedModule = __webpack_module_cache__[moduleId];
491 /******/ if (cachedModule !== undefined) {
492 /******/ return cachedModule.exports;
493 /******/ }
494 /******/ // Create a new module (and put it into the cache)
495 /******/ const module = __webpack_module_cache__[moduleId] = {
496 /******/ // no module.id needed
497 /******/ // no module.loaded needed
498 /******/ exports: {}
499 /******/ };
500 /******/
501 /******/ // Execute the module function
502 /******/ if (!(moduleId in __webpack_modules__)) {
503 /******/ delete __webpack_module_cache__[moduleId];
504 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
505 /******/ e.code = 'MODULE_NOT_FOUND';
506 /******/ throw e;
507 /******/ }
508 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
509 /******/
510 /******/ // Return the exports of the module
511 /******/ return module.exports;
512 /******/ }
513 /******/
514 /************************************************************************/
515 /******/ /* webpack/runtime/define property getters */
516 /******/ (() => {
517 /******/ // define getter/value functions for harmony exports
518 /******/ __webpack_require__.d = (exports, definition) => {
519 /******/ if(Array.isArray(definition)) {
520 /******/ var i = 0;
521 /******/ while(i < definition.length) {
522 /******/ var key = definition[i++];
523 /******/ var binding = definition[i++];
524 /******/ if(!__webpack_require__.o(exports, key)) {
525 /******/ if(binding === 0) {
526 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
527 /******/ } else {
528 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
529 /******/ }
530 /******/ } else if(binding === 0) { i++; }
531 /******/ }
532 /******/ } else {
533 /******/ for(var key in definition) {
534 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
535 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
536 /******/ }
537 /******/ }
538 /******/ }
539 /******/ };
540 /******/ })();
541 /******/
542 /******/ /* webpack/runtime/hasOwnProperty shorthand */
543 /******/ (() => {
544 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
545 /******/ })();
546 /******/
547 /******/ /* webpack/runtime/make namespace object */
548 /******/ (() => {
549 /******/ // define __esModule on exports
550 /******/ __webpack_require__.r = (exports) => {
551 /******/ if(Symbol.toStringTag) {
552 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
553 /******/ }
554 /******/ Object.defineProperty(exports, '__esModule', { value: true });
555 /******/ };
556 /******/ })();
557 /******/
558 /************************************************************************/
559 let __webpack_exports__ = {};
560 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
561 (() => {
562 /*!*******************************************!*\
563 !*** ./assets/src/js/frontend/courses.js ***!
564 \*******************************************/
565 __webpack_require__.r(__webpack_exports__);
566 /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../api */ "./assets/src/js/api.js");
567 /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils */ "./assets/src/js/utils.js");
568 /* harmony import */ var _utils_cookies__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/cookies */ "./assets/src/js/utils/cookies.js");
569 /**
570 * @deprecated 4.2.5.8
571 * But still support for theme has html old, override.
572 * Todo: if want remove file, need to check theme override file archive, can via remove hook override file.
573 */
574
575
576
577
578 const elListCoursesIdNewDefault = '.lp-list-courses-default';
579 if ('undefined' === typeof lpData || 'undefined' === typeof lpSettingCourses) {
580 console.log('lpData || lpSettingCourses is undefined');
581 }
582
583 // Call API load courses.
584 // When LP v4.2.3.3 release a long time, we will remove this function on theme Eduma.
585 // assets/js/thim-course-filter-v2.js
586 window.lpArchiveRequestCourse = args => {
587 window.lpCourseList.updateEventTypeBeforeFetch('filter');
588 window.lpCourseList.triggerFetchAPI(args);
589 };
590
591 // Events
592 document.addEventListener('change', function (e) {
593 const target = e.target;
594 if (window.lpCourseList.checkIsNewListCourses()) {
595 return;
596 }
597 window.lpCourseList.onChangeSortBy(e, target);
598 window.lpCourseList.onChangeTypeLayout(e, target);
599 });
600 document.addEventListener('click', function (e) {
601 const target = e.target;
602 if (window.lpCourseList.checkIsNewListCourses()) {
603 return;
604 }
605 window.lpCourseList.clickLoadMore(e, target);
606 window.lpCourseList.clickNumberPage(e, target);
607 });
608 document.addEventListener('scroll', function (e) {
609 const target = e.target;
610 if (window.lpCourseList.checkIsNewListCourses()) {
611 return;
612 }
613 window.lpCourseList.scrollInfinite(e, target);
614 });
615 document.addEventListener('keyup', function (e) {
616 const target = e.target;
617 if (window.lpCourseList.checkIsNewListCourses()) {
618 return;
619 }
620 window.lpCourseList.searchCourse(e, target);
621 });
622 document.addEventListener('submit', function (e) {
623 const target = e.target;
624 if (window.lpCourseList.checkIsNewListCourses()) {
625 return;
626 }
627 window.lpCourseList.searchCourse(e, target);
628 });
629 window.lpCourseList = (() => {
630 const classArchiveCourse = 'lp-archive-courses';
631 const classListCourse = 'learn-press-courses';
632 const classPaginationCourse = 'learn-press-pagination';
633 const classSkeletonArchiveCourse = 'lp-archive-course-skeleton';
634 const classCoursesPageResult = 'courses-page-result';
635 const lpArchiveLoadAjax = parseInt(lpSettingCourses.lpArchiveLoadAjax || 0);
636 const lpArchiveNoLoadAjaxFirst = parseInt(lpSettingCourses.lpArchiveNoLoadAjaxFirst) === 1;
637 const lpArchiveSkeletonParam = lpData.urlParams || [];
638 const currentUrl = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.lpGetCurrentURLNoParam)();
639 let filterCourses = {};
640 const typePagination = lpSettingCourses.lpArchivePaginationType || 'number';
641 let typeEventBeforeFetch;
642 let timeOutSearch;
643 let isLoadingInfinite = false;
644 const fetchAPI = (args, callBack = {}) => {
645 //console.log( 'Fetch API Courses' );
646 const url = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(_api__WEBPACK_IMPORTED_MODULE_0__["default"].frontend.apiCourses, args);
647 let paramsFetch = {};
648 if (0 !== parseInt(lpData.user_id)) {
649 paramsFetch = {
650 headers: {
651 'X-WP-Nonce': lpData.nonce
652 }
653 };
654 }
655 (0,_utils__WEBPACK_IMPORTED_MODULE_1__.lpFetchAPI)(url, paramsFetch, callBack);
656 };
657 return {
658 init: () => {
659 const urlParams = {};
660 const urlQueryString = window.location.search;
661 const urlSearchParams = new URLSearchParams(urlQueryString);
662 for (const [key, val] of urlSearchParams.entries()) {
663 urlParams[key] = val;
664 }
665 filterCourses = {
666 ...lpArchiveSkeletonParam,
667 ...urlParams
668 };
669 filterCourses.paged = parseInt(filterCourses.paged || 1);
670 if (isNaN(filterCourses.paged)) {
671 filterCourses.paged = 1;
672 }
673 if (lpArchiveNoLoadAjaxFirst && typePagination !== 'number') {
674 filterCourses.paged = 1;
675 }
676 window.localStorage.setItem('lp_filter_courses', JSON.stringify(filterCourses));
677 },
678 updateEventTypeBeforeFetch: type => {
679 typeEventBeforeFetch = type;
680 },
681 onChangeSortBy: (e, target) => {
682 if (!target.classList.contains('courses-order-by')) {
683 return;
684 }
685 e.preventDefault();
686 const filterCourses = JSON.parse(window.localStorage.getItem('lp_filter_courses')) || {};
687 filterCourses.order_by = target.value || '';
688 if ('undefined' !== typeof lpSettingCourses && lpData.is_course_archive && lpSettingCourses.lpArchiveLoadAjax) {
689 window.lpCourseList.triggerFetchAPI(filterCourses);
690 } else {
691 window.location.href = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(currentUrl, filterCourses);
692 }
693 },
694 onChangeTypeLayout: (e, target) => {
695 if ('lp-switch-layout-btn' !== target.getAttribute('name')) {
696 return;
697 }
698 const elArchive = target.closest(`.${classArchiveCourse}`);
699 if (!elArchive) {
700 return;
701 }
702 const elListCourse = elArchive.querySelector(`.${classListCourse}`);
703 if (!elListCourse) {
704 return;
705 }
706 e.preventDefault();
707 const layout = target.value;
708 if (layout) {
709 elListCourse.dataset.layout = layout;
710 _utils_cookies__WEBPACK_IMPORTED_MODULE_2__["default"].set('courses-layout', layout);
711 }
712 },
713 clickNumberPage: (e, target) => {
714 if (!lpArchiveLoadAjax || parseInt(lpSettingCourses.noLoadCoursesJs)) {
715 return;
716 }
717 if (target.classList.contains('page-numbers')) {
718 const parentArchive = target.closest(`.${classArchiveCourse}`);
719 if (!parentArchive) {
720 return;
721 }
722 e.preventDefault();
723 const pageCurrent = filterCourses.paged;
724 if (target.classList.contains('prev')) {
725 filterCourses.paged = pageCurrent - 1;
726 } else if (target.classList.contains('next')) {
727 filterCourses.paged = pageCurrent + 1;
728 } else {
729 filterCourses.paged = parseInt(target.textContent);
730 }
731 typeEventBeforeFetch = 'number';
732 window.lpCourseList.triggerFetchAPI(filterCourses);
733 return;
734 }
735 const parent = target.closest('.page-numbers');
736 if (parent) {
737 e.preventDefault();
738 parent.click();
739 }
740 },
741 clickLoadMore: (e, target) => {
742 if (!target.classList.contains('courses-btn-load-more')) {
743 return;
744 }
745 const elArchive = target.closest(`.${classArchiveCourse}`);
746 if (!elArchive) {
747 return;
748 }
749 const elListCourse = elArchive.querySelector(`.${classListCourse}`);
750 if (!elListCourse) {
751 return;
752 }
753 e.preventDefault();
754 ++filterCourses.paged;
755 typeEventBeforeFetch = 'load-more';
756 window.lpCourseList.triggerFetchAPI(filterCourses);
757 },
758 scrollInfinite: (e, target) => {
759 const elArchive = document.querySelector(`.${classArchiveCourse}`);
760 if (!elArchive) {
761 return;
762 }
763 const elInfinite = elArchive.querySelector('.courses-load-infinite');
764 if (!elInfinite) {
765 return;
766 }
767
768 // Create an IntersectionObserver object.
769 const observer = new IntersectionObserver(function (entries) {
770 for (const entry of entries) {
771 // If the entry is intersecting, load the image.
772 if (entry.isIntersecting) {
773 if (isLoadingInfinite) {
774 return;
775 }
776 ++filterCourses.paged;
777 typeEventBeforeFetch = 'infinite';
778 window.lpCourseList.triggerFetchAPI(filterCourses);
779
780 //observer.unobserve( entry.target );
781 }
782 }
783 });
784 observer.observe(elInfinite);
785 },
786 triggerFetchAPI: args => {
787 // For case, click on pagination, filter.
788 const elArchive = document.querySelector(`.${classArchiveCourse}`);
789 if (!elArchive) {
790 return;
791 }
792 const elListCourse = elArchive.querySelector(`.${classListCourse}`);
793 if (!elListCourse) {
794 return;
795 }
796 filterCourses = args;
797 let callBack;
798 switch (typeEventBeforeFetch) {
799 case 'load-more':
800 callBack = window.lpCourseList.callBackPaginationTypeLoadMore(elArchive, elListCourse);
801 break;
802 case 'infinite':
803 callBack = window.lpCourseList.callBackPaginationTypeInfinite(elArchive, elListCourse);
804 break;
805 case 'custom':
806 callBack = args.customCallBack || false;
807 break;
808 case 'filter':
809 default:
810 // number
811 // Change url by params filter courses
812 //callBack = window.lpCourseList.callBackPaginationTypeNumber( elListCourse );
813 callBack = window.lpCourseList.callBackFilter(args, elArchive, elListCourse);
814 break;
815 }
816 if (!callBack) {
817 return;
818 }
819
820 //console.log( 'Args', args );
821
822 fetchAPI(args, callBack);
823 },
824 callBackFilter: (args, elArchive, elListCourse) => {
825 if (!elListCourse) {
826 return;
827 }
828 const skeleton = elListCourse.querySelector(`.${classSkeletonArchiveCourse}`);
829 return {
830 before: () => {
831 window.history.pushState('', '', (0,_utils__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(currentUrl, args));
832 window.localStorage.setItem('lp_filter_courses', JSON.stringify(args));
833 if (skeleton) {
834 skeleton.style.display = 'block';
835 }
836 },
837 success: res => {
838 // Remove all items before insert new items.
839 const elLis = elListCourse.querySelectorAll(`:not(.${classSkeletonArchiveCourse})`);
840 elLis.forEach(elLi => {
841 const parent = elLi.closest(`.${classSkeletonArchiveCourse}`);
842 if (parent) {
843 return;
844 }
845 elLi.remove();
846 });
847
848 // Insert new items.
849 elListCourse.insertAdjacentHTML('afterbegin', res.data.content || '');
850
851 // Check if Pagination exists will remove.
852 const elPagination = document.querySelector(`.${classPaginationCourse}`);
853 if (elPagination) {
854 elPagination.remove();
855 }
856
857 // Insert Pagination.
858 const pagination = res.data.pagination || '';
859 elListCourse.insertAdjacentHTML('afterend', pagination);
860
861 // Set showing results page.
862 const elCoursesPageResult = document.querySelector(`.${classCoursesPageResult}`);
863 if (elCoursesPageResult) {
864 elCoursesPageResult.innerHTML = res.data.from_to || '';
865 }
866 },
867 error: error => {
868 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${error.message || 'Error'}</div>`;
869 },
870 completed: () => {
871 if (skeleton) {
872 skeleton.style.display = 'none';
873 }
874 // Scroll to archive element
875 const optionScroll = {
876 behavior: 'smooth'
877 };
878 elListCourse.closest(`.${classArchiveCourse}`).scrollIntoView(optionScroll);
879 }
880 };
881 },
882 /*callBackPaginationTypeNumber: ( elListCourse ) => {
883 if ( ! elListCourse ) {
884 return;
885 }
886 const skeleton = elListCourse.querySelector( `.${ classSkeletonArchiveCourse }` );
887 return {
888 before: () => {
889 const urlPush = lpAddQueryArgs( currentUrl, args );
890 window.history.pushState( '', '', urlPush );
891 // Save filter courses to Storage
892 window.localStorage.setItem( 'lp_filter_courses', JSON.stringify( args ) );
893 if ( skeleton ) {
894 skeleton.style.display = 'block';
895 }
896 },
897 success: ( res ) => {
898 // Remove all items before insert new items.
899 const elLis = elListCourse.querySelectorAll( `:not(.${ classSkeletonArchiveCourse })` );
900 elLis.forEach( ( elLi ) => {
901 const parent = elLi.closest( `.${ classSkeletonArchiveCourse }` );
902 if ( parent ) {
903 return;
904 }
905 elLi.remove();
906 } );
907 // Insert new items.
908 elListCourse.insertAdjacentHTML( 'afterbegin', res.data.content || '' );
909 // Check if Pagination exists will remove.
910 const elPagination = document.querySelector( `.${ classPaginationCourse }` );
911 if ( elPagination ) {
912 elPagination.remove();
913 }
914 // Insert Pagination.
915 const pagination = res.data.pagination || '';
916 elListCourse.insertAdjacentHTML( 'afterend', pagination );
917 },
918 error: ( error ) => {
919 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${ error.message || 'Error' }</div>`;
920 },
921 completed: () => {
922 if ( skeleton ) {
923 skeleton.style.display = 'none';
924 }
925 // Scroll to archive element
926 const optionScroll = { behavior: 'smooth' };
927 elListCourse.closest( '.lp-archive-courses' ).scrollIntoView( optionScroll );
928 },
929 };
930 },*/
931 callBackPaginationTypeLoadMore: (elArchive, elListCourse) => {
932 //console.log( 'callBackPaginationTypeLoadMore' );
933 if (!elListCourse || !elArchive) {
934 return false;
935 }
936 const btnLoadMore = elArchive.querySelector('.courses-btn-load-more');
937 let elLoading;
938 if (btnLoadMore) {
939 elLoading = btnLoadMore.querySelector('.lp-loading-circle');
940 }
941 //const skeleton = document.querySelector( `.${ classSkeletonArchiveCourse }` );
942
943 return {
944 before: () => {
945 if (btnLoadMore) {
946 elLoading.classList.remove('hide');
947 btnLoadMore.setAttribute('disabled', 'disabled');
948 }
949
950 /*if ( skeleton ) {
951 skeleton.style.display = 'block';
952 }*/
953 },
954 success: res => {
955 elListCourse.insertAdjacentHTML('beforeend', res.data.content || '');
956 elListCourse.insertAdjacentHTML('afterend', res.data.pagination || '');
957
958 // Set showing results page.
959 const elCoursesPageResult = document.querySelector(`.${classCoursesPageResult}`);
960 if (elCoursesPageResult) {
961 elCoursesPageResult.innerHTML = res.data.from_to || '';
962 }
963 },
964 error: error => {
965 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${error.message || 'Error'}</div>`;
966 },
967 completed: () => {
968 if (btnLoadMore) {
969 elLoading.classList.add('hide');
970 btnLoadMore.remove();
971 }
972
973 /*if ( skeleton ) {
974 skeleton.style.display = 'none';
975 }*/
976 }
977 };
978 },
979 callBackPaginationTypeInfinite: (elArchive, elListCourse) => {
980 //console.log( 'callBackPaginationTypeInfinite' );
981 if (!elListCourse || !elListCourse) {
982 return;
983 }
984 const elInfinite = elArchive.querySelector('.courses-load-infinite');
985 if (!elInfinite) {
986 return;
987 }
988 const loading = elInfinite.querySelector('.lp-loading-circle');
989 isLoadingInfinite = true;
990 elInfinite.classList.remove('courses-load-infinite');
991 return {
992 before: () => {
993 loading.classList.remove('hide');
994 },
995 success: res => {
996 elListCourse.insertAdjacentHTML('beforeend', res.data.content || '');
997 if (res.data.pagination) {
998 elListCourse.insertAdjacentHTML('afterend', res.data.pagination || '');
999 }
1000
1001 // Set showing results page.
1002 const elCoursesPageResult = document.querySelector(`.${classCoursesPageResult}`);
1003 if (elCoursesPageResult) {
1004 elCoursesPageResult.innerHTML = res.data.from_to || '';
1005 }
1006 },
1007 error: error => {
1008 elListCourse.innerHTML += `<div class="lp-ajax-message error" style="display:block">${error.message || 'Error'}</div>`;
1009 },
1010 completed: () => {
1011 elInfinite.remove();
1012 isLoadingInfinite = false;
1013 }
1014 };
1015 },
1016 searchCourse: (e, target) => {
1017 if ('c_search' === target.name) {
1018 e.preventDefault();
1019 const parentFormSearch = target.closest('form.search-courses');
1020 if (!parentFormSearch) {
1021 return;
1022 }
1023 const btnSearch = parentFormSearch.querySelector('button[type="submit"]');
1024 btnSearch.click();
1025 return;
1026 }
1027 if (!target.classList.contains('search-courses')) {
1028 return;
1029 }
1030 const formSearchCourses = target;
1031 e.preventDefault();
1032 const elArchive = formSearchCourses.closest(`.${classArchiveCourse}`);
1033 if (!elArchive) {
1034 return;
1035 }
1036 const elListCourse = elArchive.querySelector(`.${classListCourse}`);
1037 if (!elListCourse) {
1038 return;
1039 }
1040 const elInputSearch = formSearchCourses.querySelector('input[name=c_search]');
1041 const keyword = elInputSearch.value;
1042 if (!keyword || keyword && keyword.length > 2) {
1043 if (undefined !== timeOutSearch) {
1044 clearTimeout(timeOutSearch);
1045 }
1046 timeOutSearch = setTimeout(function () {
1047 typeEventBeforeFetch = 'filter';
1048 filterCourses.c_search = keyword;
1049 filterCourses.paged = 1;
1050 window.lpCourseList.triggerFetchAPI(filterCourses);
1051 }, 800);
1052 }
1053 },
1054 ajaxEnableLoadPage: () => {
1055 // For case enable AJAX when load page.
1056 let countTime = 0;
1057 if (!lpArchiveNoLoadAjaxFirst) {
1058 let detectedElArchive;
1059 const callBack = {
1060 success: res => {
1061 detectedElArchive = setInterval(function () {
1062 const skeleton = document.querySelector(`.${classSkeletonArchiveCourse}`);
1063 const elArchive = document.querySelector(`.${classArchiveCourse}`);
1064 let elListCourse;
1065 if (elArchive) {
1066 elListCourse = elArchive.querySelector(`.${classListCourse}`);
1067 }
1068 ++countTime;
1069 if (countTime > 5000) {
1070 clearInterval(detectedElArchive);
1071 }
1072 if (elListCourse && skeleton) {
1073 clearInterval(detectedElArchive);
1074 elListCourse.insertAdjacentHTML('afterbegin', res.data.content || '');
1075 skeleton.style.display = 'none';
1076 const pagination = res.data.pagination || '';
1077 elListCourse.insertAdjacentHTML('afterend', pagination);
1078
1079 // Set showing results page.
1080 const elCoursesPageResult = document.querySelector(`.${classCoursesPageResult}`);
1081 if (elCoursesPageResult) {
1082 elCoursesPageResult.innerHTML = res.data.from_to || '';
1083 }
1084 }
1085 }, 1);
1086 }
1087 };
1088 if ('number' !== typePagination) {
1089 filterCourses.paged = 1;
1090 }
1091 fetchAPI(filterCourses, callBack);
1092 }
1093 },
1094 getFilterParams: () => {
1095 return filterCourses;
1096 },
1097 // Check has exists new list courses.
1098 checkIsNewListCourses: () => {
1099 const elListCoursesNew = document.querySelector(elListCoursesIdNewDefault);
1100 return !!elListCoursesNew;
1101 }
1102 };
1103 })();
1104 document.addEventListener('DOMContentLoaded', function () {
1105 if (window.lpCourseList.checkIsNewListCourses()) {
1106 return;
1107 }
1108 window.lpCourseList.init();
1109 window.lpCourseList.ajaxEnableLoadPage();
1110 });
1111 })();
1112
1113 /******/ })()
1114 ;
1115 //# sourceMappingURL=courses.js.map