PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.4
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 4.1.7.3.2 All 140 releases
learnpress / assets / dist / js / admin / list-students-enrolled.js

list-students-enrolled.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.4, at assets/dist/js/admin/list-students-enrolled.js

746 lines 22.6 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/utils.js"
6 /*!********************************!*\
7 !*** ./assets/src/js/utils.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 */ debounce: () => (/* binding */ debounce),
14 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
15 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
16 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
17 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
18 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
19 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
20 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
21 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
22 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
23 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
24 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
25 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
26 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
27 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
28 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
29 /* harmony export */ });
30 /**
31 * Utils functions
32 *
33 * @param url
34 * @param data
35 * @param functions
36 * @since 4.2.5.1
37 * @version 1.0.6
38 */
39 const lpClassName = {
40 hidden: 'lp-hidden',
41 loading: 'loading',
42 elCollapse: 'lp-collapse',
43 elSectionToggle: '.lp-section-toggle',
44 elTriggerToggle: '.lp-trigger-toggle'
45 };
46 const lpFetchAPI = (url, data = {}, functions = {}) => {
47 if ('function' === typeof functions.before) {
48 functions.before();
49 }
50 fetch(url, {
51 method: 'GET',
52 ...data
53 }).then(response => response.json()).then(response => {
54 if ('function' === typeof functions.success) {
55 functions.success(response);
56 }
57 }).catch(err => {
58 if ('function' === typeof functions.error) {
59 functions.error(err);
60 }
61 }).finally(() => {
62 if ('function' === typeof functions.completed) {
63 functions.completed();
64 }
65 });
66 };
67
68 /**
69 * Get current URL without params.
70 *
71 * @since 4.2.5.1
72 */
73 const lpGetCurrentURLNoParam = () => {
74 let currentUrl = window.location.href;
75 const hasParams = currentUrl.includes('?');
76 if (hasParams) {
77 currentUrl = currentUrl.split('?')[0];
78 }
79 return currentUrl;
80 };
81 const lpAddQueryArgs = (endpoint, args) => {
82 const url = new URL(endpoint);
83 Object.keys(args).forEach(arg => {
84 url.searchParams.set(arg, args[arg]);
85 });
86 return url;
87 };
88
89 /**
90 * Listen element viewed.
91 *
92 * @param el
93 * @param callback
94 * @since 4.2.5.8
95 */
96 const listenElementViewed = (el, callback) => {
97 const observerSeeItem = new IntersectionObserver(function (entries) {
98 for (const entry of entries) {
99 if (entry.isIntersecting) {
100 callback(entry);
101 }
102 }
103 });
104 observerSeeItem.observe(el);
105 };
106
107 /**
108 * Listen element created.
109 *
110 * @param callback
111 * @since 4.2.5.8
112 */
113 const listenElementCreated = callback => {
114 const observerCreateItem = new MutationObserver(function (mutations) {
115 mutations.forEach(function (mutation) {
116 if (mutation.addedNodes) {
117 mutation.addedNodes.forEach(function (node) {
118 if (node.nodeType === 1) {
119 callback(node);
120 }
121 });
122 }
123 });
124 });
125 observerCreateItem.observe(document, {
126 childList: true,
127 subtree: true
128 });
129 // End.
130 };
131
132 /**
133 * Listen element created.
134 *
135 * @param selector
136 * @param callback
137 * @since 4.2.7.1
138 */
139 const lpOnElementReady = (selector, callback) => {
140 const element = document.querySelector(selector);
141 if (element) {
142 callback(element);
143 return;
144 }
145 const observer = new MutationObserver((mutations, obs) => {
146 const element = document.querySelector(selector);
147 if (element) {
148 obs.disconnect();
149 callback(element);
150 }
151 });
152 observer.observe(document.documentElement, {
153 childList: true,
154 subtree: true
155 });
156 };
157
158 // Parse JSON from string with content include LP_AJAX_START.
159 const lpAjaxParseJsonOld = data => {
160 if (typeof data !== 'string') {
161 return data;
162 }
163 const m = String.raw({
164 raw: data
165 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
166 try {
167 if (m) {
168 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
169 } else {
170 data = JSON.parse(data);
171 }
172 } catch (e) {
173 data = {};
174 }
175 return data;
176 };
177
178 // status 0: hide, 1: show
179 const lpShowHideEl = (el, status = 0) => {
180 if (!el) {
181 return;
182 }
183 if (!status) {
184 el.classList.add(lpClassName.hidden);
185 } else {
186 el.classList.remove(lpClassName.hidden);
187 }
188 };
189
190 // status 0: hide, 1: show
191 const lpSetLoadingEl = (el, status) => {
192 if (!el) {
193 return;
194 }
195 if (!status) {
196 el.classList.remove(lpClassName.loading);
197 } else {
198 el.classList.add(lpClassName.loading);
199 }
200 };
201
202 // Toggle collapse section
203 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
204 if (!elTriggerClassName) {
205 elTriggerClassName = lpClassName.elTriggerToggle;
206 }
207
208 // Exclude elements, which should not trigger the collapse toggle
209 if (elsExclude && elsExclude.length > 0) {
210 for (const elExclude of elsExclude) {
211 if (target.closest(elExclude)) {
212 return;
213 }
214 }
215 }
216 const elTrigger = target.closest(elTriggerClassName);
217 if (!elTrigger) {
218 return;
219 }
220
221 //console.log( 'elTrigger', elTrigger );
222
223 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
224 if (!elSectionToggle) {
225 return;
226 }
227 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
228 if ('function' === typeof callback) {
229 callback(elSectionToggle);
230 }
231 };
232
233 // Get data of form
234 const getDataOfForm = form => {
235 const dataSend = {};
236 const formData = new FormData(form);
237 for (const pair of formData.entries()) {
238 const key = pair[0];
239 const value = formData.getAll(key);
240 if (!dataSend.hasOwnProperty(key)) {
241 // Convert value array to string.
242 dataSend[key] = value.join(',');
243 }
244 }
245 return dataSend;
246 };
247
248 // Get field keys of form
249 const getFieldKeysOfForm = form => {
250 const keys = [];
251 const elements = form.elements;
252 for (let i = 0; i < elements.length; i++) {
253 const name = elements[i].name;
254 if (name && !keys.includes(name)) {
255 keys.push(name);
256 }
257 }
258 return keys;
259 };
260
261 // Merge data handle with data form.
262 const mergeDataWithDatForm = (elForm, dataHandle) => {
263 const dataForm = getDataOfForm(elForm);
264 const keys = getFieldKeysOfForm(elForm);
265 keys.forEach(key => {
266 if (!dataForm.hasOwnProperty(key)) {
267 delete dataHandle[key];
268 } else if (dataForm[key][0] === '') {
269 delete dataForm[key];
270 delete dataHandle[key];
271 }
272 });
273 dataHandle = {
274 ...dataHandle,
275 ...dataForm
276 };
277 return dataHandle;
278 };
279
280 /**
281 * Event trigger
282 * For each list of event handlers, listen event on document.
283 *
284 * eventName: 'click', 'change', ...
285 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
286 *
287 * @param eventName
288 * @param eventHandlers
289 */
290 const eventHandlers = (eventName, eventHandlers) => {
291 document.addEventListener(eventName, e => {
292 const target = e.target;
293 let args = {
294 e,
295 target
296 };
297 eventHandlers.forEach(eventHandler => {
298 args = {
299 ...args,
300 ...eventHandler
301 };
302
303 //console.log( args );
304
305 // Check condition before call back
306 if (eventHandler.conditionBeforeCallBack) {
307 if (eventHandler.conditionBeforeCallBack(args) !== true) {
308 return;
309 }
310 }
311
312 // Special check for keydown event with checkIsEventEnter = true
313 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
314 if (e.key !== 'Enter') {
315 return;
316 }
317 }
318 if (target.closest(eventHandler.selector)) {
319 if (eventHandler.class) {
320 // Call method of class, function callBack will understand exactly {this} is class object.
321 eventHandler.class[eventHandler.callBack](args);
322 } else {
323 // For send args is objected, {this} is eventHandler object, not class object.
324 eventHandler.callBack(args);
325 }
326 }
327 });
328 });
329 };
330
331 /**
332 * Debounce - delays function execution until after `wait` ms of inactivity.
333 *
334 * Each call resets the timer. Only the last call in a burst executes.
335 *
336 * USE CASES:
337 * - Search inputs, form validation, window resize
338 * - Multiple elements need independent timers
339 * - When you need to call with different arguments
340 *
341 * EXAMPLES:
342 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
343 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
344 *
345 * const debouncedResize = debounce( recalculateLayout, 250 );
346 * window.addEventListener('resize', debouncedResize);
347 *
348 * ⚠️ Create ONCE outside event handlers, not inside.
349 *
350 * @param {Function} func - Function to debounce (can be anonymous)
351 * @param {number} wait - Milliseconds to wait (default: 500)
352 * @return {Function} Debounced wrapper function
353 * @since 4.3.7
354 * @version 1.0.0
355 */
356 const debounce = (func, wait = 500) => {
357 let timer;
358 return args => {
359 clearTimeout(timer);
360 timer = setTimeout(() => func(args), wait);
361 };
362 };
363
364 /***/ }
365
366 /******/ });
367 /************************************************************************/
368 /******/ // The module cache
369 /******/ const __webpack_module_cache__ = {};
370 /******/
371 /******/ // The require function
372 /******/ function __webpack_require__(moduleId) {
373 /******/ // Check if module is in cache
374 /******/ const cachedModule = __webpack_module_cache__[moduleId];
375 /******/ if (cachedModule !== undefined) {
376 /******/ return cachedModule.exports;
377 /******/ }
378 /******/ // Create a new module (and put it into the cache)
379 /******/ const module = __webpack_module_cache__[moduleId] = {
380 /******/ // no module.id needed
381 /******/ // no module.loaded needed
382 /******/ exports: {}
383 /******/ };
384 /******/
385 /******/ // Execute the module function
386 /******/ if (!(moduleId in __webpack_modules__)) {
387 /******/ delete __webpack_module_cache__[moduleId];
388 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
389 /******/ e.code = 'MODULE_NOT_FOUND';
390 /******/ throw e;
391 /******/ }
392 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
393 /******/
394 /******/ // Return the exports of the module
395 /******/ return module.exports;
396 /******/ }
397 /******/
398 /************************************************************************/
399 /******/ /* webpack/runtime/define property getters */
400 /******/ (() => {
401 /******/ // define getter/value functions for harmony exports
402 /******/ __webpack_require__.d = (exports, definition) => {
403 /******/ if(Array.isArray(definition)) {
404 /******/ var i = 0;
405 /******/ while(i < definition.length) {
406 /******/ var key = definition[i++];
407 /******/ var binding = definition[i++];
408 /******/ if(!__webpack_require__.o(exports, key)) {
409 /******/ if(binding === 0) {
410 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
411 /******/ } else {
412 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
413 /******/ }
414 /******/ } else if(binding === 0) { i++; }
415 /******/ }
416 /******/ } else {
417 /******/ for(var key in definition) {
418 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
419 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
420 /******/ }
421 /******/ }
422 /******/ }
423 /******/ };
424 /******/ })();
425 /******/
426 /******/ /* webpack/runtime/hasOwnProperty shorthand */
427 /******/ (() => {
428 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
429 /******/ })();
430 /******/
431 /******/ /* webpack/runtime/make namespace object */
432 /******/ (() => {
433 /******/ // define __esModule on exports
434 /******/ __webpack_require__.r = (exports) => {
435 /******/ if(Symbol.toStringTag) {
436 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
437 /******/ }
438 /******/ Object.defineProperty(exports, '__esModule', { value: true });
439 /******/ };
440 /******/ })();
441 /******/
442 /************************************************************************/
443 let __webpack_exports__ = {};
444 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
445 (() => {
446 /*!*******************************************************!*\
447 !*** ./assets/src/js/admin/list-students-enrolled.js ***!
448 \*******************************************************/
449 __webpack_require__.r(__webpack_exports__);
450 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
451 /* harmony export */ ListStudentsEnrolled: () => (/* binding */ ListStudentsEnrolled)
452 /* harmony export */ });
453 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
454 /**
455 * List Students Enrolled Script
456 *
457 * Handles filter and search interactions for the enrolled students table.
458 * Pagination is handled by loadAJAX.js clickNumberPage (via .page-numbers class).
459 *
460 * @since 4.3.3
461 * @version 1.0.0
462 */
463
464 class ListStudentsEnrolled {
465 constructor() {
466 this.instructorId = null;
467 this.elContainer = null;
468 this.isRequesting = false;
469 }
470 static selectors = {
471 elContainer: '#lp-enrolled-students',
472 elForm: '.lp-enrolled-students-form',
473 elLPTarget: '.lp-target',
474 elCourseNameInput: '.lp-enrolled-filter-course-name',
475 elCourseIdInput: '#lp-enrolled-filter-course-id',
476 elCourseList: '#lp-enrolled-course-list',
477 elSearchInput: '.lp-enrolled-search-input',
478 elStartDateInput: '.lp-enrolled-filter-start-date',
479 elEndDateInput: '.lp-enrolled-filter-end-date',
480 elBtnSearch: '.lp-enrolled-btn-search',
481 elBtnClear: '.lp-enrolled-btn-clear'
482 };
483 init() {
484 this.elContainer = document.querySelector(ListStudentsEnrolled.selectors.elContainer);
485 if (!this.elContainer) {
486 return;
487 }
488 const elLPTarget = this.elContainer.querySelector(ListStudentsEnrolled.selectors.elLPTarget);
489 const ajaxHandle = this.getAjaxHandle();
490 if (elLPTarget && ajaxHandle) {
491 const dataSend = ajaxHandle.getDataSetCurrent(elLPTarget);
492 if (dataSend && dataSend.args) {
493 this.instructorId = dataSend.args.instructor_id;
494 }
495 }
496 this.events();
497 }
498 events() {
499 if (ListStudentsEnrolled._loadedEvents) {
500 return;
501 }
502 ListStudentsEnrolled._loadedEvents = this;
503
504 // Search/Clear button click.
505 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
506 selector: ListStudentsEnrolled.selectors.elBtnSearch,
507 class: this,
508 callBack: this.searchStudents.name
509 }, {
510 selector: ListStudentsEnrolled.selectors.elBtnClear,
511 class: this,
512 callBack: this.clearFilters.name
513 }]);
514
515 // Search on Enter key.
516 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
517 selector: ListStudentsEnrolled.selectors.elSearchInput,
518 class: this,
519 callBack: this.triggerBtnSearch.name,
520 checkIsEventEnter: true
521 }, {
522 selector: ListStudentsEnrolled.selectors.elCourseNameInput,
523 class: this,
524 callBack: this.triggerBtnSearch.name,
525 checkIsEventEnter: true
526 }, {
527 selector: ListStudentsEnrolled.selectors.elStartDateInput,
528 class: this,
529 callBack: this.triggerBtnSearch.name,
530 checkIsEventEnter: true
531 }, {
532 selector: ListStudentsEnrolled.selectors.elEndDateInput,
533 class: this,
534 callBack: this.triggerBtnSearch.name,
535 checkIsEventEnter: true
536 }]);
537 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
538 selector: ListStudentsEnrolled.selectors.elStartDateInput,
539 class: this,
540 callBack: this.checkDatesRange.name
541 }, {
542 selector: ListStudentsEnrolled.selectors.elEndDateInput,
543 class: this,
544 callBack: this.checkDatesRange.name
545 }]);
546 }
547
548 // Click button search.
549 triggerBtnSearch() {
550 const buttonSearch = this.elContainer.querySelector(ListStudentsEnrolled.selectors.elBtnSearch);
551 if (buttonSearch) {
552 buttonSearch.click();
553 }
554 }
555
556 // Ensure start date is not after end date and vice versa. If invalid, adjust the other date to match.
557 checkDatesRange(args) {
558 const {
559 e
560 } = args;
561 const elInput = e?.target;
562 if (!elInput) {
563 return;
564 }
565 const elForm = elInput.closest(ListStudentsEnrolled.selectors.elForm);
566 if (!elForm) {
567 return;
568 }
569 const startDateInput = elForm.querySelector(ListStudentsEnrolled.selectors.elStartDateInput);
570 const endDateInput = elForm.querySelector(ListStudentsEnrolled.selectors.elEndDateInput);
571 if (elInput === startDateInput) {
572 if (startDateInput.value) {
573 endDateInput.min = startDateInput.value;
574 if (endDateInput.value && endDateInput.value < startDateInput.value) {
575 endDateInput.value = startDateInput.value;
576 }
577 } else {
578 endDateInput.min = '';
579 }
580 } else if (elInput === endDateInput) {
581 if (endDateInput.value) {
582 startDateInput.max = endDateInput.value;
583 if (startDateInput.value && startDateInput.value > endDateInput.value) {
584 startDateInput.value = endDateInput.value;
585 }
586 } else {
587 startDateInput.max = '';
588 }
589 }
590 }
591 setButtonLoadingState(btn, isLoading) {
592 if (!btn) {
593 return;
594 }
595 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(btn, isLoading ? 1 : 0);
596 btn.disabled = !!isLoading;
597 }
598 getAjaxHandle() {
599 const ajaxHandle = window.lpAJAXG;
600 if (!ajaxHandle || typeof ajaxHandle.getDataSetCurrent !== 'function' || typeof ajaxHandle.setDataSetCurrent !== 'function' || typeof ajaxHandle.showHideLoading !== 'function' || typeof ajaxHandle.fetchAJAX !== 'function') {
601 return null;
602 }
603 return ajaxHandle;
604 }
605 syncCourseIdFromName(elForm) {
606 const courseIdInput = elForm?.querySelector(ListStudentsEnrolled.selectors.elCourseIdInput);
607 if (!courseIdInput) {
608 return;
609 }
610 courseIdInput.value = '0';
611 const courseNameInput = elForm.querySelector(ListStudentsEnrolled.selectors.elCourseNameInput);
612 const datalist = elForm.querySelector(ListStudentsEnrolled.selectors.elCourseList);
613 const courseName = courseNameInput?.value.trim() || '';
614 if (!courseName || !datalist) {
615 return;
616 }
617 const selectedOption = Array.from(datalist.options || []).find(option => option.value.trim() === courseName);
618 if (selectedOption) {
619 courseIdInput.value = selectedOption.dataset.courseId || '0';
620 }
621 }
622 getFilterArgsFromForm(elForm, dataArgs = {}) {
623 this.syncCourseIdFromName(elForm);
624 return lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(elForm, dataArgs);
625 }
626
627 /**
628 * Search students: update args.search, re-fetch.
629 * @param args
630 */
631 searchStudents(args) {
632 const {
633 e
634 } = args;
635 if (e) {
636 e.preventDefault();
637 }
638 const btn = args?.target?.closest(ListStudentsEnrolled.selectors.elBtnSearch);
639 if (btn) {
640 if (this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
641 return;
642 }
643 } else if (this.isRequesting) {
644 return;
645 }
646 const elForm = btn.closest(ListStudentsEnrolled.selectors.elForm);
647 const elLPTarget = this.elContainer.querySelector(ListStudentsEnrolled.selectors.elLPTarget);
648 if (!elLPTarget || !elForm) {
649 return;
650 }
651 const ajaxHandle = this.getAjaxHandle();
652 if (!ajaxHandle) {
653 return;
654 }
655 this.setButtonLoadingState(btn, true);
656 const dataSend = ajaxHandle.getDataSetCurrent(elLPTarget);
657 dataSend.args = this.getFilterArgsFromForm(elForm, dataSend.args || {});
658 dataSend.args.paged = 1;
659 ajaxHandle.setDataSetCurrent(elLPTarget, dataSend);
660 this.reloadContent(elLPTarget, dataSend, btn);
661 }
662
663 /**
664 * Clear all filters and reload default data.
665 * @param args
666 */
667 clearFilters(args) {
668 const {
669 e
670 } = args;
671 if (e) {
672 e.preventDefault();
673 }
674 const btn = args?.target?.closest(ListStudentsEnrolled.selectors.elBtnClear);
675 if (btn) {
676 if (this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
677 return;
678 }
679 } else if (this.isRequesting) {
680 return;
681 }
682 const elForm = btn.closest(ListStudentsEnrolled.selectors.elForm);
683 const elLPTarget = this.elContainer.querySelector(ListStudentsEnrolled.selectors.elLPTarget);
684 if (!elLPTarget || !elForm) {
685 return;
686 }
687 const ajaxHandle = this.getAjaxHandle();
688 if (!ajaxHandle) {
689 return;
690 }
691 this.setButtonLoadingState(btn, true);
692 elForm.reset();
693 this.syncCourseIdFromName(elForm);
694 const dataSend = ajaxHandle.getDataSetCurrent(elLPTarget);
695 dataSend.args = lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(elForm, dataSend.args || {});
696 dataSend.args.paged = 1;
697 ajaxHandle.setDataSetCurrent(elLPTarget, dataSend);
698 this.reloadContent(elLPTarget, dataSend, btn);
699 }
700
701 /**
702 * Shared reload helper: loading indicator + AJAX fetch.
703 * @param elLPTarget
704 * @param dataSend
705 * @param btn
706 */
707 reloadContent(elLPTarget, dataSend, btn = null) {
708 const ajaxHandle = this.getAjaxHandle();
709 if (!ajaxHandle) {
710 this.isRequesting = false;
711 this.setButtonLoadingState(btn, false);
712 return;
713 }
714 this.isRequesting = true;
715 ajaxHandle.showHideLoading(elLPTarget, 1);
716 const callBack = {
717 success: response => {
718 const {
719 status,
720 data
721 } = response;
722 if ('success' === status) {
723 elLPTarget.innerHTML = data.content;
724 }
725 },
726 error: error => console.error(error),
727 completed: () => {
728 this.isRequesting = false;
729 ajaxHandle.showHideLoading(elLPTarget, 0);
730 this.setButtonLoadingState(btn, false);
731 }
732 };
733 ajaxHandle.fetchAJAX(dataSend, callBack);
734 }
735 }
736
737 // Auto-initialize when DOM is available (for standalone page load).
738 const listStudentsEnrolled = new ListStudentsEnrolled();
739 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(ListStudentsEnrolled.selectors.elContainer, () => {
740 listStudentsEnrolled.init();
741 });
742 })();
743
744 /******/ })()
745 ;
746 //# sourceMappingURL=list-students-enrolled.js.map