PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
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 4.2.1 All 138 releases
learnpress / assets / src / js / lpPopupSelectItemToAdd.js

lpPopupSelectItemToAdd.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at assets/src/js/lpPopupSelectItemToAdd.js

485 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * LearnPress Popup Select Item
3 *
4 * Handles load(search) item from API, show in popup and select item.
5 */
6
7 import * as lpUtils from 'lpAssetsJsPath/utils.js';
8 import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
9 import SweetAlert from 'sweetalert2';
10
11 let itemsSelectedData = [];
12 let elPopup;
13 let timeSearchTitleItem;
14
15 export class LpPopupSelectItemToAdd {
16 constructor() {
17 this.init();
18 }
19
20 static selectors = {
21 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
22 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
23 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
24 elHeaderCountItemSelected: '.header-count-items-selected',
25 elSelectItem: '.lp-select-item',
26 elListItems: '.list-items',
27 elPopupItemsToSelect: '.lp-popup-items-to-select',
28 elSearchTitleItem: '.lp-search-title-item',
29 elBtnBackListItems: '.lp-btn-back-to-select-items',
30 elListItemsWrap: '.list-items-wrap',
31 elListItemsSelected: '.list-items-selected',
32 elItemSelectedClone: '.li-item-selected.clone',
33 elItemSelected: '.li-item-selected',
34 LPTarget: '.lp-target',
35 };
36
37 init() {
38 this.events();
39 }
40
41 events = () => {
42 if ( LpPopupSelectItemToAdd._loadedEvents ) {
43 return;
44 }
45 LpPopupSelectItemToAdd._loadedEvents = true;
46
47 lpUtils.eventHandlers( 'click', [
48 {
49 selector:
50 LpPopupSelectItemToAdd.selectors
51 .elBtnShowPopupItemsToSelect,
52 callBack: this.showPopupItemsToSelect.name,
53 class: this,
54 },
55 {
56 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
57 callBack: this.selectItemsFromList.name,
58 class: this,
59 },
60 {
61 selector:
62 LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
63 callBack: this.showItemsSelected.name,
64 class: this,
65 },
66 {
67 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
68 callBack: this.backToSelectItems.name,
69 class: this,
70 },
71 {
72 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
73 callBack: this.removeItemSelected.name,
74 class: this,
75 },
76 {
77 selector: '.tabs .tab',
78 callBack: this.chooseTabItemsType.name,
79 class: this,
80 },
81 ] );
82
83 lpUtils.eventHandlers( 'keyup', [
84 {
85 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
86 callBack: this.searchTitleItemToSelect.name,
87 class: this,
88 },
89 ] );
90 };
91
92 // Show popup items to select
93 showPopupItemsToSelect = ( args ) => {
94 const { e, target = false, callBack } = args;
95 const elBtnShowPopupItemsToSelect = target.closest(
96 `${ LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect }`
97 );
98 if ( ! elBtnShowPopupItemsToSelect ) {
99 return;
100 }
101
102 // Reset items selected data when opening popup
103 itemsSelectedData = [];
104
105 const templateId = target.dataset.template || '';
106 const modalTemplate = document.querySelector( templateId );
107
108 SweetAlert.fire( {
109 html: modalTemplate.innerHTML,
110 showConfirmButton: false,
111 showCloseButton: true,
112 width: 'max(350px, 65vw)',
113 customClass: {
114 popup: 'lp-select-items-popup',
115 htmlContainer: 'lp-select-items-html-container',
116 container: 'lp-select-items-container',
117 },
118 willOpen: () => {
119 elPopup = SweetAlert.getPopup();
120
121 const elLPTarget = elPopup.querySelector(
122 `${ LpPopupSelectItemToAdd.selectors.LPTarget }`
123 );
124
125 // Avoid duplicate AJAX: loadAJAX.js handles fresh elements; skip if already loaded. Set timeout to ensure DOM is ready handle.
126 setTimeout( ()=> {
127 const elLoadAjaxElement = elLPTarget.closest( '.lp-load-ajax-element:not(.loaded)' );
128 if ( ! elLoadAjaxElement ) {
129 return;
130 }
131
132 if ( elLPTarget ) {
133 const dataSend =
134 window.lpAJAXG.getDataSetCurrent( elLPTarget );
135 dataSend.args.paged = 1;
136 dataSend.args.item_selecting = itemsSelectedData || [];
137 window.lpAJAXG.setDataSetCurrent( elLPTarget, dataSend );
138
139 window.lpAJAXG.fetchAJAX( dataSend, {
140 success: ( response ) => {
141 const { data } = response;
142 const elSkeleton = elPopup.querySelector(
143 '.lp-skeleton-animation'
144 );
145 elSkeleton.remove();
146 elLPTarget.innerHTML = data.content || '';
147
148 this.watchItemsSelectedDataChange();
149 },
150 } );
151 }
152 }, 1 );
153 },
154 } ).then( ( result ) => {
155 if ( result.isDismissed ) {
156 }
157 } );
158 };
159
160 // Choose tab items type
161 chooseTabItemsType = ( args ) => {
162 const { e, target, callBack } = args;
163 const elTabType = target.closest( '.tab' );
164 if ( ! elTabType ) {
165 return;
166 }
167 e.preventDefault();
168
169 const elTabs = elTabType.closest( '.tabs' );
170 if ( ! elTabs ) {
171 return;
172 }
173
174 const elSelectItemsToAdd = elTabs.closest(
175 `${ LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect }`
176 );
177 const elInputSearch = elSelectItemsToAdd.querySelector(
178 `${ LpPopupSelectItemToAdd.selectors.elSearchTitleItem }`
179 );
180
181 const itemType = elTabType.dataset.type;
182 const elTabLis = elTabs.querySelectorAll( '.tab' );
183 elTabLis.forEach( ( elTabLi ) => {
184 if ( elTabLi.classList.contains( 'active' ) ) {
185 elTabLi.classList.remove( 'active' );
186 }
187 } );
188 elTabType.classList.add( 'active' );
189 // Reset search input
190 elInputSearch.value = '';
191
192 const elLPTarget = elSelectItemsToAdd.querySelector(
193 `${ LpPopupSelectItemToAdd.selectors.LPTarget }`
194 );
195
196 const dataSend = window.lpAJAXG.getDataSetCurrent( elLPTarget );
197 dataSend.args.item_type = itemType;
198 dataSend.args.paged = 1;
199 dataSend.args.item_selecting = itemsSelectedData || [];
200 window.lpAJAXG.setDataSetCurrent( elLPTarget, dataSend );
201
202 window.lpAJAXG.showHideLoading( elLPTarget, 1 );
203
204 window.lpAJAXG.fetchAJAX( dataSend, {
205 success: ( response ) => {
206 const { data } = response;
207 elLPTarget.innerHTML = data.content || '';
208 },
209 error: ( error ) => {
210 lpToastify.show( error, 'error' );
211 },
212 completed: () => {
213 window.lpAJAXG.showHideLoading( elLPTarget, 0 );
214 this.watchItemsSelectedDataChange();
215 },
216 } );
217 };
218
219 // Choice items to add list items selected before adding to section
220 selectItemsFromList = ( args ) => {
221 const { e, target } = args;
222 const elItemAttend = target.closest(
223 `${ LpPopupSelectItemToAdd.selectors.elSelectItem }`
224 );
225 if ( ! elItemAttend ) {
226 return;
227 }
228
229 const elInput = elItemAttend.querySelector( 'input[type="checkbox"]' );
230 if ( target.tagName !== 'INPUT' ) {
231 elInput.click();
232 return;
233 }
234
235 const elUl = elItemAttend.closest(
236 `${ LpPopupSelectItemToAdd.selectors.elListItems }`
237 );
238 if ( ! elUl ) {
239 return;
240 }
241
242 const itemSelected = { ...elInput.dataset };
243 //console.log( 'itemSelected', itemSelected );
244
245 if ( elInput.checked ) {
246 const exists = itemsSelectedData.some(
247 ( item ) => item.id === itemSelected.id
248 );
249 if ( ! exists ) {
250 itemsSelectedData.push( itemSelected );
251 }
252 } else {
253 const index = itemsSelectedData.findIndex(
254 ( item ) => item.id === itemSelected.id
255 );
256 if ( index !== -1 ) {
257 itemsSelectedData.splice( index, 1 );
258 }
259 }
260
261 this.watchItemsSelectedDataChange();
262 };
263
264 // Search title item
265 searchTitleItemToSelect = ( args ) => {
266 const { e, target } = args;
267 const elInputSearch = target.closest(
268 LpPopupSelectItemToAdd.selectors.elSearchTitleItem
269 );
270 if ( ! elInputSearch ) {
271 return;
272 }
273
274 const elLPTarget = elPopup.querySelector(
275 `${ LpPopupSelectItemToAdd.selectors.LPTarget }`
276 );
277
278 clearTimeout( timeSearchTitleItem );
279
280 timeSearchTitleItem = setTimeout( () => {
281 const dataSet = window.lpAJAXG.getDataSetCurrent( elLPTarget );
282 dataSet.args.search_title = elInputSearch.value.trim();
283 dataSet.args.item_selecting = itemsSelectedData;
284 dataSet.args.paged = 1;
285 window.lpAJAXG.setDataSetCurrent( elLPTarget, dataSet );
286
287 // Show loading
288 window.lpAJAXG.showHideLoading( elLPTarget, 1 );
289
290 window.lpAJAXG.fetchAJAX( dataSet, {
291 success: ( response ) => {
292 const { data } = response;
293 elLPTarget.innerHTML = data.content || '';
294 },
295 error: ( error ) => {
296 lpToastify.show( error, 'error' );
297 },
298 completed: () => {
299 window.lpAJAXG.showHideLoading( elLPTarget, 0 );
300 },
301 } );
302 }, 800 );
303 };
304
305 // Show list of items, to choose items to add to section
306 showItemsSelected = ( args ) => {
307 const { e, target } = args;
308 const elBtnCountItemsSelected = target.closest(
309 `${ LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected }`
310 );
311 if ( ! elBtnCountItemsSelected ) {
312 return;
313 }
314
315 const elBtnBack = elPopup.querySelector(
316 `${ LpPopupSelectItemToAdd.selectors.elBtnBackListItems }`
317 );
318 const elTabs = elPopup.querySelector( '.tabs' );
319 const elListItemsWrap = elPopup.querySelector(
320 `${ LpPopupSelectItemToAdd.selectors.elListItemsWrap }`
321 );
322 const elHeaderItemsSelected = elPopup.querySelector(
323 `${ LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected }`
324 );
325 const elListItemsSelected = elPopup.querySelector(
326 `${ LpPopupSelectItemToAdd.selectors.elListItemsSelected }`
327 );
328 const elItemClone = elListItemsSelected.querySelector(
329 `${ LpPopupSelectItemToAdd.selectors.elItemSelectedClone }`
330 );
331 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
332
333 lpUtils.lpShowHideEl( elListItemsWrap, 0 );
334 lpUtils.lpShowHideEl( elBtnCountItemsSelected, 0 );
335 lpUtils.lpShowHideEl( elTabs, 0 );
336 lpUtils.lpShowHideEl( elBtnBack, 1 );
337 lpUtils.lpShowHideEl( elHeaderItemsSelected, 1 );
338 lpUtils.lpShowHideEl( elListItemsSelected, 1 );
339
340 elListItemsSelected
341 .querySelectorAll(
342 `${ LpPopupSelectItemToAdd.selectors.elItemSelected }:not(.clone)`
343 )
344 .forEach( ( elItem ) => {
345 elItem.remove();
346 } );
347 itemsSelectedData.forEach( ( item ) => {
348 const elItemSelected = elItemClone.cloneNode( true );
349 elItemSelected.classList.remove( 'clone' );
350 Object.entries( item ).forEach( ( [ key, value ] ) => {
351 elItemSelected.dataset[ key ] = value;
352 } );
353 const elTitleDisplay =
354 elItemSelected.querySelector( '.title-display' );
355 elTitleDisplay.innerHTML = item.title;
356
357 lpUtils.lpShowHideEl( elItemSelected, 1 );
358
359 elItemClone.insertAdjacentElement( 'beforebegin', elItemSelected );
360 } );
361 };
362
363 // Back to list of items
364 backToSelectItems = ( args ) => {
365 const { e, target } = args;
366 const elBtnBack = target.closest(
367 `${ LpPopupSelectItemToAdd.selectors.elBtnBackListItems }`
368 );
369 if ( ! elBtnBack ) {
370 return;
371 }
372
373 const elBtnCountItemsSelected = elPopup.querySelector(
374 `${ LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected }`
375 );
376 const elTabs = elPopup.querySelector( '.tabs' );
377 const elListItemsWrap = elPopup.querySelector(
378 `${ LpPopupSelectItemToAdd.selectors.elListItemsWrap }`
379 );
380 const elHeaderCountItemSelected = elPopup.querySelector(
381 `${ LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected }`
382 );
383 const elListItemsSelected = elPopup.querySelector(
384 `${ LpPopupSelectItemToAdd.selectors.elListItemsSelected }`
385 );
386 lpUtils.lpShowHideEl( elBtnCountItemsSelected, 1 );
387 lpUtils.lpShowHideEl( elListItemsWrap, 1 );
388 lpUtils.lpShowHideEl( elTabs, 1 );
389 lpUtils.lpShowHideEl( elBtnBack, 0 );
390 lpUtils.lpShowHideEl( elHeaderCountItemSelected, 0 );
391 lpUtils.lpShowHideEl( elListItemsSelected, 0 );
392 };
393
394 // Remove item selected from list items selected
395 removeItemSelected = ( args ) => {
396 const { e, target } = args;
397 const elRemoveItemSelected = target.closest(
398 `${ LpPopupSelectItemToAdd.selectors.elItemSelected }`
399 );
400 if ( ! elRemoveItemSelected ) {
401 return;
402 }
403
404 const itemRemove = elRemoveItemSelected.dataset;
405 const index = itemsSelectedData.findIndex(
406 ( item ) => item.id === itemRemove.id
407 );
408 if ( index !== -1 ) {
409 itemsSelectedData.splice( index, 1 );
410 }
411
412 elRemoveItemSelected.remove();
413
414 this.watchItemsSelectedDataChange();
415 };
416
417 // Watch items selected when data change
418 watchItemsSelectedDataChange = () => {
419 // Update count items selected, disable/enable buttons
420 const elBtnAddItemsSelected = elPopup.querySelector(
421 `${ LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected }`
422 );
423 const elBtnCountItemsSelected = elPopup.querySelector(
424 `${ LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected }`
425 );
426 const elSpanCount = elBtnCountItemsSelected.querySelector( 'span' );
427 const elHeaderCount = elPopup.querySelector(
428 `${ LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected }`
429 );
430 const elTarget = elPopup.querySelector(
431 `${ LpPopupSelectItemToAdd.selectors.LPTarget }`
432 );
433
434 if ( itemsSelectedData.length !== 0 ) {
435 elBtnCountItemsSelected.disabled = false;
436 elBtnAddItemsSelected.disabled = false;
437 elBtnAddItemsSelected.classList.add( 'active' );
438 elSpanCount.textContent = `(${ itemsSelectedData.length })`;
439 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
440 } else {
441 elBtnCountItemsSelected.disabled = true;
442 elBtnAddItemsSelected.disabled = true;
443 elBtnAddItemsSelected.classList.remove( 'active' );
444 elSpanCount.textContent = '';
445 elHeaderCount.textContent = '';
446 }
447
448 // Update list input checked, when items removed, or change tab type
449 const elListItems = elPopup.querySelector(
450 `${ LpPopupSelectItemToAdd.selectors.elListItems }`
451 );
452 const elInputs = elListItems.querySelectorAll(
453 'input[type="checkbox"]'
454 );
455 elInputs.forEach( ( elInputItem ) => {
456 const itemSelected = elInputItem.dataset;
457 const exists = itemsSelectedData.some(
458 ( item ) => item.id === itemSelected.id
459 );
460 elInputItem.checked = exists;
461 } );
462
463 // Set item selecting data to dataset for query.
464 const dataSet = window.lpAJAXG.getDataSetCurrent( elTarget );
465 dataSet.args.item_selecting = itemsSelectedData;
466 window.lpAJAXG.setDataSetCurrent( elTarget, dataSet );
467 };
468
469 // Add items selected to section
470 addItemsSelectedToSection = ( args ) => {
471 const { e, target, callBackHandle } = args;
472
473 if ( ! elPopup ) {
474 return;
475 }
476
477 SweetAlert.close();
478
479 if ( typeof callBackHandle === 'function' ) {
480 callBackHandle( itemsSelectedData );
481 itemsSelectedData = [];
482 }
483 };
484 }
485