PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.5
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.5
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.5, at assets/js/dist/frontend/courses-v2.js

949 lines 29.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 */ 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 /******/ const __webpack_module_cache__ = {};
560 /******/
561 /******/ // The require function
562 /******/ function __webpack_require__(moduleId) {
563 /******/ // Check if module is in cache
564 /******/ const 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 /******/ const 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 /******/ const 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/value functions for harmony exports
592 /******/ __webpack_require__.d = (exports, definition) => {
593 /******/ if(Array.isArray(definition)) {
594 /******/ var i = 0;
595 /******/ while(i < definition.length) {
596 /******/ var key = definition[i++];
597 /******/ var binding = definition[i++];
598 /******/ if(!__webpack_require__.o(exports, key)) {
599 /******/ if(binding === 0) {
600 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
601 /******/ } else {
602 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
603 /******/ }
604 /******/ } else if(binding === 0) { i++; }
605 /******/ }
606 /******/ } else {
607 /******/ for(var key in definition) {
608 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
609 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
610 /******/ }
611 /******/ }
612 /******/ }
613 /******/ };
614 /******/ })();
615 /******/
616 /******/ /* webpack/runtime/hasOwnProperty shorthand */
617 /******/ (() => {
618 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
619 /******/ })();
620 /******/
621 /******/ /* webpack/runtime/make namespace object */
622 /******/ (() => {
623 /******/ // define __esModule on exports
624 /******/ __webpack_require__.r = (exports) => {
625 /******/ if(Symbol.toStringTag) {
626 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
627 /******/ }
628 /******/ Object.defineProperty(exports, '__esModule', { value: true });
629 /******/ };
630 /******/ })();
631 /******/
632 /************************************************************************/
633 let __webpack_exports__ = {};
634 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
635 (() => {
636 /*!**********************************************!*\
637 !*** ./assets/src/js/frontend/courses-v2.js ***!
638 \**********************************************/
639 __webpack_require__.r(__webpack_exports__);
640 /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../api */ "./assets/src/js/api.js");
641 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
642 /**
643 * Handle events for courses list.
644 *
645 * @since 4.2.5.8
646 * @version 1.0.1
647 */
648
649
650
651 if ('undefined' === typeof lpData) {
652 console.log('lpData is undefined');
653 }
654
655 // Events
656 document.addEventListener('change', function (e) {
657 const target = e.target;
658 window.lpCoursesList.onChangeSortBy(e, target);
659 window.lpCoursesList.onChangeTypeLayout(e, target);
660 });
661 document.addEventListener('click', function (e) {
662 const target = e.target;
663 window.lpCoursesList.LoadMore(e, target);
664 });
665 document.addEventListener('keyup', function (e) {
666 const target = e.target;
667 window.lpCoursesList.searchCourse(e, target);
668 });
669 document.addEventListener('submit', function (e) {
670 const target = e.target;
671
672 //window.lpCourseList.searchCourse( e, target );
673 });
674 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpOnElementReady)('.course-filter-btn-mobile', function (el) {
675 const widgetCourseFilter = document.querySelector('.widget_course_filter');
676 if (!widgetCourseFilter) {
677 el.remove();
678 }
679 });
680 let timeOutSearch;
681 window.lpCoursesList = (() => {
682 const classListCourse = '.lp-list-courses-no-css';
683 const classLPTarget = '.lp-target';
684 const classLoadMore = 'courses-btn-load-more-no-css';
685 const classPageResult = '.courses-page-result';
686 const classLoading = '.lp-loading-no-css';
687 const urlCurrent = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpGetCurrentURLNoParam)();
688 return {
689 LoadMore: (e, target) => {
690 const btnLoadMore = target.closest(`.${classLoadMore + ':not(.disabled)'}`);
691 if (!btnLoadMore) {
692 return;
693 }
694 const elLPTarget = btnLoadMore.closest(`${classLPTarget}`);
695 if (!elLPTarget) {
696 return;
697 }
698 e.preventDefault();
699 btnLoadMore.classList.add('disabled');
700 const elLoading = btnLoadMore.querySelector(classLoading);
701 const dataObj = JSON.parse(elLPTarget.dataset.send);
702 const dataSend = {
703 ...dataObj
704 };
705 if (!dataSend.args.hasOwnProperty('paged')) {
706 dataSend.args.paged = 1;
707 }
708 dataSend.args.paged++;
709 elLPTarget.dataset.send = JSON.stringify(dataSend);
710 if (elLoading) {
711 elLoading.classList.remove('hide');
712 }
713 const callBack = {
714 success: response => {
715 const {
716 status,
717 message,
718 data
719 } = response;
720 const paged = parseInt(data.paged);
721 const totalPages = parseInt(data.total_pages);
722 const newEl = document.createElement('div');
723 newEl.innerHTML = data.content || '';
724 const elListCourse = elLPTarget.querySelector(classListCourse);
725 const elPageResult = elLPTarget.querySelector(classPageResult);
726 const elPageResultNew = newEl.querySelector(classPageResult);
727 elListCourse.insertAdjacentHTML('beforeend', newEl.querySelector(classListCourse).innerHTML);
728 if (elPageResult && elPageResultNew) {
729 elPageResult.innerHTML = elPageResultNew.innerHTML;
730 }
731 if (paged >= totalPages) {
732 btnLoadMore.remove();
733 }
734 },
735 error: error => {
736 console.log(error);
737 },
738 completed: () => {
739 //console.log( 'completed' );
740 if (elLoading) {
741 elLoading.classList.add('hide');
742 }
743 btnLoadMore.classList.remove('disabled');
744 }
745 };
746 window.lpAJAXG.fetchAJAX(dataSend, callBack);
747 },
748 LoadInfinite: () => {
749 // When see element, will call API to load more items.
750 const callBackAfterSeeItem = entry => {
751 const elInfinite = entry.target;
752 const elLoading = elInfinite.querySelector(`${classLoading}:not(.disabled)`);
753 if (!elLoading) {
754 return;
755 }
756 elLoading.classList.remove('hide');
757 elLoading.classList.add('disabled');
758 const elLPTarget = elInfinite.closest(classLPTarget);
759 if (!elLPTarget) {
760 return;
761 }
762 const dataObj = JSON.parse(elLPTarget.dataset.send);
763 const dataSend = {
764 ...dataObj
765 }; // Clone object
766
767 if (!dataSend.args.hasOwnProperty('paged')) {
768 dataSend.args.paged = 1;
769 }
770
771 // Handle set data send to call API
772 dataSend.args.paged++;
773 elLPTarget.dataset.send = JSON.stringify(dataSend);
774 const callBack = {
775 success: response => {
776 const {
777 status,
778 message,
779 data
780 } = response;
781 const newEl = document.createElement('div');
782 newEl.innerHTML = data.content || '';
783 const elListCourse = elLPTarget.querySelector(classListCourse);
784 const elPageResult = elLPTarget.querySelector(classPageResult);
785 const elPageResultNew = newEl.querySelector(classPageResult);
786 elListCourse.insertAdjacentHTML('beforeend', newEl.querySelector(classListCourse).innerHTML);
787 if (elPageResult && elPageResultNew) {
788 elPageResult.innerHTML = elPageResultNew.innerHTML;
789 }
790 if (data.total_pages === data.paged) {
791 elInfinite.remove();
792 }
793 },
794 error: error => {
795 console.log(error);
796 },
797 completed: () => {
798 //console.log( 'completed' );
799 elLoading.classList.add('hide');
800 elLoading.classList.remove('disabled');
801 }
802 };
803 window.lpAJAXG.fetchAJAX(dataSend, callBack);
804 };
805
806 // Listen el courses load infinite have just created.
807 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementCreated)(node => {
808 if (node.classList.contains('courses-load-infinite-no-css')) {
809 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(node, callBackAfterSeeItem);
810 } else if (node.classList.contains('wp-block-learnpress-list-courses')) {
811 // For block Gutenberg
812 const elInfinite = node.querySelector('.courses-load-infinite-no-css');
813 if (elInfinite) {
814 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(elInfinite, callBackAfterSeeItem);
815 }
816 }
817 });
818
819 // If el created on DOMContentLoaded.
820 const elInfinite = document.querySelector('.courses-load-infinite-no-css');
821 if (elInfinite) {
822 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.listenElementViewed)(elInfinite, callBackAfterSeeItem);
823 }
824 },
825 onChangeSortBy: (e, target) => {
826 if (!target.classList.contains('courses-order-by')) {
827 return;
828 }
829 const elLPTarget = target.closest(classLPTarget);
830 if (!elLPTarget) {
831 lpData.urlParams.paged = 1;
832 lpData.urlParams.order_by = target.value || '';
833 window.location.href = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(urlCurrent, lpData.urlParams);
834 return;
835 }
836 e.preventDefault();
837 const dataObj = JSON.parse(elLPTarget.dataset.send);
838 const dataSend = {
839 ...dataObj
840 };
841 dataSend.args.paged = 1;
842 dataSend.args.order_by = target.value || '';
843 elLPTarget.dataset.send = JSON.stringify(dataSend);
844
845 // Set url params to reload page.
846 // Todo: need check allow set url params.
847 lpData.urlParams.paged = dataSend.args.paged;
848 lpData.urlParams.order_by = dataSend.args.order_by;
849 window.history.pushState({}, '', (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)(urlCurrent, lpData.urlParams));
850 // End.
851
852 // Show loading
853 window.lpAJAXG.showHideLoading(elLPTarget, 1);
854 // End
855
856 const callBack = {
857 success: response => {
858 //console.log( 'response', response );
859 const {
860 status,
861 message,
862 data
863 } = response;
864 elLPTarget.innerHTML = data.content || '';
865 },
866 error: error => {
867 console.log(error);
868 },
869 completed: () => {
870 //console.log( 'completed' );
871 window.lpAJAXG.showHideLoading(elLPTarget, 0);
872 }
873 };
874 window.lpAJAXG.fetchAJAX(dataSend, callBack);
875 },
876 onChangeTypeLayout: (e, target) => {
877 if ('lp-switch-layout-btn' !== target.getAttribute('name')) {
878 return;
879 }
880 const elListCourse = document.querySelector(classListCourse);
881 if (!elListCourse) {
882 return;
883 }
884 e.preventDefault();
885 const layout = target.value;
886 if (layout) {
887 elListCourse.dataset.layout = layout;
888 window.wpCookies.set('courses-layout', layout, 24 * 60 * 60, '/');
889 }
890 },
891 searchCourse: (e, target) => {
892 if ('c_search' !== target.name) {
893 return;
894 }
895 const elLPTarget = target.closest(classLPTarget);
896 if (!elLPTarget) {
897 return;
898 }
899 e.preventDefault();
900 const dataObj = JSON.parse(elLPTarget.dataset.send);
901 const dataSend = {
902 ...dataObj
903 };
904 const keyword = target.value;
905 dataSend.args.c_search = keyword || '';
906 dataSend.args.paged = 1;
907 elLPTarget.dataset.send = JSON.stringify(dataSend);
908
909 // Set url params to reload page.
910 // Todo: need check allow set url params.
911 lpData.urlParams.paged = dataSend.args.paged;
912 lpData.urlParams.c_search = dataSend.args.c_search;
913 window.history.pushState({}, '', (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpAddQueryArgs)((0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpGetCurrentURLNoParam)(), lpData.urlParams));
914 // End.
915
916 if (!keyword || keyword && keyword.length > 2) {
917 if (undefined !== timeOutSearch) {
918 clearTimeout(timeOutSearch);
919 }
920 timeOutSearch = setTimeout(function () {
921 const callBack = {
922 success: response => {
923 //console.log( 'response', response );
924 const {
925 status,
926 message,
927 data
928 } = response;
929 elLPTarget.innerHTML = data.content || '';
930 },
931 error: error => {
932 console.log(error);
933 },
934 completed: () => {
935 //console.log( 'completed' );
936 }
937 };
938 window.lpAJAXG.fetchAJAX(dataSend, callBack);
939 }, 800);
940 }
941 }
942 };
943 })();
944 window.lpCoursesList.LoadInfinite();
945 })();
946
947 /******/ })()
948 ;
949 //# sourceMappingURL=courses-v2.js.map