PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9.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-v2.js

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

946 lines 29.5 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 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
29 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
30 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
31 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
32 };
33 }
34 if ('undefined' !== typeof lpData) {
35 lp_rest_url = lpData.lp_rest_url;
36 lplistAPI.frontend = {
37 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
38 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
39 // Deprecated API, don't load from v4.3.7
40 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
41 // Deprecated since 4.3.0
42 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
43 };
44 }
45 if (lp_rest_url) {
46 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
47 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
48 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
49 }
50 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
51
52 /***/ },
53
54 /***/ "./assets/src/js/utils.js"
55 /*!********************************!*\
56 !*** ./assets/src/js/utils.js ***!
57 \********************************/
58 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
59
60 __webpack_require__.r(__webpack_exports__);
61 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
62 /* harmony export */ debounce: () => (/* binding */ debounce),
63 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
64 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
65 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
66 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
67 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
68 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
69 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
70 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
71 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
72 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
73 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
74 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
75 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
76 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
77 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
78 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
79 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
80 /* harmony export */ });
81 /**
82 * Utils functions
83 *
84 * @param url
85 * @param data
86 * @param functions
87 * @since 4.2.5.1
88 * @version 1.0.7
89 */
90 const lpClassName = {
91 hidden: 'lp-hidden',
92 loading: 'loading',
93 elCollapse: 'lp-collapse',
94 elSectionToggle: '.lp-section-toggle',
95 elTriggerToggle: '.lp-trigger-toggle',
96 elBtnFullScreen: '.lp-btn-full-screen-view',
97 elFullScreen: 'lp-full-screen-view',
98 elBtnFullScreenClose: 'lp-full-screen-view__close'
99 };
100 const lpFetchAPI = (url, data = {}, functions = {}) => {
101 if ('function' === typeof functions.before) {
102 functions.before();
103 }
104 fetch(url, {
105 method: 'GET',
106 ...data
107 }).then(response => response.json()).then(response => {
108 if ('function' === typeof functions.success) {
109 functions.success(response);
110 }
111 }).catch(err => {
112 if ('function' === typeof functions.error) {
113 functions.error(err);
114 }
115 }).finally(() => {
116 if ('function' === typeof functions.completed) {
117 functions.completed();
118 }
119 });
120 };
121
122 /**
123 * Get current URL without params.
124 *
125 * @since 4.2.5.1
126 */
127 const lpGetCurrentURLNoParam = () => {
128 let currentUrl = window.location.href;
129 const hasParams = currentUrl.includes('?');
130 if (hasParams) {
131 currentUrl = currentUrl.split('?')[0];
132 }
133 return currentUrl;
134 };
135 const lpAddQueryArgs = (endpoint, args) => {
136 const url = new URL(endpoint);
137 Object.keys(args).forEach(arg => {
138 url.searchParams.set(arg, args[arg]);
139 });
140 return url;
141 };
142
143 /**
144 * Listen element viewed.
145 *
146 * @param el
147 * @param callback
148 * @since 4.2.5.8
149 */
150 const listenElementViewed = (el, callback) => {
151 const observerSeeItem = new IntersectionObserver(function (entries) {
152 for (const entry of entries) {
153 if (entry.isIntersecting) {
154 callback(entry);
155 }
156 }
157 });
158 observerSeeItem.observe(el);
159 };
160
161 /**
162 * Listen element created.
163 *
164 * @param callback
165 * @since 4.2.5.8
166 */
167 const listenElementCreated = callback => {
168 const observerCreateItem = new MutationObserver(function (mutations) {
169 mutations.forEach(function (mutation) {
170 if (mutation.addedNodes) {
171 mutation.addedNodes.forEach(function (node) {
172 if (node.nodeType === 1) {
173 callback(node);
174 }
175 });
176 }
177 });
178 });
179 observerCreateItem.observe(document, {
180 childList: true,
181 subtree: true
182 });
183 // End.
184 };
185
186 /**
187 * Listen element created.
188 *
189 * @param selector
190 * @param callback
191 * @since 4.2.7.1
192 */
193 const lpOnElementReady = (selector, callback) => {
194 const element = document.querySelector(selector);
195 if (element) {
196 callback(element);
197 return;
198 }
199 const observer = new MutationObserver((mutations, obs) => {
200 const element = document.querySelector(selector);
201 if (element) {
202 obs.disconnect();
203 callback(element);
204 }
205 });
206 observer.observe(document.documentElement, {
207 childList: true,
208 subtree: true
209 });
210 };
211
212 // Parse JSON from string with content include LP_AJAX_START.
213 const lpAjaxParseJsonOld = data => {
214 if (typeof data !== 'string') {
215 return data;
216 }
217 const m = String.raw({
218 raw: data
219 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
220 try {
221 if (m) {
222 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
223 } else {
224 data = JSON.parse(data);
225 }
226 } catch (e) {
227 data = {};
228 }
229 return data;
230 };
231
232 // status 0: hide, 1: show
233 const lpShowHideEl = (el, status = 0) => {
234 if (!el) {
235 return;
236 }
237 if (!status) {
238 el.classList.add(lpClassName.hidden);
239 } else {
240 el.classList.remove(lpClassName.hidden);
241 }
242 };
243
244 // status 0: hide, 1: show
245 const lpSetLoadingEl = (el, status) => {
246 if (!el) {
247 return;
248 }
249 if (!status) {
250 el.classList.remove(lpClassName.loading);
251 } else {
252 el.classList.add(lpClassName.loading);
253 }
254 };
255
256 // Toggle collapse section
257 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
258 if (!elTriggerClassName) {
259 elTriggerClassName = lpClassName.elTriggerToggle;
260 }
261
262 // Exclude elements, which should not trigger the collapse toggle
263 if (elsExclude && elsExclude.length > 0) {
264 for (const elExclude of elsExclude) {
265 if (target.closest(elExclude)) {
266 return;
267 }
268 }
269 }
270 const elTrigger = target.closest(elTriggerClassName);
271 if (!elTrigger) {
272 return;
273 }
274
275 //console.log( 'elTrigger', elTrigger );
276
277 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
278 if (!elSectionToggle) {
279 return;
280 }
281 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
282 if ('function' === typeof callback) {
283 callback(elSectionToggle);
284 }
285 };
286
287 // Get data of form
288 const getDataOfForm = form => {
289 const dataSend = {};
290 const formData = new FormData(form);
291 for (const pair of formData.entries()) {
292 const key = pair[0];
293 const value = formData.getAll(key);
294 if (!dataSend.hasOwnProperty(key)) {
295 // Convert value array to string.
296 dataSend[key] = value.join(',');
297 }
298 }
299 return dataSend;
300 };
301
302 // Get field keys of form
303 const getFieldKeysOfForm = form => {
304 const keys = [];
305 const elements = form.elements;
306 for (let i = 0; i < elements.length; i++) {
307 const name = elements[i].name;
308 if (name && !keys.includes(name)) {
309 keys.push(name);
310 }
311 }
312 return keys;
313 };
314
315 // Merge data handle with data form.
316 const mergeDataWithDatForm = (elForm, dataHandle) => {
317 const dataForm = getDataOfForm(elForm);
318 const keys = getFieldKeysOfForm(elForm);
319 keys.forEach(key => {
320 if (!dataForm.hasOwnProperty(key)) {
321 delete dataHandle[key];
322 } else if (dataForm[key][0] === '') {
323 delete dataForm[key];
324 delete dataHandle[key];
325 }
326 });
327 dataHandle = {
328 ...dataHandle,
329 ...dataForm
330 };
331 return dataHandle;
332 };
333
334 /**
335 * Event trigger
336 * For each list of event handlers, listen event on document.
337 *
338 * eventName: 'click', 'change', ...
339 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
340 *
341 * @param eventName
342 * @param eventHandlers
343 */
344 const eventHandlers = (eventName, eventHandlers) => {
345 document.addEventListener(eventName, e => {
346 const target = e.target;
347 let args = {
348 e,
349 target
350 };
351 eventHandlers.forEach(eventHandler => {
352 args = {
353 ...args,
354 ...eventHandler
355 };
356
357 //console.log( args );
358
359 // Check condition before call back
360 if (eventHandler.conditionBeforeCallBack) {
361 if (eventHandler.conditionBeforeCallBack(args) !== true) {
362 return;
363 }
364 }
365
366 // Special check for keydown event with checkIsEventEnter = true
367 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
368 if (e.key !== 'Enter') {
369 return;
370 }
371 }
372 if (target.closest(eventHandler.selector)) {
373 if (eventHandler.class) {
374 // Call method of class, function callBack will understand exactly {this} is class object.
375 eventHandler.class[eventHandler.callBack](args);
376 } else {
377 // For send args is objected, {this} is eventHandler object, not class object.
378 eventHandler.callBack(args);
379 }
380 }
381 });
382 });
383 };
384
385 /**
386 * Debounce - delays function execution until after `wait` ms of inactivity.
387 *
388 * Each call resets the timer. Only the last call in a burst executes.
389 *
390 * USE CASES:
391 * - Search inputs, form validation, window resize
392 * - Multiple elements need independent timers
393 * - When you need to call with different arguments
394 *
395 * EXAMPLES:
396 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
397 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
398 *
399 * const debouncedResize = debounce( recalculateLayout, 250 );
400 * window.addEventListener('resize', debouncedResize);
401 *
402 * ⚠️ Create ONCE outside event handlers, not inside.
403 *
404 * @param {Function} func - Function to debounce (can be anonymous)
405 * @param {number} wait - Milliseconds to wait (default: 500)
406 * @return {Function} Debounced wrapper function
407 * @since 4.3.7
408 * @version 1.0.0
409 */
410 const debounce = (func, wait = 500) => {
411 let timer;
412 return args => {
413 clearTimeout(timer);
414 timer = setTimeout(() => func(args), wait);
415 };
416 };
417
418 /**
419 * Initialize lp-toggle-enable components.
420 *
421 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
422 * Reads initial state from `data-enabled` attribute ("true"/"false").
423 * Calls `data-on-toggle` callback (if provided via options) on state change.
424 *
425 * HTML structure:
426 * <label class="lp-toggle-enable" data-enabled="true">
427 * <input type="checkbox" class="lp-toggle-enable__input" />
428 * <span class="lp-toggle-enable__track"></span>
429 * </label>
430 *
431 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
432 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
433 * @since 4.4.5
434 * @version 1.0.0
435 */
436 window.lpToggleEnableInit = 0;
437 const toggleEnable = (onToggle = null) => {
438 if (window.lpToggleEnableInit) {
439 return;
440 }
441 window.lpToggleEnableInit = 1;
442 const selector = '.lp-toggle-enable';
443 const updateUI = (toggle, isEnabled) => {
444 toggle.classList.toggle('is-enabled', isEnabled);
445 const input = toggle.querySelector('.lp-toggle-enable__input');
446 if (input) {
447 input.checked = isEnabled;
448 input.value = isEnabled ? '1' : '0';
449 }
450 };
451
452 // Delegate click handling via eventHandlers.
453 eventHandlers('click', [{
454 selector,
455 callBack: args => {
456 const {
457 e,
458 target
459 } = args;
460 const toggle = target.closest(selector);
461 if (!toggle || toggle.classList.contains('is-disabled')) {
462 return;
463 }
464 e.preventDefault();
465 const isEnabled = !toggle.classList.contains('is-enabled');
466 updateUI(toggle, isEnabled);
467 if ('function' === typeof onToggle) {
468 onToggle(toggle, isEnabled);
469 }
470 }
471 }]);
472 };
473
474 /**
475 * Initialize custom fullscreen view buttons.
476 *
477 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
478 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
479 * target element. Falls back to the button's parent element when
480 * `data-target` is not provided.
481 *
482 * @since 4.4.5
483 * @version 1.0.0
484 */
485 window.lpFullScreenViewInit = 0;
486 const fullScreenView = () => {
487 if (window.lpFullScreenViewInit) {
488 return;
489 }
490 window.lpFullScreenViewInit = 1;
491 let lastScrollY = 0;
492 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
493 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
494 if (isFullscreen) {
495 elTarget.classList.remove(lpClassName.elFullScreen);
496 document.documentElement.classList.remove('lp-full-screen-active');
497 window.scrollTo(0, lastScrollY);
498 } else {
499 lastScrollY = window.scrollY;
500 elTarget.classList.add(lpClassName.elFullScreen);
501 document.documentElement.classList.add('lp-full-screen-active');
502 }
503 if (!isFullscreen) {
504 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
505 const closeButton = document.createElement('button');
506 closeButton.type = 'button';
507 closeButton.className = lpClassName.elBtnFullScreenClose;
508 closeButton.setAttribute('aria-label', 'Close');
509 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
510 closeButton.addEventListener('click', e => {
511 e.preventDefault();
512 lpToggleFullscreenView(elTarget);
513 });
514 elTarget.appendChild(closeButton);
515 }
516 } else {
517 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
518 if (closeButton) {
519 closeButton.remove();
520 }
521 }
522 };
523 eventHandlers('click', [{
524 selector: lpClassName.elBtnFullScreen,
525 callBack: args => {
526 const {
527 e,
528 target
529 } = args;
530 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
531 if (!elBtnFullScreen) {
532 console.log('No full screen button found');
533 return;
534 }
535 e.preventDefault();
536 let elTarget = null;
537 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
538 console.log(targetSelector);
539 if (targetSelector) {
540 elTarget = document.querySelector(targetSelector);
541 }
542 if (!elTarget) {
543 console.log('No target element found');
544 return;
545 }
546 lpToggleFullscreenView(elTarget, elBtnFullScreen);
547 }
548 }]);
549 };
550
551 /***/ }
552
553 /******/ });
554 /************************************************************************/
555 /******/ // The module cache
556 /******/ const __webpack_module_cache__ = {};
557 /******/
558 /******/ // The require function
559 /******/ function __webpack_require__(moduleId) {
560 /******/ // Check if module is in cache
561 /******/ const cachedModule = __webpack_module_cache__[moduleId];
562 /******/ if (cachedModule !== undefined) {
563 /******/ return cachedModule.exports;
564 /******/ }
565 /******/ // Create a new module (and put it into the cache)
566 /******/ const module = __webpack_module_cache__[moduleId] = {
567 /******/ // no module.id needed
568 /******/ // no module.loaded needed
569 /******/ exports: {}
570 /******/ };
571 /******/
572 /******/ // Execute the module function
573 /******/ if (!(moduleId in __webpack_modules__)) {
574 /******/ delete __webpack_module_cache__[moduleId];
575 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
576 /******/ e.code = 'MODULE_NOT_FOUND';
577 /******/ throw e;
578 /******/ }
579 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
580 /******/
581 /******/ // Return the exports of the module
582 /******/ return module.exports;
583 /******/ }
584 /******/
585 /************************************************************************/
586 /******/ /* webpack/runtime/define property getters */
587 /******/ (() => {
588 /******/ // define getter/value functions for harmony exports
589 /******/ __webpack_require__.d = (exports, definition) => {
590 /******/ if(Array.isArray(definition)) {
591 /******/ var i = 0;
592 /******/ while(i < definition.length) {
593 /******/ var key = definition[i++];
594 /******/ var binding = definition[i++];
595 /******/ if(!__webpack_require__.o(exports, key)) {
596 /******/ if(binding === 0) {
597 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
598 /******/ } else {
599 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
600 /******/ }
601 /******/ } else if(binding === 0) { i++; }
602 /******/ }
603 /******/ } else {
604 /******/ for(var key in definition) {
605 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
606 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
607 /******/ }
608 /******/ }
609 /******/ }
610 /******/ };
611 /******/ })();
612 /******/
613 /******/ /* webpack/runtime/hasOwnProperty shorthand */
614 /******/ (() => {
615 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
616 /******/ })();
617 /******/
618 /******/ /* webpack/runtime/make namespace object */
619 /******/ (() => {
620 /******/ // define __esModule on exports
621 /******/ __webpack_require__.r = (exports) => {
622 /******/ if(Symbol.toStringTag) {
623 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
624 /******/ }
625 /******/ Object.defineProperty(exports, '__esModule', { value: true });
626 /******/ };
627 /******/ })();
628 /******/
629 /************************************************************************/
630 let __webpack_exports__ = {};
631 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
632 (() => {
633 /*!**********************************************!*\
634 !*** ./assets/src/js/frontend/courses-v2.js ***!
635 \**********************************************/
636 __webpack_require__.r(__webpack_exports__);
637 /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../api */ "./assets/src/js/api.js");
638 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
639 /**
640 * Handle events for courses list.
641 *
642 * @since 4.2.5.8
643 * @version 1.0.1
644 */
645
646
647
648 if ('undefined' === typeof lpData) {
649 console.log('lpData is undefined');
650 }
651
652 // Events
653 document.addEventListener('change', function (e) {
654 const target = e.target;
655 window.lpCoursesList.onChangeSortBy(e, target);
656 window.lpCoursesList.onChangeTypeLayout(e, target);
657 });
658 document.addEventListener('click', function (e) {
659 const target = e.target;
660 window.lpCoursesList.LoadMore(e, target);
661 });
662 document.addEventListener('keyup', function (e) {
663 const target = e.target;
664 window.lpCoursesList.searchCourse(e, target);
665 });
666 document.addEventListener('submit', function (e) {
667 const target = e.target;
668
669 //window.lpCourseList.searchCourse( e, target );
670 });
671 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpOnElementReady)('.course-filter-btn-mobile', function (el) {
672 const widgetCourseFilter = document.querySelector('.widget_course_filter');
673 if (!widgetCourseFilter) {
674 el.remove();
675 }
676 });
677 let timeOutSearch;
678 window.lpCoursesList = (() => {
679 const classListCourse = '.lp-list-courses-no-css';
680 const classLPTarget = '.lp-target';
681 const classLoadMore = 'courses-btn-load-more-no-css';
682 const classPageResult = '.courses-page-result';
683 const classLoading = '.lp-loading-no-css';
684 const urlCurrent = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpGetCurrentURLNoParam)();
685 return {
686 LoadMore: (e, target) => {
687 const btnLoadMore = target.closest(`.${classLoadMore + ':not(.disabled)'}`);
688 if (!btnLoadMore) {
689 return;
690 }
691 const elLPTarget = btnLoadMore.closest(`${classLPTarget}`);
692 if (!elLPTarget) {
693 return;
694 }
695 e.preventDefault();
696 btnLoadMore.classList.add('disabled');
697 const elLoading = btnLoadMore.querySelector(classLoading);
698 const dataObj = JSON.parse(elLPTarget.dataset.send);
699 const dataSend = {
700 ...dataObj
701 };
702 if (!dataSend.args.hasOwnProperty('paged')) {
703 dataSend.args.paged = 1;
704 }
705 dataSend.args.paged++;
706 elLPTarget.dataset.send = JSON.stringify(dataSend);
707 if (elLoading) {
708 elLoading.classList.remove('hide');
709 }
710 const callBack = {
711 success: response => {
712 const {
713 status,
714 message,
715 data
716 } = response;
717 const paged = parseInt(data.paged);
718 const totalPages = parseInt(data.total_pages);
719 const newEl = document.createElement('div');
720 newEl.innerHTML = data.content || '';
721 const elListCourse = elLPTarget.querySelector(classListCourse);
722 const elPageResult = elLPTarget.querySelector(classPageResult);
723 const elPageResultNew = newEl.querySelector(classPageResult);
724 elListCourse.insertAdjacentHTML('beforeend', newEl.querySelector(classListCourse).innerHTML);
725 if (elPageResult && elPageResultNew) {
726 elPageResult.innerHTML = elPageResultNew.innerHTML;
727 }
728 if (paged >= totalPages) {
729 btnLoadMore.remove();
730 }
731 },
732 error: error => {
733 console.log(error);
734 },
735 completed: () => {
736 //console.log( 'completed' );
737 if (elLoading) {
738 elLoading.classList.add('hide');
739 }
740 btnLoadMore.classList.remove('disabled');
741 }
742 };
743 window.lpAJAXG.fetchAJAX(dataSend, callBack);
744 },
745 LoadInfinite: () => {
746 // When see element, will call API to load more items.
747 const callBackAfterSeeItem = entry => {
748 const elInfinite = entry.target;
749 const elLoading = elInfinite.querySelector(`${classLoading}:not(.disabled)`);
750 if (!elLoading) {
751 return;
752 }
753 elLoading.classList.remove('hide');
754 elLoading.classList.add('disabled');
755 const elLPTarget = elInfinite.closest(classLPTarget);
756 if (!elLPTarget) {
757 return;
758 }
759 const dataObj = JSON.parse(elLPTarget.dataset.send);
760 const dataSend = {
761 ...dataObj
762 }; // Clone object
763
764 if (!dataSend.args.hasOwnProperty('paged')) {
765 dataSend.args.paged = 1;
766 }
767
768 // Handle set data send to call API
769 dataSend.args.paged++;
770 elLPTarget.dataset.send = JSON.stringify(dataSend);
771 const callBack = {
772 success: response => {
773 const {
774 status,
775 message,
776 data
777 } = response;
778 const newEl = document.createElement('div');
779 newEl.innerHTML = data.content || '';
780 const elListCourse = elLPTarget.querySelector(classListCourse);
781 const elPageResult = elLPTarget.querySelector(classPageResult);
782 const elPageResultNew = newEl.querySelector(classPageResult);
783 elListCourse.insertAdjacentHTML('beforeend', newEl.querySelector(classListCourse).innerHTML);
784 if (elPageResult && elPageResultNew) {
785 elPageResult.innerHTML = elPageResultNew.innerHTML;
786 }
787 if (data.total_pages === data.paged) {
788 elInfinite.remove();
789 }
790 },
791 error: error => {
792 console.log(error);
793 },
794 completed: () => {
795 //console.log( 'completed' );
796 elLoading.classList.add('hide');
797 elLoading.classList.remove('disabled');
798 }
799 };
800 window.lpAJAXG.fetchAJAX(dataSend, callBack);
801 };
802
803 // Listen el courses load infinite have just created.
804 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementCreated)(node => {
805 if (node.classList.contains('courses-load-infinite-no-css')) {
806 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(node, callBackAfterSeeItem);
807 } else if (node.classList.contains('wp-block-learnpress-list-courses')) {
808 // For block Gutenberg
809 const elInfinite = node.querySelector('.courses-load-infinite-no-css');
810 if (elInfinite) {
811 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(elInfinite, callBackAfterSeeItem);
812 }
813 }
814 });
815
816 // If el created on DOMContentLoaded.
817 const elInfinite = document.querySelector('.courses-load-infinite-no-css');
818 if (elInfinite) {
819 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(elInfinite, callBackAfterSeeItem);
820 }
821 },
822 onChangeSortBy: (e, target) => {
823 if (!target.classList.contains('courses-order-by')) {
824 return;
825 }
826 const elLPTarget = target.closest(classLPTarget);
827 if (!elLPTarget) {
828 lpData.urlParams.paged = 1;
829 lpData.urlParams.order_by = target.value || '';
830 window.location.href = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(urlCurrent, lpData.urlParams);
831 return;
832 }
833 e.preventDefault();
834 const dataObj = JSON.parse(elLPTarget.dataset.send);
835 const dataSend = {
836 ...dataObj
837 };
838 dataSend.args.paged = 1;
839 dataSend.args.order_by = target.value || '';
840 elLPTarget.dataset.send = JSON.stringify(dataSend);
841
842 // Set url params to reload page.
843 // Todo: need check allow set url params.
844 lpData.urlParams.paged = dataSend.args.paged;
845 lpData.urlParams.order_by = dataSend.args.order_by;
846 window.history.pushState({}, '', (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(urlCurrent, lpData.urlParams));
847 // End.
848
849 // Show loading
850 window.lpAJAXG.showHideLoading(elLPTarget, 1);
851 // End
852
853 const callBack = {
854 success: response => {
855 //console.log( 'response', response );
856 const {
857 status,
858 message,
859 data
860 } = response;
861 elLPTarget.innerHTML = data.content || '';
862 },
863 error: error => {
864 console.log(error);
865 },
866 completed: () => {
867 //console.log( 'completed' );
868 window.lpAJAXG.showHideLoading(elLPTarget, 0);
869 }
870 };
871 window.lpAJAXG.fetchAJAX(dataSend, callBack);
872 },
873 onChangeTypeLayout: (e, target) => {
874 if ('lp-switch-layout-btn' !== target.getAttribute('name')) {
875 return;
876 }
877 const elListCourse = document.querySelector(classListCourse);
878 if (!elListCourse) {
879 return;
880 }
881 e.preventDefault();
882 const layout = target.value;
883 if (layout) {
884 elListCourse.dataset.layout = layout;
885 window.wpCookies.set('courses-layout', layout, 24 * 60 * 60, '/');
886 }
887 },
888 searchCourse: (e, target) => {
889 if ('c_search' !== target.name) {
890 return;
891 }
892 const elLPTarget = target.closest(classLPTarget);
893 if (!elLPTarget) {
894 return;
895 }
896 e.preventDefault();
897 const dataObj = JSON.parse(elLPTarget.dataset.send);
898 const dataSend = {
899 ...dataObj
900 };
901 const keyword = target.value;
902 dataSend.args.c_search = keyword || '';
903 dataSend.args.paged = 1;
904 elLPTarget.dataset.send = JSON.stringify(dataSend);
905
906 // Set url params to reload page.
907 // Todo: need check allow set url params.
908 lpData.urlParams.paged = dataSend.args.paged;
909 lpData.urlParams.c_search = dataSend.args.c_search;
910 window.history.pushState({}, '', (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)((0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpGetCurrentURLNoParam)(), lpData.urlParams));
911 // End.
912
913 if (!keyword || keyword && keyword.length > 2) {
914 if (undefined !== timeOutSearch) {
915 clearTimeout(timeOutSearch);
916 }
917 timeOutSearch = setTimeout(function () {
918 const callBack = {
919 success: response => {
920 //console.log( 'response', response );
921 const {
922 status,
923 message,
924 data
925 } = response;
926 elLPTarget.innerHTML = data.content || '';
927 },
928 error: error => {
929 console.log(error);
930 },
931 completed: () => {
932 //console.log( 'completed' );
933 }
934 };
935 window.lpAJAXG.fetchAJAX(dataSend, callBack);
936 }, 800);
937 }
938 }
939 };
940 })();
941 window.lpCoursesList.LoadInfinite();
942 })();
943
944 /******/ })()
945 ;
946 //# sourceMappingURL=courses-v2.js.map