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 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
← All changes | assets/src/js/admin/edit-quiz.js +597 -597 4.3.9 → 4.4.9 View file →
@@ -1,597 +1,597 @@
1 -/**
2 - * Edit Quiz JS handler as a class.
3 - *
4 - * @since 4.2.8.6
5 - * @version 1.0.3
6 - */
7 -import * as lpUtils from '../utils.js';
8 -import SweetAlert from 'sweetalert2';
9 -import Sortable from 'sortablejs';
10 -import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
11 -import 'toastify-js/src/toastify.css';
12 -import { EditQuestion } from './edit-question.js';
13 -import { LpPopupSelectItemToAdd } from 'lpAssetsJsPath/lpPopupSelectItemToAdd.js';
14 -
15 -let editQuestion;
16 -
17 -const lpPopupSelectItemToAdd = new LpPopupSelectItemToAdd();
18 -lpPopupSelectItemToAdd.init();
19 -
20 -class EditQuiz {
21 - constructor() {
22 - this.idUrlHandle = 'edit-quiz-questions';
23 - this.elEditQuizWrap = null;
24 - this.elEditListQuestions = null;
25 - this.quizID = null;
26 - }
27 -
28 - static selectors = {
29 - elEditQuizWrap: '.lp-edit-quiz-wrap',
30 - elQuestionEditMain: '.lp-question-edit-main',
31 - elQuestionToggleAll: '.lp-question-toggle-all',
32 - elEditListQuestions: '.lp-edit-list-questions',
33 - elQuestionItem: '.lp-question-item',
34 - elQuestionToggle: '.lp-question-toggle',
35 - elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
36 - elBtnAddQuestion: '.lp-btn-add-question',
37 - elBtnRemoveQuestion: '.lp-btn-remove-question',
38 - elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
39 - elBtnCancelUpdateQuestionTitle: '.lp-btn-cancel-update-question-title',
40 - elQuestionTitleNewInput: '.lp-question-title-new-input',
41 - elQuestionTitleInput: '.lp-question-title-input',
42 - elQuestionTypeLabel: '.lp-question-type-label',
43 - elQuestionTypeNew: '.lp-question-type-new',
44 - elAddNewQuestion: 'add-new-question',
45 - elQuestionClone: '.lp-question-item.clone',
46 - LPTarget: '.lp-target',
47 - elCollapse: 'lp-collapse',
48 - };
49 -
50 - init() {
51 - lpUtils.lpOnElementReady( EditQuiz.selectors.elEditQuizWrap, ( elEditQuizWrapFound ) => {
52 - this.elEditQuizWrap = elEditQuizWrapFound;
53 - this.elEditListQuestions = this.elEditQuizWrap.querySelector( EditQuiz.selectors.elEditListQuestions );
54 - const elLPTarget = this.elEditQuizWrap.closest( EditQuiz.selectors.LPTarget );
55 - const dataSend = window.lpAJAXG.getDataSetCurrent( elLPTarget );
56 - this.quizID = dataSend.args.quiz_id;
57 -
58 - this.sortAbleQuestion();
59 - editQuestion = new EditQuestion();
60 - editQuestion.init();
61 - const elQuestionEditMains = elEditQuizWrapFound.querySelectorAll( `${ EditQuiz.selectors.elQuestionEditMain }` );
62 - elQuestionEditMains.forEach( ( elQuestionEditMain ) => {
63 - editQuestion.sortAbleQuestionAnswer( elQuestionEditMain );
64 - } );
65 -
66 - this.events();
67 - } );
68 - }
69 -
70 - events() {
71 - if ( EditQuiz._loadedEvents ) {
72 - return;
73 - }
74 - EditQuiz._loadedEvents = true;
75 -
76 - lpUtils.eventHandlers( 'click', [
77 - {
78 - selector: EditQuiz.selectors.elQuestionToggleAll,
79 - class: this,
80 - callBack: this.toggleQuestionAll.name,
81 - },
82 - {
83 - selector: EditQuiz.selectors.elBtnAddQuestion,
84 - class: this,
85 - callBack: this.addQuestion.name,
86 - },
87 - {
88 - selector: EditQuiz.selectors.elBtnRemoveQuestion,
89 - class: this,
90 - callBack: this.removeQuestion.name,
91 - },
92 - {
93 - selector: EditQuiz.selectors.elBtnUpdateQuestionTitle,
94 - class: this,
95 - callBack: this.updateQuestionTitle.name,
96 - },
97 - {
98 - selector: EditQuiz.selectors.elBtnCancelUpdateQuestionTitle,
99 - class: this,
100 - callBack: this.cancelChangeTitleQuestion.name,
101 - },
102 - {
103 - selector: LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
104 - class: lpPopupSelectItemToAdd,
105 - callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
106 - callBackHandle: this.addQuestionsSelectedToQuiz.bind( this ),
107 - },
108 - ] );
109 -
110 - // Keydown
111 - lpUtils.eventHandlers( 'keydown', [
112 - {
113 - selector: EditQuiz.selectors.elQuestionTitleInput,
114 - class: this,
115 - callBack: this.updateQuestionTitle.name,
116 - checkIsEventEnter: true,
117 - },
118 - {
119 - selector: EditQuiz.selectors.elQuestionTitleNewInput,
120 - class: this,
121 - callBack: this.addQuestion.name,
122 - checkIsEventEnter: true,
123 - },
124 - ] );
125 -
126 - // Keyup
127 - lpUtils.eventHandlers( 'keyup', [
128 - {
129 - selector: EditQuiz.selectors.elQuestionTitleInput,
130 - class: this,
131 - callBack: this.changeTitleQuestion.name,
132 - },
133 - {
134 - selector: `${ EditQuiz.selectors.elQuestionTitleNewInput }, ${ EditQuiz.selectors.elQuestionTypeNew }`,
135 - class: this,
136 - callBack: this.checkCanAddQuestion.name,
137 - },
138 - ] );
139 -
140 - // Change
141 - lpUtils.eventHandlers( 'change', [
142 - {
143 - selector: EditQuiz.selectors.elQuestionTypeNew,
144 - class: this,
145 - callBack: this.checkCanAddQuestion.name,
146 - },
147 - ] );
148 -
149 - // Click
150 - document.addEventListener( 'click', ( e ) => {
151 - const target = e.target;
152 -
153 - lpUtils.toggleCollapse( e, target, EditQuiz.selectors.elQuestionToggle, [], () => this.checkAllQuestionsCollapsed() );
154 - } );
155 - }
156 -
157 - // Toggle all questions
158 - toggleQuestionAll( args ) {
159 - const { e, target } = args;
160 - const elQuestionToggleAll = target.closest( `${ EditQuiz.selectors.elQuestionToggleAll }` );
161 - if ( ! elQuestionToggleAll ) {
162 - return;
163 - }
164 -
165 - const elQuestionItems = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
166 -
167 - elQuestionToggleAll.classList.toggle( `${ EditQuiz.selectors.elCollapse }` );
168 -
169 - elQuestionItems.forEach( ( el ) => {
170 - const shouldCollapse = elQuestionToggleAll.classList.contains( `${ EditQuiz.selectors.elCollapse }` );
171 - el.classList.toggle( `${ EditQuiz.selectors.elCollapse }`, shouldCollapse );
172 - } );
173 - }
174 -
175 - checkAllQuestionsCollapsed() {
176 - const elQuestionItems = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
177 - const elQuestionToggleAll = this.elEditQuizWrap.querySelector( `${ EditQuiz.selectors.elQuestionToggleAll }` );
178 -
179 - let isAllExpand = true;
180 - elQuestionItems.forEach( ( el ) => {
181 - if ( el.classList.contains( `${ EditQuiz.selectors.elCollapse }` ) ) {
182 - isAllExpand = false;
183 - return false; // Break
184 - }
185 - } );
186 -
187 - if ( isAllExpand ) {
188 - elQuestionToggleAll.classList.remove( `${ EditQuiz.selectors.elCollapse }` );
189 - } else {
190 - elQuestionToggleAll.classList.add( `${ EditQuiz.selectors.elCollapse }` );
191 - }
192 - }
193 -
194 - updateCountItems() {
195 - const elCountItemsAll = this.elEditQuizWrap.querySelector( '.total-items' );
196 - const elItemsAll = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
197 - const itemsAllCount = elItemsAll.length;
198 -
199 - elCountItemsAll.dataset.count = itemsAllCount;
200 - elCountItemsAll.querySelector( '.count' ).textContent = itemsAllCount;
201 - }
202 -
203 - // Add question to quiz
204 - addQuestion( args ) {
205 - const { e, target, callBackNest } = args;
206 - e.preventDefault();
207 -
208 - const elAddNewQuestion = target.closest( `.${ EditQuiz.selectors.elAddNewQuestion }` );
209 - if ( ! elAddNewQuestion ) {
210 - return;
211 - }
212 -
213 - const elQuestionTitleNewInput = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTitleNewInput }` );
214 - const questionTitle = elQuestionTitleNewInput.value.trim();
215 - if ( ! questionTitle ) {
216 - lpToastify.show( elQuestionTitleNewInput.dataset.messEmptyTitle, 'error' );
217 - return;
218 - }
219 -
220 - const elQuestionType = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTypeNew }` );
221 - const questionType = elQuestionType.value;
222 - if ( ! questionType ) {
223 - lpToastify.show( elQuestionType.dataset.messEmptyType, 'error' );
224 - return;
225 - }
226 -
227 - const elQuestionClone = this.elEditListQuestions.querySelector( `${ EditQuiz.selectors.elQuestionItem }.clone` );
228 - const newQuestionItem = elQuestionClone.cloneNode( true );
229 - const elQuestionTitleInput = newQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
230 -
231 - elQuestionTitleInput.value = questionTitle;
232 - elQuestionTitleNewInput.value = '';
233 - newQuestionItem.classList.remove( 'clone' );
234 - lpUtils.lpShowHideEl( newQuestionItem, 1 );
235 - elQuestionClone.insertAdjacentElement( 'beforebegin', newQuestionItem );
236 - lpUtils.lpSetLoadingEl( newQuestionItem, 1 );
237 -
238 - const callBack = {
239 - success: ( response ) => {
240 - const { message, status, data } = response;
241 - const { question, html_edit_question } = data;
242 -
243 - if ( status === 'error' ) {
244 - throw `Error: ${ message }`;
245 - } else if ( status === 'success' ) {
246 - newQuestionItem.dataset.questionId = question.ID;
247 - newQuestionItem.dataset.questionType = question.meta_data._lp_type;
248 - newQuestionItem.outerHTML = html_edit_question;
249 - const elQuestionItemCreated = this.elEditListQuestions.querySelector( `${ EditQuiz.selectors.elQuestionItem }[data-question-id="${ question.ID }"]` );
250 - elQuestionItemCreated.classList.remove( EditQuiz.selectors.elCollapse );
251 - this.updateCountItems();
252 - editQuestion.initTinyMCE();
253 - const elQuestionEditMain = elQuestionItemCreated.querySelector( `${ EditQuiz.selectors.elQuestionEditMain }` );
254 - editQuestion.sortAbleQuestionAnswer( elQuestionEditMain );
255 -
256 - // Callback nest
257 - if ( callBackNest && typeof callBackNest.success === 'function' ) {
258 - callBackNest.success( { response, elQuestionItemCreated } );
259 - }
260 - }
261 -
262 - lpToastify.show( message, status );
263 - },
264 - error: ( error ) => {
265 - newQuestionItem.remove();
266 - lpToastify.show( error, 'error' );
267 -
268 - if ( callBackNest && typeof callBackNest.error === 'function' ) {
269 - callBackNest.error( { error, newQuestionItem } );
270 - }
271 - },
272 - completed: () => {
273 - lpUtils.lpSetLoadingEl( newQuestionItem, 0 );
274 - this.checkCanAddQuestion( { e, target: elQuestionTitleNewInput } );
275 -
276 - if ( callBackNest && typeof callBackNest.completed === 'function' ) {
277 - callBackNest.completed( { newQuestionItem } );
278 - }
279 - },
280 - };
281 -
282 - let dataSend = JSON.parse( elQuestionTitleNewInput.dataset.send );
283 - dataSend = { ...dataSend,
284 - question_title: questionTitle,
285 - question_type: questionType,
286 - };
287 - window.lpAJAXG.fetchAJAX( dataSend, callBack );
288 - }
289 -
290 - // Add questions selected from popup to quiz
291 - addQuestionsSelectedToQuiz( itemsSelected ) {
292 - const questionIds = [];
293 - itemsSelected.forEach( ( item ) => {
294 - const elQuestionItemClone = this.elEditQuizWrap.querySelector( `${ EditQuiz.selectors.elQuestionItem }.clone` );
295 - if ( ! elQuestionItemClone ) {
296 - return;
297 - }
298 -
299 - questionIds.push( item.id );
300 - const elQuestionItemNew = elQuestionItemClone.cloneNode( true );
301 - const elQuestionItemTitleInput = elQuestionItemNew.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
302 - elQuestionItemNew.classList.remove( 'clone' );
303 - elQuestionItemNew.dataset.questionId = item.id;
304 - elQuestionItemTitleInput.value = item.titleSelected;
305 -
306 - lpUtils.lpSetLoadingEl( elQuestionItemNew, 1 );
307 - lpUtils.lpShowHideEl( elQuestionItemNew, 1 );
308 - elQuestionItemClone.insertAdjacentElement( 'beforebegin', elQuestionItemNew );
309 - lpUtils.lpSetLoadingEl( elQuestionItemNew, 1 );
310 - } );
311 -
312 - const callBack = {
313 - success: ( response ) => {
314 - const { message, status, data } = response;
315 -
316 - if ( status === 'success' ) {
317 - lpToastify.show( message, status );
318 -
319 - const { html_edit_question } = data;
320 - if ( html_edit_question ) {
321 - Object.entries( html_edit_question ).forEach( ( [ question_id, item_html ] ) => {
322 - const elQuestionItemNew = this.elEditQuizWrap.querySelector(
323 - `${ EditQuiz.selectors.elQuestionItem }[data-question-id="${ question_id }"]`
324 - );
325 - elQuestionItemNew.outerHTML = item_html;
326 - } );
327 - }
328 - this.updateCountItems();
329 - editQuestion.initTinyMCE();
330 - } else {
331 - throw `Error: ${ message }`;
332 - }
333 - },
334 - error: ( error ) => {
335 - lpToastify.show( error, 'error' );
336 - },
337 - completed: () => {
338 - // completed handler intentionally empty
339 - },
340 - };
341 -
342 - const dataSend = { action: 'add_questions_to_quiz', quiz_id: this.quizID, question_ids: questionIds, args: { id_url: this.idUrlHandle } };
343 - window.lpAJAXG.fetchAJAX( dataSend, callBack );
344 - }
345 -
346 - checkCanAddQuestion( args ) {
347 - const { e, target } = args;
348 - const elTrigger = target.closest( EditQuiz.selectors.elQuestionTitleNewInput ) || target.closest( EditQuiz.selectors.elQuestionTypeNew );
349 - if ( ! elTrigger ) {
350 - return;
351 - }
352 -
353 - const elAddNewQuestion = elTrigger.closest( `.${ EditQuiz.selectors.elAddNewQuestion }` );
354 - if ( ! elAddNewQuestion ) {
355 - return;
356 - }
357 -
358 - const elBtnAddQuestion = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elBtnAddQuestion }` );
359 - if ( ! elBtnAddQuestion ) {
360 - return;
361 - }
362 -
363 - const elQuestionTitleInput = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTitleNewInput }` );
364 - const elQuestionTypeNew = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTypeNew }` );
365 -
366 - const questionTitle = elQuestionTitleInput.value.trim();
367 - const questionType = elQuestionTypeNew.value;
368 -
369 - if ( questionTitle && questionType ) {
370 - elBtnAddQuestion.classList.add( 'active' );
371 - } else {
372 - elBtnAddQuestion.classList.remove( 'active' );
373 - }
374 - }
375 -
376 - removeQuestion( args ) {
377 - const { e, target } = args;
378 - const elBtnRemoveQuestion = target.closest( `${ EditQuiz.selectors.elBtnRemoveQuestion }` );
379 - if ( ! elBtnRemoveQuestion ) {
380 - return;
381 - }
382 -
383 - const elQuestionItem = elBtnRemoveQuestion.closest( `${ EditQuiz.selectors.elQuestionItem }` );
384 - if ( ! elQuestionItem ) {
385 - return;
386 - }
387 -
388 - const questionId = elQuestionItem.dataset.questionId;
389 -
390 - SweetAlert.fire( {
391 - title: elBtnRemoveQuestion.dataset.title,
392 - text: elBtnRemoveQuestion.dataset.content,
393 - icon: 'warning',
394 - showCloseButton: true,
395 - showCancelButton: true,
396 - cancelButtonText: lpDataAdmin.i18n.cancel,
397 - confirmButtonText: lpDataAdmin.i18n.yes,
398 - reverseButtons: true,
399 - } ).then( ( result ) => {
400 - if ( result.isConfirmed ) {
401 - lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
402 -
403 - const callBack = {
404 - success: ( response ) => {
405 - const { message, status } = response;
406 -
407 - lpToastify.show( message, status );
408 -
409 - if ( status === 'success' ) {
410 - elQuestionItem.remove();
411 - this.updateCountItems();
412 - }
413 - },
414 - error: ( error ) => {
415 - lpToastify.show( error, 'error' );
416 - },
417 - completed: () => {
418 - lpUtils.lpSetLoadingEl( elQuestionItem, 0 );
419 - },
420 - };
421 -
422 - const dataSend = {
423 - quiz_id: this.quizID,
424 - action: 'remove_question_from_quiz',
425 - question_id: questionId,
426 - args: { id_url: this.idUrlHandle },
427 - };
428 - window.lpAJAXG.fetchAJAX( dataSend, callBack );
429 - }
430 - } );
431 - }
432 -
433 - updateQuestionTitle( args ) {
434 - const { e, target } = args;
435 - let canHandle = false;
436 -
437 - if ( target.closest( `${ EditQuiz.selectors.elBtnUpdateQuestionTitle }` ) ) {
438 - canHandle = true;
439 - } else if ( target.closest( `${ EditQuiz.selectors.elQuestionTitleInput }` ) && e.key === 'Enter' ) {
440 - canHandle = true;
441 - }
442 -
443 - if ( ! canHandle ) {
444 - return;
445 - }
446 -
447 - e.preventDefault();
448 -
449 - const elQuestionItem = target.closest( `${ EditQuiz.selectors.elQuestionItem }` );
450 - if ( ! elQuestionItem ) {
451 - return;
452 - }
453 -
454 - const elQuestionTitleInput = elQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
455 - if ( ! elQuestionTitleInput ) {
456 - return;
457 - }
458 -
459 - const questionId = elQuestionItem.dataset.questionId;
460 - const questionTitleValue = elQuestionTitleInput.value.trim();
461 - const titleOld = elQuestionTitleInput.dataset.old;
462 - const message = elQuestionTitleInput.dataset.messEmptyTitle;
463 - if ( questionTitleValue.length === 0 ) {
464 - lpToastify.show( message, 'error' );
465 - return;
466 - }
467 -
468 - if ( questionTitleValue === titleOld ) {
469 - return;
470 - }
471 -
472 - elQuestionTitleInput.blur();
473 - lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
474 -
475 - const callBack = {
476 - success: ( response ) => {
477 - const { message, status } = response;
478 -
479 - if ( status === 'success' ) {
480 - elQuestionTitleInput.dataset.old = questionTitleValue;
481 - } else {
482 - elQuestionTitleInput.value = titleOld;
483 - }
484 -
485 - lpToastify.show( message, status );
486 - },
487 - error: ( error ) => {
488 - lpToastify.show( error, 'error' );
489 - },
490 - completed: () => {
491 - lpUtils.lpSetLoadingEl( elQuestionItem, 0 );
492 - elQuestionItem.classList.remove( 'editing' );
493 - },
494 - };
495 -
496 - const dataSend = {
497 - quiz_id: this.quizID,
498 - action: 'update_question',
499 - question_id: questionId,
500 - question_title: questionTitleValue,
501 - args: { id_url: this.idUrlHandle },
502 - };
503 - window.lpAJAXG.fetchAJAX( dataSend, callBack );
504 - }
505 -
506 - changeTitleQuestion( args ) {
507 - const { e, target } = args;
508 - const elQuestionTitleInput = target.closest( `${ EditQuiz.selectors.elQuestionTitleInput }` );
509 - if ( ! elQuestionTitleInput ) {
510 - return;
511 - }
512 -
513 - const elQuestionItem = elQuestionTitleInput.closest( `${ EditQuiz.selectors.elQuestionItem }` );
514 - const titleValue = elQuestionTitleInput.value.trim();
515 - const titleValueOld = elQuestionTitleInput.dataset.old || '';
516 -
517 - if ( titleValue === titleValueOld ) {
518 - elQuestionItem.classList.remove( 'editing' );
519 - } else {
520 - elQuestionItem.classList.add( 'editing' );
521 - }
522 - }
523 -
524 - cancelChangeTitleQuestion( args ) {
525 - const { e, target } = args;
526 - const elBtnCancelUpdateQuestionTitle = target.closest( `${ EditQuiz.selectors.elBtnCancelUpdateQuestionTitle }` );
527 - if ( ! elBtnCancelUpdateQuestionTitle ) {
528 - return;
529 - }
530 -
531 - const elQuestionItem = elBtnCancelUpdateQuestionTitle.closest( `${ EditQuiz.selectors.elQuestionItem }` );
532 - const elQuestionTitleInput = elQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
533 - elQuestionTitleInput.value = elQuestionTitleInput.dataset.old || '';
534 - elQuestionItem.classList.remove( 'editing' );
535 - }
536 -
537 - sortAbleQuestion() {
538 - let isUpdateSectionPosition = 0;
539 - let timeout;
540 -
541 - new Sortable( this.elEditListQuestions, {
542 - handle: '.drag',
543 - animation: 150,
544 - onEnd: ( evt ) => {
545 - const elQuestionItem = evt.item;
546 - if ( ! isUpdateSectionPosition ) {
547 - return;
548 - }
549 -
550 - clearTimeout( timeout );
551 - timeout = setTimeout( () => {
552 - lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
553 -
554 - const questionIds = [];
555 - const elQuestionItems = this.elEditListQuestions.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
556 - elQuestionItems.forEach( ( elItem ) => {
557 - const questionId = elItem.dataset.questionId;
558 - if ( questionId ) {
559 - questionIds.push( questionId );
560 - }
561 - } );
562 -
563 - const callBack = {
564 - success: ( response ) => {
565 - const { message, status } = response;
566 -
567 - if ( status === 'success' ) {
568 - lpToastify.show( message, status );
569 - editQuestion.initTinyMCE();
570 - } else {
571 - throw `Error: ${ message }`;
572 - }
573 - },
574 - error: ( error ) => {
575 - lpToastify.show( error, 'error' );
576 - },
577 - completed: () => {
578 - lpUtils.lpSetLoadingEl( elQuestionItem, 0 ); isUpdateSectionPosition = 0;
579 - },
580 - };
581 -
582 - const dataSend = { quiz_id: this.quizID, action: 'update_questions_position', question_ids: questionIds, args: { id_url: this.idUrlHandle } };
583 - window.lpAJAXG.fetchAJAX( dataSend, callBack );
584 - }, 1000 );
585 - },
586 - onMove: () => {
587 - clearTimeout( timeout );
588 - },
589 - onUpdate: () => {
590 - isUpdateSectionPosition = 1;
591 - },
592 - } );
593 - }
594 -}
595 -
596 -const editQuiz = new EditQuiz();
597 -editQuiz.init();
1 +/**
2 + * Edit Quiz JS handler as a class.
3 + *
4 + * @since 4.2.8.6
5 + * @version 1.0.3
6 + */
7 +import * as lpUtils from '../utils.js';
8 +import SweetAlert from 'sweetalert2';
9 +import Sortable from 'sortablejs';
10 +import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
11 +import 'toastify-js/src/toastify.css';
12 +import { EditQuestion } from './edit-question.js';
13 +import { LpPopupSelectItemToAdd } from 'lpAssetsJsPath/lpPopupSelectItemToAdd.js';
14 +
15 +let editQuestion;
16 +
17 +const lpPopupSelectItemToAdd = new LpPopupSelectItemToAdd();
18 +lpPopupSelectItemToAdd.init();
19 +
20 +class EditQuiz {
21 + constructor() {
22 + this.idUrlHandle = 'edit-quiz-questions';
23 + this.elEditQuizWrap = null;
24 + this.elEditListQuestions = null;
25 + this.quizID = null;
26 + }
27 +
28 + static selectors = {
29 + elEditQuizWrap: '.lp-edit-quiz-wrap',
30 + elQuestionEditMain: '.lp-question-edit-main',
31 + elQuestionToggleAll: '.lp-question-toggle-all',
32 + elEditListQuestions: '.lp-edit-list-questions',
33 + elQuestionItem: '.lp-question-item',
34 + elQuestionToggle: '.lp-question-toggle',
35 + elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
36 + elBtnAddQuestion: '.lp-btn-add-question',
37 + elBtnRemoveQuestion: '.lp-btn-remove-question',
38 + elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
39 + elBtnCancelUpdateQuestionTitle: '.lp-btn-cancel-update-question-title',
40 + elQuestionTitleNewInput: '.lp-question-title-new-input',
41 + elQuestionTitleInput: '.lp-question-title-input',
42 + elQuestionTypeLabel: '.lp-question-type-label',
43 + elQuestionTypeNew: '.lp-question-type-new',
44 + elAddNewQuestion: 'add-new-question',
45 + elQuestionClone: '.lp-question-item.clone',
46 + LPTarget: '.lp-target',
47 + elCollapse: 'lp-collapse',
48 + };
49 +
50 + init() {
51 + lpUtils.lpOnElementReady( EditQuiz.selectors.elEditQuizWrap, ( elEditQuizWrapFound ) => {
52 + this.elEditQuizWrap = elEditQuizWrapFound;
53 + this.elEditListQuestions = this.elEditQuizWrap.querySelector( EditQuiz.selectors.elEditListQuestions );
54 + const elLPTarget = this.elEditQuizWrap.closest( EditQuiz.selectors.LPTarget );
55 + const dataSend = window.lpAJAXG.getDataSetCurrent( elLPTarget );
56 + this.quizID = dataSend.args.quiz_id;
57 +
58 + this.sortAbleQuestion();
59 + editQuestion = new EditQuestion();
60 + editQuestion.init();
61 + const elQuestionEditMains = elEditQuizWrapFound.querySelectorAll( `${ EditQuiz.selectors.elQuestionEditMain }` );
62 + elQuestionEditMains.forEach( ( elQuestionEditMain ) => {
63 + editQuestion.sortAbleQuestionAnswer( elQuestionEditMain );
64 + } );
65 +
66 + this.events();
67 + } );
68 + }
69 +
70 + events() {
71 + if ( EditQuiz._loadedEvents ) {
72 + return;
73 + }
74 + EditQuiz._loadedEvents = true;
75 +
76 + lpUtils.eventHandlers( 'click', [
77 + {
78 + selector: EditQuiz.selectors.elQuestionToggleAll,
79 + class: this,
80 + callBack: this.toggleQuestionAll.name,
81 + },
82 + {
83 + selector: EditQuiz.selectors.elBtnAddQuestion,
84 + class: this,
85 + callBack: this.addQuestion.name,
86 + },
87 + {
88 + selector: EditQuiz.selectors.elBtnRemoveQuestion,
89 + class: this,
90 + callBack: this.removeQuestion.name,
91 + },
92 + {
93 + selector: EditQuiz.selectors.elBtnUpdateQuestionTitle,
94 + class: this,
95 + callBack: this.updateQuestionTitle.name,
96 + },
97 + {
98 + selector: EditQuiz.selectors.elBtnCancelUpdateQuestionTitle,
99 + class: this,
100 + callBack: this.cancelChangeTitleQuestion.name,
101 + },
102 + {
103 + selector: LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
104 + class: lpPopupSelectItemToAdd,
105 + callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
106 + callBackHandle: this.addQuestionsSelectedToQuiz.bind( this ),
107 + },
108 + ] );
109 +
110 + // Keydown
111 + lpUtils.eventHandlers( 'keydown', [
112 + {
113 + selector: EditQuiz.selectors.elQuestionTitleInput,
114 + class: this,
115 + callBack: this.updateQuestionTitle.name,
116 + checkIsEventEnter: true,
117 + },
118 + {
119 + selector: EditQuiz.selectors.elQuestionTitleNewInput,
120 + class: this,
121 + callBack: this.addQuestion.name,
122 + checkIsEventEnter: true,
123 + },
124 + ] );
125 +
126 + // Keyup
127 + lpUtils.eventHandlers( 'keyup', [
128 + {
129 + selector: EditQuiz.selectors.elQuestionTitleInput,
130 + class: this,
131 + callBack: this.changeTitleQuestion.name,
132 + },
133 + {
134 + selector: `${ EditQuiz.selectors.elQuestionTitleNewInput }, ${ EditQuiz.selectors.elQuestionTypeNew }`,
135 + class: this,
136 + callBack: this.checkCanAddQuestion.name,
137 + },
138 + ] );
139 +
140 + // Change
141 + lpUtils.eventHandlers( 'change', [
142 + {
143 + selector: EditQuiz.selectors.elQuestionTypeNew,
144 + class: this,
145 + callBack: this.checkCanAddQuestion.name,
146 + },
147 + ] );
148 +
149 + // Click
150 + document.addEventListener( 'click', ( e ) => {
151 + const target = e.target;
152 +
153 + lpUtils.toggleCollapse( e, target, EditQuiz.selectors.elQuestionToggle, [], () => this.checkAllQuestionsCollapsed() );
154 + } );
155 + }
156 +
157 + // Toggle all questions
158 + toggleQuestionAll( args ) {
159 + const { e, target } = args;
160 + const elQuestionToggleAll = target.closest( `${ EditQuiz.selectors.elQuestionToggleAll }` );
161 + if ( ! elQuestionToggleAll ) {
162 + return;
163 + }
164 +
165 + const elQuestionItems = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
166 +
167 + elQuestionToggleAll.classList.toggle( `${ EditQuiz.selectors.elCollapse }` );
168 +
169 + elQuestionItems.forEach( ( el ) => {
170 + const shouldCollapse = elQuestionToggleAll.classList.contains( `${ EditQuiz.selectors.elCollapse }` );
171 + el.classList.toggle( `${ EditQuiz.selectors.elCollapse }`, shouldCollapse );
172 + } );
173 + }
174 +
175 + checkAllQuestionsCollapsed() {
176 + const elQuestionItems = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
177 + const elQuestionToggleAll = this.elEditQuizWrap.querySelector( `${ EditQuiz.selectors.elQuestionToggleAll }` );
178 +
179 + let isAllExpand = true;
180 + elQuestionItems.forEach( ( el ) => {
181 + if ( el.classList.contains( `${ EditQuiz.selectors.elCollapse }` ) ) {
182 + isAllExpand = false;
183 + return false; // Break
184 + }
185 + } );
186 +
187 + if ( isAllExpand ) {
188 + elQuestionToggleAll.classList.remove( `${ EditQuiz.selectors.elCollapse }` );
189 + } else {
190 + elQuestionToggleAll.classList.add( `${ EditQuiz.selectors.elCollapse }` );
191 + }
192 + }
193 +
194 + updateCountItems() {
195 + const elCountItemsAll = this.elEditQuizWrap.querySelector( '.total-items' );
196 + const elItemsAll = this.elEditQuizWrap.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
197 + const itemsAllCount = elItemsAll.length;
198 +
199 + elCountItemsAll.dataset.count = itemsAllCount;
200 + elCountItemsAll.querySelector( '.count' ).textContent = itemsAllCount;
201 + }
202 +
203 + // Add question to quiz
204 + addQuestion( args ) {
205 + const { e, target, callBackNest } = args;
206 + e.preventDefault();
207 +
208 + const elAddNewQuestion = target.closest( `.${ EditQuiz.selectors.elAddNewQuestion }` );
209 + if ( ! elAddNewQuestion ) {
210 + return;
211 + }
212 +
213 + const elQuestionTitleNewInput = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTitleNewInput }` );
214 + const questionTitle = elQuestionTitleNewInput.value.trim();
215 + if ( ! questionTitle ) {
216 + lpToastify.show( elQuestionTitleNewInput.dataset.messEmptyTitle, 'error' );
217 + return;
218 + }
219 +
220 + const elQuestionType = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTypeNew }` );
221 + const questionType = elQuestionType.value;
222 + if ( ! questionType ) {
223 + lpToastify.show( elQuestionType.dataset.messEmptyType, 'error' );
224 + return;
225 + }
226 +
227 + const elQuestionClone = this.elEditListQuestions.querySelector( `${ EditQuiz.selectors.elQuestionItem }.clone` );
228 + const newQuestionItem = elQuestionClone.cloneNode( true );
229 + const elQuestionTitleInput = newQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
230 +
231 + elQuestionTitleInput.value = questionTitle;
232 + elQuestionTitleNewInput.value = '';
233 + newQuestionItem.classList.remove( 'clone' );
234 + lpUtils.lpShowHideEl( newQuestionItem, 1 );
235 + elQuestionClone.insertAdjacentElement( 'beforebegin', newQuestionItem );
236 + lpUtils.lpSetLoadingEl( newQuestionItem, 1 );
237 +
238 + const callBack = {
239 + success: ( response ) => {
240 + const { message, status, data } = response;
241 + const { question, html_edit_question } = data;
242 +
243 + if ( status === 'error' ) {
244 + throw `Error: ${ message }`;
245 + } else if ( status === 'success' ) {
246 + newQuestionItem.dataset.questionId = question.ID;
247 + newQuestionItem.dataset.questionType = question.meta_data._lp_type;
248 + newQuestionItem.outerHTML = html_edit_question;
249 + const elQuestionItemCreated = this.elEditListQuestions.querySelector( `${ EditQuiz.selectors.elQuestionItem }[data-question-id="${ question.ID }"]` );
250 + elQuestionItemCreated.classList.remove( EditQuiz.selectors.elCollapse );
251 + this.updateCountItems();
252 + editQuestion.initTinyMCE();
253 + const elQuestionEditMain = elQuestionItemCreated.querySelector( `${ EditQuiz.selectors.elQuestionEditMain }` );
254 + editQuestion.sortAbleQuestionAnswer( elQuestionEditMain );
255 +
256 + // Callback nest
257 + if ( callBackNest && typeof callBackNest.success === 'function' ) {
258 + callBackNest.success( { response, elQuestionItemCreated } );
259 + }
260 + }
261 +
262 + lpToastify.show( message, status );
263 + },
264 + error: ( error ) => {
265 + newQuestionItem.remove();
266 + lpToastify.show( error, 'error' );
267 +
268 + if ( callBackNest && typeof callBackNest.error === 'function' ) {
269 + callBackNest.error( { error, newQuestionItem } );
270 + }
271 + },
272 + completed: () => {
273 + lpUtils.lpSetLoadingEl( newQuestionItem, 0 );
274 + this.checkCanAddQuestion( { e, target: elQuestionTitleNewInput } );
275 +
276 + if ( callBackNest && typeof callBackNest.completed === 'function' ) {
277 + callBackNest.completed( { newQuestionItem } );
278 + }
279 + },
280 + };
281 +
282 + let dataSend = JSON.parse( elQuestionTitleNewInput.dataset.send );
283 + dataSend = { ...dataSend,
284 + question_title: questionTitle,
285 + question_type: questionType,
286 + };
287 + window.lpAJAXG.fetchAJAX( dataSend, callBack );
288 + }
289 +
290 + // Add questions selected from popup to quiz
291 + addQuestionsSelectedToQuiz( itemsSelected ) {
292 + const questionIds = [];
293 + itemsSelected.forEach( ( item ) => {
294 + const elQuestionItemClone = this.elEditQuizWrap.querySelector( `${ EditQuiz.selectors.elQuestionItem }.clone` );
295 + if ( ! elQuestionItemClone ) {
296 + return;
297 + }
298 +
299 + questionIds.push( item.id );
300 + const elQuestionItemNew = elQuestionItemClone.cloneNode( true );
301 + const elQuestionItemTitleInput = elQuestionItemNew.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
302 + elQuestionItemNew.classList.remove( 'clone' );
303 + elQuestionItemNew.dataset.questionId = item.id;
304 + elQuestionItemTitleInput.value = item.titleSelected;
305 +
306 + lpUtils.lpSetLoadingEl( elQuestionItemNew, 1 );
307 + lpUtils.lpShowHideEl( elQuestionItemNew, 1 );
308 + elQuestionItemClone.insertAdjacentElement( 'beforebegin', elQuestionItemNew );
309 + lpUtils.lpSetLoadingEl( elQuestionItemNew, 1 );
310 + } );
311 +
312 + const callBack = {
313 + success: ( response ) => {
314 + const { message, status, data } = response;
315 +
316 + if ( status === 'success' ) {
317 + lpToastify.show( message, status );
318 +
319 + const { html_edit_question } = data;
320 + if ( html_edit_question ) {
321 + Object.entries( html_edit_question ).forEach( ( [ question_id, item_html ] ) => {
322 + const elQuestionItemNew = this.elEditQuizWrap.querySelector(
323 + `${ EditQuiz.selectors.elQuestionItem }[data-question-id="${ question_id }"]`
324 + );
325 + elQuestionItemNew.outerHTML = item_html;
326 + } );
327 + }
328 + this.updateCountItems();
329 + editQuestion.initTinyMCE();
330 + } else {
331 + throw `Error: ${ message }`;
332 + }
333 + },
334 + error: ( error ) => {
335 + lpToastify.show( error, 'error' );
336 + },
337 + completed: () => {
338 + // completed handler intentionally empty
339 + },
340 + };
341 +
342 + const dataSend = { action: 'add_questions_to_quiz', quiz_id: this.quizID, question_ids: questionIds, args: { id_url: this.idUrlHandle } };
343 + window.lpAJAXG.fetchAJAX( dataSend, callBack );
344 + }
345 +
346 + checkCanAddQuestion( args ) {
347 + const { e, target } = args;
348 + const elTrigger = target.closest( EditQuiz.selectors.elQuestionTitleNewInput ) || target.closest( EditQuiz.selectors.elQuestionTypeNew );
349 + if ( ! elTrigger ) {
350 + return;
351 + }
352 +
353 + const elAddNewQuestion = elTrigger.closest( `.${ EditQuiz.selectors.elAddNewQuestion }` );
354 + if ( ! elAddNewQuestion ) {
355 + return;
356 + }
357 +
358 + const elBtnAddQuestion = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elBtnAddQuestion }` );
359 + if ( ! elBtnAddQuestion ) {
360 + return;
361 + }
362 +
363 + const elQuestionTitleInput = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTitleNewInput }` );
364 + const elQuestionTypeNew = elAddNewQuestion.querySelector( `${ EditQuiz.selectors.elQuestionTypeNew }` );
365 +
366 + const questionTitle = elQuestionTitleInput.value.trim();
367 + const questionType = elQuestionTypeNew.value;
368 +
369 + if ( questionTitle && questionType ) {
370 + elBtnAddQuestion.classList.add( 'active' );
371 + } else {
372 + elBtnAddQuestion.classList.remove( 'active' );
373 + }
374 + }
375 +
376 + removeQuestion( args ) {
377 + const { e, target } = args;
378 + const elBtnRemoveQuestion = target.closest( `${ EditQuiz.selectors.elBtnRemoveQuestion }` );
379 + if ( ! elBtnRemoveQuestion ) {
380 + return;
381 + }
382 +
383 + const elQuestionItem = elBtnRemoveQuestion.closest( `${ EditQuiz.selectors.elQuestionItem }` );
384 + if ( ! elQuestionItem ) {
385 + return;
386 + }
387 +
388 + const questionId = elQuestionItem.dataset.questionId;
389 +
390 + SweetAlert.fire( {
391 + title: elBtnRemoveQuestion.dataset.title,
392 + text: elBtnRemoveQuestion.dataset.content,
393 + icon: 'warning',
394 + showCloseButton: true,
395 + showCancelButton: true,
396 + cancelButtonText: lpDataAdmin.i18n.cancel,
397 + confirmButtonText: lpDataAdmin.i18n.yes,
398 + reverseButtons: true,
399 + } ).then( ( result ) => {
400 + if ( result.isConfirmed ) {
401 + lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
402 +
403 + const callBack = {
404 + success: ( response ) => {
405 + const { message, status } = response;
406 +
407 + lpToastify.show( message, status );
408 +
409 + if ( status === 'success' ) {
410 + elQuestionItem.remove();
411 + this.updateCountItems();
412 + }
413 + },
414 + error: ( error ) => {
415 + lpToastify.show( error, 'error' );
416 + },
417 + completed: () => {
418 + lpUtils.lpSetLoadingEl( elQuestionItem, 0 );
419 + },
420 + };
421 +
422 + const dataSend = {
423 + quiz_id: this.quizID,
424 + action: 'remove_question_from_quiz',
425 + question_id: questionId,
426 + args: { id_url: this.idUrlHandle },
427 + };
428 + window.lpAJAXG.fetchAJAX( dataSend, callBack );
429 + }
430 + } );
431 + }
432 +
433 + updateQuestionTitle( args ) {
434 + const { e, target } = args;
435 + let canHandle = false;
436 +
437 + if ( target.closest( `${ EditQuiz.selectors.elBtnUpdateQuestionTitle }` ) ) {
438 + canHandle = true;
439 + } else if ( target.closest( `${ EditQuiz.selectors.elQuestionTitleInput }` ) && e.key === 'Enter' ) {
440 + canHandle = true;
441 + }
442 +
443 + if ( ! canHandle ) {
444 + return;
445 + }
446 +
447 + e.preventDefault();
448 +
449 + const elQuestionItem = target.closest( `${ EditQuiz.selectors.elQuestionItem }` );
450 + if ( ! elQuestionItem ) {
451 + return;
452 + }
453 +
454 + const elQuestionTitleInput = elQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
455 + if ( ! elQuestionTitleInput ) {
456 + return;
457 + }
458 +
459 + const questionId = elQuestionItem.dataset.questionId;
460 + const questionTitleValue = elQuestionTitleInput.value.trim();
461 + const titleOld = elQuestionTitleInput.dataset.old;
462 + const message = elQuestionTitleInput.dataset.messEmptyTitle;
463 + if ( questionTitleValue.length === 0 ) {
464 + lpToastify.show( message, 'error' );
465 + return;
466 + }
467 +
468 + if ( questionTitleValue === titleOld ) {
469 + return;
470 + }
471 +
472 + elQuestionTitleInput.blur();
473 + lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
474 +
475 + const callBack = {
476 + success: ( response ) => {
477 + const { message, status } = response;
478 +
479 + if ( status === 'success' ) {
480 + elQuestionTitleInput.dataset.old = questionTitleValue;
481 + } else {
482 + elQuestionTitleInput.value = titleOld;
483 + }
484 +
485 + lpToastify.show( message, status );
486 + },
487 + error: ( error ) => {
488 + lpToastify.show( error, 'error' );
489 + },
490 + completed: () => {
491 + lpUtils.lpSetLoadingEl( elQuestionItem, 0 );
492 + elQuestionItem.classList.remove( 'editing' );
493 + },
494 + };
495 +
496 + const dataSend = {
497 + quiz_id: this.quizID,
498 + action: 'update_question',
499 + question_id: questionId,
500 + question_title: questionTitleValue,
501 + args: { id_url: this.idUrlHandle },
502 + };
503 + window.lpAJAXG.fetchAJAX( dataSend, callBack );
504 + }
505 +
506 + changeTitleQuestion( args ) {
507 + const { e, target } = args;
508 + const elQuestionTitleInput = target.closest( `${ EditQuiz.selectors.elQuestionTitleInput }` );
509 + if ( ! elQuestionTitleInput ) {
510 + return;
511 + }
512 +
513 + const elQuestionItem = elQuestionTitleInput.closest( `${ EditQuiz.selectors.elQuestionItem }` );
514 + const titleValue = elQuestionTitleInput.value.trim();
515 + const titleValueOld = elQuestionTitleInput.dataset.old || '';
516 +
517 + if ( titleValue === titleValueOld ) {
518 + elQuestionItem.classList.remove( 'editing' );
519 + } else {
520 + elQuestionItem.classList.add( 'editing' );
521 + }
522 + }
523 +
524 + cancelChangeTitleQuestion( args ) {
525 + const { e, target } = args;
526 + const elBtnCancelUpdateQuestionTitle = target.closest( `${ EditQuiz.selectors.elBtnCancelUpdateQuestionTitle }` );
527 + if ( ! elBtnCancelUpdateQuestionTitle ) {
528 + return;
529 + }
530 +
531 + const elQuestionItem = elBtnCancelUpdateQuestionTitle.closest( `${ EditQuiz.selectors.elQuestionItem }` );
532 + const elQuestionTitleInput = elQuestionItem.querySelector( `${ EditQuiz.selectors.elQuestionTitleInput }` );
533 + elQuestionTitleInput.value = elQuestionTitleInput.dataset.old || '';
534 + elQuestionItem.classList.remove( 'editing' );
535 + }
536 +
537 + sortAbleQuestion() {
538 + let isUpdateSectionPosition = 0;
539 + let timeout;
540 +
541 + new Sortable( this.elEditListQuestions, {
542 + handle: '.drag',
543 + animation: 150,
544 + onEnd: ( evt ) => {
545 + const elQuestionItem = evt.item;
546 + if ( ! isUpdateSectionPosition ) {
547 + return;
548 + }
549 +
550 + clearTimeout( timeout );
551 + timeout = setTimeout( () => {
552 + lpUtils.lpSetLoadingEl( elQuestionItem, 1 );
553 +
554 + const questionIds = [];
555 + const elQuestionItems = this.elEditListQuestions.querySelectorAll( `${ EditQuiz.selectors.elQuestionItem }:not(.clone)` );
556 + elQuestionItems.forEach( ( elItem ) => {
557 + const questionId = elItem.dataset.questionId;
558 + if ( questionId ) {
559 + questionIds.push( questionId );
560 + }
561 + } );
562 +
563 + const callBack = {
564 + success: ( response ) => {
565 + const { message, status } = response;
566 +
567 + if ( status === 'success' ) {
568 + lpToastify.show( message, status );
569 + editQuestion.initTinyMCE();
570 + } else {
571 + throw `Error: ${ message }`;
572 + }
573 + },
574 + error: ( error ) => {
575 + lpToastify.show( error, 'error' );
576 + },
577 + completed: () => {
578 + lpUtils.lpSetLoadingEl( elQuestionItem, 0 ); isUpdateSectionPosition = 0;
579 + },
580 + };
581 +
582 + const dataSend = { quiz_id: this.quizID, action: 'update_questions_position', question_ids: questionIds, args: { id_url: this.idUrlHandle } };
583 + window.lpAJAXG.fetchAJAX( dataSend, callBack );
584 + }, 1000 );
585 + },
586 + onMove: () => {
587 + clearTimeout( timeout );
588 + },
589 + onUpdate: () => {
590 + isUpdateSectionPosition = 1;
591 + },
592 + } );
593 + }
594 +}
595 +
596 +const editQuiz = new EditQuiz();
597 +editQuiz.init();