PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.6
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.6
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
learnpress / assets / js / dist / frontend / courses-v2.js

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

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