PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
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
← All changes | assets/src/js/admin/list-students-enrolled.js +369 -371 4.3.9 → 4.4.9 View file →
@@ -1,371 +1,369 @@
1 -/**
2 - * List Students Enrolled Script
3 - *
4 - * Handles filter and search interactions for the enrolled students table.
5 - * Pagination is handled by loadAJAX.js clickNumberPage (via .page-numbers class).
6 - *
7 - * @since 4.3.3
8 - * @version 1.0.0
9 - */
10 -import * as lpUtils from 'lpAssetsJsPath/utils.js';
11 -
12 -export class ListStudentsEnrolled {
13 - constructor() {
14 - this.instructorId = null;
15 - this.elContainer = null;
16 - this.isRequesting = false;
17 - }
18 -
19 - static selectors = {
20 - elContainer: '#lp-enrolled-students',
21 - elForm: '.lp-enrolled-students-form',
22 - elLPTarget: '.lp-target',
23 - elCourseNameInput: '.lp-enrolled-filter-course-name',
24 - elCourseIdInput: '#lp-enrolled-filter-course-id',
25 - elCourseList: '#lp-enrolled-course-list',
26 - elSearchInput: '.lp-enrolled-search-input',
27 - elStartDateInput: '.lp-enrolled-filter-start-date',
28 - elEndDateInput: '.lp-enrolled-filter-end-date',
29 - elBtnSearch: '.lp-enrolled-btn-search',
30 - elBtnClear: '.lp-enrolled-btn-clear',
31 - };
32 -
33 - init() {
34 - this.elContainer = document.querySelector(
35 - ListStudentsEnrolled.selectors.elContainer
36 - );
37 - if ( ! this.elContainer ) {
38 - return;
39 - }
40 -
41 - const elLPTarget = this.elContainer.querySelector(
42 - ListStudentsEnrolled.selectors.elLPTarget
43 - );
44 - const ajaxHandle = this.getAjaxHandle();
45 - if ( elLPTarget && ajaxHandle ) {
46 - const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
47 - if ( dataSend && dataSend.args ) {
48 - this.instructorId = dataSend.args.instructor_id;
49 - }
50 - }
51 -
52 - this.events();
53 - }
54 -
55 - events() {
56 - if ( ListStudentsEnrolled._loadedEvents ) {
57 - return;
58 - }
59 -
60 - ListStudentsEnrolled._loadedEvents = this;
61 -
62 - // Search/Clear button click.
63 - lpUtils.eventHandlers( 'click', [
64 - {
65 - selector: ListStudentsEnrolled.selectors.elBtnSearch,
66 - class: this,
67 - callBack: this.searchStudents.name,
68 - },
69 - {
70 - selector: ListStudentsEnrolled.selectors.elBtnClear,
71 - class: this,
72 - callBack: this.clearFilters.name,
73 - },
74 - ] );
75 -
76 - // Search on Enter key.
77 - lpUtils.eventHandlers( 'keydown', [
78 - {
79 - selector: ListStudentsEnrolled.selectors.elSearchInput,
80 - class: this,
81 - callBack: this.triggerBtnSearch.name,
82 - checkIsEventEnter: true,
83 - },
84 - {
85 - selector: ListStudentsEnrolled.selectors.elCourseNameInput,
86 - class: this,
87 - callBack: this.triggerBtnSearch.name,
88 - checkIsEventEnter: true,
89 - },
90 - {
91 - selector: ListStudentsEnrolled.selectors.elStartDateInput,
92 - class: this,
93 - callBack: this.triggerBtnSearch.name,
94 - checkIsEventEnter: true,
95 - },
96 - {
97 - selector: ListStudentsEnrolled.selectors.elEndDateInput,
98 - class: this,
99 - callBack: this.triggerBtnSearch.name,
100 - checkIsEventEnter: true,
101 - },
102 - ] );
103 -
104 - lpUtils.eventHandlers( 'change', [
105 - {
106 - selector: ListStudentsEnrolled.selectors.elStartDateInput,
107 - class: this,
108 - callBack: this.checkDatesRange.name,
109 - },
110 - {
111 - selector: ListStudentsEnrolled.selectors.elEndDateInput,
112 - class: this,
113 - callBack: this.checkDatesRange.name,
114 - },
115 - ] );
116 - }
117 -
118 - // Click button search.
119 - triggerBtnSearch() {
120 - const buttonSearch = this.elContainer.querySelector(
121 - ListStudentsEnrolled.selectors.elBtnSearch
122 - );
123 - if ( buttonSearch ) {
124 - buttonSearch.click();
125 - }
126 - }
127 -
128 - // Ensure start date is not after end date and vice versa. If invalid, adjust the other date to match.
129 - checkDatesRange( args ) {
130 - const { e } = args;
131 - const elInput = e?.target;
132 - if ( ! elInput ) {
133 - return;
134 - }
135 -
136 - const elForm = elInput.closest( ListStudentsEnrolled.selectors.elForm );
137 - if ( ! elForm ) {
138 - return;
139 - }
140 -
141 - const startDateInput = elForm.querySelector(
142 - ListStudentsEnrolled.selectors.elStartDateInput,
143 - );
144 - const endDateInput = elForm.querySelector(
145 - ListStudentsEnrolled.selectors.elEndDateInput,
146 - );
147 -
148 - if ( elInput === startDateInput ) {
149 - if ( startDateInput.value ) {
150 - endDateInput.min = startDateInput.value;
151 - if ( endDateInput.value && endDateInput.value < startDateInput.value ) {
152 - endDateInput.value = startDateInput.value;
153 - }
154 - } else {
155 - endDateInput.min = '';
156 - }
157 - } else if ( elInput === endDateInput ) {
158 - if ( endDateInput.value ) {
159 - startDateInput.max = endDateInput.value;
160 - if ( startDateInput.value && startDateInput.value > endDateInput.value ) {
161 - startDateInput.value = endDateInput.value;
162 - }
163 - } else {
164 - startDateInput.max = '';
165 - }
166 - }
167 - }
168 -
169 - setButtonLoadingState( btn, isLoading ) {
170 - if ( ! btn ) {
171 - return;
172 - }
173 -
174 - lpUtils.lpSetLoadingEl( btn, isLoading ? 1 : 0 );
175 - btn.disabled = !! isLoading;
176 - }
177 -
178 - getAjaxHandle() {
179 - const ajaxHandle = window.lpAJAXG;
180 - if (
181 - ! ajaxHandle ||
182 - typeof ajaxHandle.getDataSetCurrent !== 'function' ||
183 - typeof ajaxHandle.setDataSetCurrent !== 'function' ||
184 - typeof ajaxHandle.showHideLoading !== 'function' ||
185 - typeof ajaxHandle.fetchAJAX !== 'function'
186 - ) {
187 - return null;
188 - }
189 -
190 - return ajaxHandle;
191 - }
192 -
193 - syncCourseIdFromName( elForm ) {
194 - const courseIdInput = elForm?.querySelector(
195 - ListStudentsEnrolled.selectors.elCourseIdInput
196 - );
197 - if ( ! courseIdInput ) {
198 - return;
199 - }
200 -
201 - courseIdInput.value = '0';
202 -
203 - const courseNameInput = elForm.querySelector(
204 - ListStudentsEnrolled.selectors.elCourseNameInput
205 - );
206 - const datalist = elForm.querySelector(
207 - ListStudentsEnrolled.selectors.elCourseList
208 - );
209 - const courseName = courseNameInput?.value.trim() || '';
210 - if ( ! courseName || ! datalist ) {
211 - return;
212 - }
213 -
214 - const selectedOption = Array.from( datalist.options || [] ).find(
215 - ( option ) => option.value.trim() === courseName
216 - );
217 - if ( selectedOption ) {
218 - courseIdInput.value = selectedOption.dataset.courseId || '0';
219 - }
220 - }
221 -
222 - getFilterArgsFromForm( elForm, dataArgs = {} ) {
223 - this.syncCourseIdFromName( elForm );
224 - return lpUtils.mergeDataWithDatForm( elForm, dataArgs );
225 - }
226 -
227 - /**
228 - * Search students: update args.search, re-fetch.
229 - * @param args
230 - */
231 - searchStudents( args ) {
232 - const { e } = args;
233 - if ( e ) {
234 - e.preventDefault();
235 - }
236 - const btn = args?.target?.closest(
237 - ListStudentsEnrolled.selectors.elBtnSearch
238 - );
239 - if ( btn ) {
240 - if (
241 - this.isRequesting ||
242 - btn.classList.contains( 'loading' ) ||
243 - btn.disabled
244 - ) {
245 - return;
246 - }
247 - } else if ( this.isRequesting ) {
248 - return;
249 - }
250 -
251 - const elForm = btn.closest( ListStudentsEnrolled.selectors.elForm );
252 - const elLPTarget = this.elContainer.querySelector(
253 - ListStudentsEnrolled.selectors.elLPTarget
254 - );
255 - if ( ! elLPTarget || ! elForm ) {
256 - return;
257 - }
258 -
259 - const ajaxHandle = this.getAjaxHandle();
260 - if ( ! ajaxHandle ) {
261 - return;
262 - }
263 -
264 - this.setButtonLoadingState( btn, true );
265 -
266 - const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
267 - dataSend.args = this.getFilterArgsFromForm(
268 - elForm,
269 - dataSend.args || {}
270 - );
271 - dataSend.args.paged = 1;
272 - ajaxHandle.setDataSetCurrent( elLPTarget, dataSend );
273 -
274 - this.reloadContent( elLPTarget, dataSend, btn );
275 - }
276 -
277 - /**
278 - * Clear all filters and reload default data.
279 - * @param args
280 - */
281 - clearFilters( args ) {
282 - const { e } = args;
283 - if ( e ) {
284 - e.preventDefault();
285 - }
286 - const btn = args?.target?.closest(
287 - ListStudentsEnrolled.selectors.elBtnClear
288 - );
289 - if ( btn ) {
290 - if (
291 - this.isRequesting ||
292 - btn.classList.contains( 'loading' ) ||
293 - btn.disabled
294 - ) {
295 - return;
296 - }
297 - } else if ( this.isRequesting ) {
298 - return;
299 - }
300 -
301 - const elForm = btn.closest( ListStudentsEnrolled.selectors.elForm );
302 - const elLPTarget = this.elContainer.querySelector(
303 - ListStudentsEnrolled.selectors.elLPTarget
304 - );
305 - if ( ! elLPTarget || ! elForm ) {
306 - return;
307 - }
308 -
309 - const ajaxHandle = this.getAjaxHandle();
310 - if ( ! ajaxHandle ) {
311 - return;
312 - }
313 -
314 - this.setButtonLoadingState( btn, true );
315 -
316 - elForm.reset();
317 - this.syncCourseIdFromName( elForm );
318 -
319 - const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
320 - dataSend.args = lpUtils.mergeDataWithDatForm(
321 - elForm,
322 - dataSend.args || {}
323 - );
324 - dataSend.args.paged = 1;
325 - ajaxHandle.setDataSetCurrent( elLPTarget, dataSend );
326 -
327 - this.reloadContent( elLPTarget, dataSend, btn );
328 - }
329 -
330 - /**
331 - * Shared reload helper: loading indicator + AJAX fetch.
332 - * @param elLPTarget
333 - * @param dataSend
334 - * @param btn
335 - */
336 - reloadContent( elLPTarget, dataSend, btn = null ) {
337 - const ajaxHandle = this.getAjaxHandle();
338 - if ( ! ajaxHandle ) {
339 - this.isRequesting = false;
340 - this.setButtonLoadingState( btn, false );
341 - return;
342 - }
343 -
344 - this.isRequesting = true;
345 - ajaxHandle.showHideLoading( elLPTarget, 1 );
346 -
347 - const callBack = {
348 - success: ( response ) => {
349 - const { status, data } = response;
350 - if ( 'success' === status ) {
351 - elLPTarget.innerHTML = data.content;
352 - }
353 - },
354 - error: ( error ) => console.error( error ),
355 - completed: () => {
356 - this.isRequesting = false;
357 - ajaxHandle.showHideLoading( elLPTarget, 0 );
358 - this.setButtonLoadingState( btn, false );
359 - },
360 - };
361 -
362 - ajaxHandle.fetchAJAX( dataSend, callBack );
363 - }
364 -}
365 -
366 -// Auto-initialize when DOM is available (for standalone page load).
367 -const listStudentsEnrolled = new ListStudentsEnrolled();
368 -
369 -lpUtils.lpOnElementReady( ListStudentsEnrolled.selectors.elContainer, () => {
370 - listStudentsEnrolled.init();
371 -} );
1 +/**
2 + * List Students Enrolled Script
3 + *
4 + * Handles filter and search interactions for the enrolled students table.
5 + * Pagination is handled by loadAJAX.js clickNumberPage (via .page-numbers class).
6 + *
7 + * @since 4.3.3
8 + * @version 1.0.0
9 + */
10 +import * as lpUtils from 'lpAssetsJsPath/utils.js';
11 +
12 +export class ListStudentsEnrolled {
13 + constructor() {
14 + this.instructorId = null;
15 + this.elContainer = null;
16 + this.isRequesting = false;
17 + }
18 +
19 + static selectors = {
20 + elContainer: '.lp-enrolled-students',
21 + elForm: '.lp-enrolled-students-form',
22 + elLPTarget: '.lp-target',
23 + elCourseNameInput: '.lp-enrolled-filter-course-name',
24 + elCourseIdInput: '#lp-enrolled-filter-course-id',
25 + elCourseList: '#lp-enrolled-course-list',
26 + elSearchInput: '.lp-enrolled-search-input',
27 + elStartDateInput: '.lp-enrolled-filter-start-date',
28 + elEndDateInput: '.lp-enrolled-filter-end-date',
29 + elBtnSearch: '.lp-enrolled-btn-search',
30 + elBtnClear: '.lp-enrolled-btn-clear',
31 + };
32 +
33 + init() {
34 + this.elContainer = document.querySelector(
35 + ListStudentsEnrolled.selectors.elContainer
36 + );
37 + if ( ! this.elContainer ) {
38 + return;
39 + }
40 +
41 + const elLPTarget = this.elContainer.querySelector(
42 + ListStudentsEnrolled.selectors.elLPTarget
43 + );
44 + const ajaxHandle = this.getAjaxHandle();
45 + if ( elLPTarget && ajaxHandle ) {
46 + const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
47 + if ( dataSend && dataSend.args ) {
48 + this.instructorId = dataSend.args.instructor_id;
49 + }
50 + }
51 +
52 + this.events();
53 + }
54 +
55 + events() {
56 + if ( ListStudentsEnrolled._loadedEvents ) {
57 + return;
58 + }
59 +
60 + ListStudentsEnrolled._loadedEvents = this;
61 +
62 + // Search/Clear button click.
63 + lpUtils.eventHandlers( 'click', [
64 + {
65 + selector: ListStudentsEnrolled.selectors.elBtnSearch,
66 + class: this,
67 + callBack: this.searchStudents.name,
68 + },
69 + {
70 + selector: ListStudentsEnrolled.selectors.elBtnClear,
71 + class: this,
72 + callBack: this.clearFilters.name,
73 + },
74 + ] );
75 +
76 + // Search on Enter key.
77 + lpUtils.eventHandlers( 'keydown', [
78 + {
79 + selector: ListStudentsEnrolled.selectors.elSearchInput,
80 + class: this,
81 + callBack: this.triggerBtnSearch.name,
82 + checkIsEventEnter: true,
83 + },
84 + {
85 + selector: ListStudentsEnrolled.selectors.elCourseNameInput,
86 + class: this,
87 + callBack: this.triggerBtnSearch.name,
88 + checkIsEventEnter: true,
89 + },
90 + {
91 + selector: ListStudentsEnrolled.selectors.elStartDateInput,
92 + class: this,
93 + callBack: this.triggerBtnSearch.name,
94 + checkIsEventEnter: true,
95 + },
96 + {
97 + selector: ListStudentsEnrolled.selectors.elEndDateInput,
98 + class: this,
99 + callBack: this.triggerBtnSearch.name,
100 + checkIsEventEnter: true,
101 + },
102 + ] );
103 +
104 + lpUtils.eventHandlers( 'change', [
105 + {
106 + selector: ListStudentsEnrolled.selectors.elStartDateInput,
107 + class: this,
108 + callBack: this.checkDatesRange.name,
109 + },
110 + {
111 + selector: ListStudentsEnrolled.selectors.elEndDateInput,
112 + class: this,
113 + callBack: this.checkDatesRange.name,
114 + },
115 + ] );
116 + }
117 +
118 + // Click button search.
119 + triggerBtnSearch() {
120 + const buttonSearch = this.elContainer.querySelector(
121 + ListStudentsEnrolled.selectors.elBtnSearch
122 + );
123 + if ( buttonSearch ) {
124 + buttonSearch.click();
125 + }
126 + }
127 +
128 + // Ensure start date is not after end date and vice versa. If invalid, adjust the other date to match.
129 + checkDatesRange( args ) {
130 + const { e } = args;
131 + const elInput = e?.target;
132 + if ( ! elInput ) {
133 + return;
134 + }
135 +
136 + const elForm = elInput.closest( ListStudentsEnrolled.selectors.elForm );
137 + if ( ! elForm ) {
138 + return;
139 + }
140 +
141 + const startDateInput = elForm.querySelector(
142 + ListStudentsEnrolled.selectors.elStartDateInput,
143 + );
144 + const endDateInput = elForm.querySelector(
145 + ListStudentsEnrolled.selectors.elEndDateInput,
146 + );
147 +
148 + if ( elInput === startDateInput ) {
149 + if ( startDateInput.value ) {
150 + endDateInput.min = startDateInput.value;
151 + if ( endDateInput.value && endDateInput.value < startDateInput.value ) {
152 + endDateInput.value = startDateInput.value;
153 + }
154 + } else {
155 + endDateInput.min = '';
156 + }
157 + } else if ( elInput === endDateInput ) {
158 + if ( endDateInput.value ) {
159 + startDateInput.max = endDateInput.value;
160 + if ( startDateInput.value && startDateInput.value > endDateInput.value ) {
161 + startDateInput.value = endDateInput.value;
162 + }
163 + } else {
164 + startDateInput.max = '';
165 + }
166 + }
167 + }
168 +
169 + setButtonLoadingState( btn, isLoading ) {
170 + if ( ! btn ) {
171 + return;
172 + }
173 +
174 + lpUtils.lpSetLoadingEl( btn, isLoading ? 1 : 0 );
175 + //btn.disabled = !! isLoading;
176 + }
177 +
178 + getAjaxHandle() {
179 + const ajaxHandle = window.lpAJAXG;
180 + if (
181 + ! ajaxHandle ||
182 + typeof ajaxHandle.getDataSetCurrent !== 'function' ||
183 + typeof ajaxHandle.setDataSetCurrent !== 'function' ||
184 + typeof ajaxHandle.showHideLoading !== 'function' ||
185 + typeof ajaxHandle.fetchAJAX !== 'function'
186 + ) {
187 + return null;
188 + }
189 +
190 + return ajaxHandle;
191 + }
192 +
193 + syncCourseIdFromName( elForm ) {
194 + const courseIdInput = elForm?.querySelector(
195 + ListStudentsEnrolled.selectors.elCourseIdInput
196 + );
197 + if ( ! courseIdInput ) {
198 + return;
199 + }
200 +
201 + courseIdInput.value = '0';
202 +
203 + const courseNameInput = elForm.querySelector(
204 + ListStudentsEnrolled.selectors.elCourseNameInput
205 + );
206 + const datalist = elForm.querySelector(
207 + ListStudentsEnrolled.selectors.elCourseList
208 + );
209 + const courseName = courseNameInput?.value.trim() || '';
210 + if ( ! courseName || ! datalist ) {
211 + return;
212 + }
213 +
214 + const selectedOption = Array.from( datalist.options || [] ).find(
215 + ( option ) => option.value.trim() === courseName
216 + );
217 + if ( selectedOption ) {
218 + courseIdInput.value = selectedOption.dataset.courseId || '0';
219 + }
220 + }
221 +
222 + getFilterArgsFromForm( elForm, dataArgs = {} ) {
223 + this.syncCourseIdFromName( elForm );
224 + return lpUtils.mergeDataWithDatForm( elForm, dataArgs );
225 + }
226 +
227 + /**
228 + * Search students: update args.search, re-fetch.
229 + * @param args
230 + */
231 + searchStudents( args ) {
232 + const { e } = args;
233 + if ( e ) {
234 + e.preventDefault();
235 + }
236 + const btn = args?.target?.closest(
237 + ListStudentsEnrolled.selectors.elBtnSearch
238 + );
239 + if ( btn ) {
240 + if (
241 + this.isRequesting ||
242 + btn.classList.contains( 'loading' )
243 + ) {
244 + return;
245 + }
246 + } else if ( this.isRequesting ) {
247 + return;
248 + }
249 +
250 + const elForm = btn.closest( ListStudentsEnrolled.selectors.elForm );
251 + const elLPTarget = this.elContainer.querySelector(
252 + ListStudentsEnrolled.selectors.elLPTarget
253 + );
254 + if ( ! elLPTarget || ! elForm ) {
255 + return;
256 + }
257 +
258 + const ajaxHandle = this.getAjaxHandle();
259 + if ( ! ajaxHandle ) {
260 + return;
261 + }
262 +
263 + this.setButtonLoadingState( btn, true );
264 +
265 + const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
266 + dataSend.args = this.getFilterArgsFromForm(
267 + elForm,
268 + dataSend.args || {}
269 + );
270 + dataSend.args.paged = 1;
271 + ajaxHandle.setDataSetCurrent( elLPTarget, dataSend );
272 +
273 + this.reloadContent( elLPTarget, dataSend, btn );
274 + }
275 +
276 + /**
277 + * Clear all filters and reload default data.
278 + * @param args
279 + */
280 + clearFilters( args ) {
281 + const { e } = args;
282 + if ( e ) {
283 + e.preventDefault();
284 + }
285 + const btn = args?.target?.closest(
286 + ListStudentsEnrolled.selectors.elBtnClear
287 + );
288 + if ( btn ) {
289 + if (
290 + this.isRequesting ||
291 + btn.classList.contains( 'loading' )
292 + ) {
293 + return;
294 + }
295 + } else if ( this.isRequesting ) {
296 + return;
297 + }
298 +
299 + const elForm = btn.closest( ListStudentsEnrolled.selectors.elForm );
300 + const elLPTarget = this.elContainer.querySelector(
301 + ListStudentsEnrolled.selectors.elLPTarget
302 + );
303 + if ( ! elLPTarget || ! elForm ) {
304 + return;
305 + }
306 +
307 + const ajaxHandle = this.getAjaxHandle();
308 + if ( ! ajaxHandle ) {
309 + return;
310 + }
311 +
312 + this.setButtonLoadingState( btn, true );
313 +
314 + elForm.reset();
315 + this.syncCourseIdFromName( elForm );
316 +
317 + const dataSend = ajaxHandle.getDataSetCurrent( elLPTarget );
318 + dataSend.args = lpUtils.mergeDataWithDatForm(
319 + elForm,
320 + dataSend.args || {}
321 + );
322 + dataSend.args.paged = 1;
323 + ajaxHandle.setDataSetCurrent( elLPTarget, dataSend );
324 +
325 + this.reloadContent( elLPTarget, dataSend, btn );
326 + }
327 +
328 + /**
329 + * Shared reload helper: loading indicator + AJAX fetch.
330 + * @param elLPTarget
331 + * @param dataSend
332 + * @param btn
333 + */
334 + reloadContent( elLPTarget, dataSend, btn = null ) {
335 + const ajaxHandle = this.getAjaxHandle();
336 + if ( ! ajaxHandle ) {
337 + this.isRequesting = false;
338 + this.setButtonLoadingState( btn, false );
339 + return;
340 + }
341 +
342 + this.isRequesting = true;
343 + ajaxHandle.showHideLoading( elLPTarget, 1 );
344 +
345 + const callBack = {
346 + success: ( response ) => {
347 + const { status, data } = response;
348 + if ( 'success' === status ) {
349 + elLPTarget.innerHTML = data.content;
350 + }
351 + },
352 + error: ( error ) => console.error( error ),
353 + completed: () => {
354 + this.isRequesting = false;
355 + ajaxHandle.showHideLoading( elLPTarget, 0 );
356 + this.setButtonLoadingState( btn, false );
357 + },
358 + };
359 +
360 + ajaxHandle.fetchAJAX( dataSend, callBack );
361 + }
362 +}
363 +
364 +// Auto-initialize when DOM is available (for standalone page load).
365 +const listStudentsEnrolled = new ListStudentsEnrolled();
366 +
367 +lpUtils.lpOnElementReady( ListStudentsEnrolled.selectors.elContainer, () => {
368 + listStudentsEnrolled.init();
369 +} );