# learnpress/4.4.9/assets/src/js/frontend/course-builder/builder-course/builder-tab-course.js

LearnPress – WordPress LMS Plugin for Create and Sell Online Courses, version 4.4.9. 408 lines.

- Page: https://pluginprobe.com/plugins/learnpress/4.4.9/code/assets/src/js/frontend/course-builder/builder-course/builder-tab-course.js
- Raw: https://pluginprobe.com/plugins/learnpress/4.4.9/raw/assets/src/js/frontend/course-builder/builder-course/builder-tab-course.js
- Modified: 2026-09-27T10:32:46+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/learnpress/4.4.9/code/assets/src/js/frontend/course-builder/builder-course/builder-tab-course.js#L10-L20`.

```javascript
import * as lpUtils from 'lpAssetsJsPath/utils.js';
import SweetAlert from 'sweetalert2';
import * as lpToastify from 'lpAssetsJsPath/lpToastify.js';
import { SWAL_ICON_DELETE, SWAL_ICON_DUPLICATE, SWAL_ICON_TRASH_DRAFT } from '../swal-icons.js';

export class BuilderTabCourse {
	constructor() {
		this.init();
	}

	static selectors = {
		elBtnCreateCourse: 'a.cb-btn-add-new[href]',
		elCourseItem: '.course-item',
		elCourseExpandedItems: '.course-action-expanded__items',
		elCourseDuplicate: '.course-action-expanded__duplicate',
		elCourseTrash: '.course-action-expanded__trash',
		elCourseDraft: '.course-action-expanded__draft',
		elCourseDelete: '.course-action-expanded__delete',
		elCourseActionExpanded: '.course-action-expanded',
		elCourseStatus: '.course-status',
	};

	init() {
		this.events();
	}

	events() {
		if ( BuilderTabCourse._loadedEvents ) {
			return;
		}
		BuilderTabCourse._loadedEvents = true;

		lpUtils.eventHandlers( 'click', [
			{
				selector: BuilderTabCourse.selectors.elCourseDuplicate,
				class: this,
				callBack: this.duplicateCourse.name,
			},
			{
				selector: BuilderTabCourse.selectors.elCourseTrash,
				class: this,
				callBack: this.trashCourse.name,
			},
			{
				selector: BuilderTabCourse.selectors.elCourseDraft,
				class: this,
				callBack: this.draftCourse.name,
			},
			{
				selector: BuilderTabCourse.selectors.elCourseDelete,
				class: this,
				callBack: this.deleteCourse.name,
			},
			{
				selector: BuilderTabCourse.selectors.elCourseActionExpanded,
				class: this,
				callBack: this.toggleExpandedAction.name,
			},
			{
				selector: BuilderTabCourse.selectors.elBtnCreateCourse,
				callBack: ( args ) => {
					const { target } = args;
					const elBtnCreateCourse = target.closest(
						BuilderTabCourse.selectors.elBtnCreateCourse
					);

					if ( ! elBtnCreateCourse ) {
						return;
					}

					lpUtils.lpSetLoadingEl( elBtnCreateCourse, 1 );
				},
			},
		] );

		document.addEventListener( 'click', ( e ) => {
			if ( ! e.target.closest( BuilderTabCourse.selectors.elCourseActionExpanded ) ) {
				this.closeAllExpanded();
			}
		} );
	}

	duplicateCourse( args ) {
		const { target } = args;
		const elCourseDuplicate = target.closest( BuilderTabCourse.selectors.elCourseDuplicate );
		const elCourseItem = elCourseDuplicate.closest( BuilderTabCourse.selectors.elCourseItem );

		if ( ! elCourseItem ) {
			return;
		}

		const courseId = elCourseItem.dataset.courseId || '';

		if ( ! courseId ) {
			return;
		}

		SweetAlert.fire( {
			title: elCourseDuplicate.dataset.title || 'Duplicate Course',
			text: elCourseDuplicate.dataset.content || 'Are you sure you want to duplicate this course?',
			iconHtml: SWAL_ICON_DUPLICATE,
			customClass: { icon: 'lp-cb-swal-icon-html' },
			showCloseButton: true,
			showCancelButton: true,
			cancelButtonText: lpData.i18n.cancel,
			confirmButtonText: lpData.i18n.yes,
			reverseButtons: true,
		} ).then( ( result ) => {
			if ( result.isConfirmed ) {
				lpUtils.lpSetLoadingEl( elCourseDuplicate, 1 );

				const dataSend = {
					action: 'duplicate_course',
					args: { id_url: 'duplicate-course' },
					course_id: courseId,
				};

				const callBack = {
					success: ( response ) => {
						const { status, message, data } = response;
						lpToastify.show( message || 'Duplicated successfully!', status );

						if ( data?.html ) {
							const elCourse = elCourseDuplicate.closest( '.course' );
							const elCourseList = elCourse.closest( '.courses-list' ) || elCourse.parentElement;

							if ( elCourseList ) {
								elCourseList.insertAdjacentHTML( 'afterbegin', data.html );
								const newCourse = elCourseList.firstElementChild;

								if ( newCourse ) {
									newCourse.scrollIntoView( { behavior: 'smooth', block: 'nearest' } );
									newCourse.classList.add( 'highlight-new-course' );
									setTimeout( () => {
										newCourse.classList.remove( 'highlight-new-course' );
									}, 1500 );
								}
							}
						}
					},
					error: ( error ) => {
						lpToastify.show( error.message || error, 'error' );
					},
					completed: () => {
						lpUtils.lpSetLoadingEl( elCourseDuplicate, 0 );
					},
				};

				window.lpAJAXG.fetchAJAX( dataSend, callBack );
			}
		} );
	}

	trashCourse( args ) {
		const { target } = args;
		const elCourseTrash = target.closest( BuilderTabCourse.selectors.elCourseTrash );
		const elCourseItem = elCourseTrash.closest( BuilderTabCourse.selectors.elCourseItem );

		if ( ! elCourseItem ) {
			return;
		}

		const courseId = elCourseItem.dataset.courseId || '';

		SweetAlert.fire( {
			title: elCourseTrash.dataset.title || 'Trash Course',
			text: elCourseTrash.dataset.content || 'Are you sure you want to move this course to trash?',
			iconHtml: SWAL_ICON_TRASH_DRAFT,
			customClass: { icon: 'lp-cb-swal-icon-html' },
			showCloseButton: true,
			showCancelButton: true,
			cancelButtonText: lpData.i18n.cancel,
			confirmButtonText: lpData.i18n.yes,
			reverseButtons: true,
		} ).then( ( result ) => {
			if ( result.isConfirmed ) {
				lpUtils.lpSetLoadingEl( elCourseTrash, 1 );

				const dataSend = {
					action: 'move_trash_course',
					args: { id_url: 'move-trash-course' },
					course_id: courseId,
				};

				const callBack = {
					success: ( response ) => {
						const { status, message, data } = response;
						lpToastify.show( message, status );

						if ( data?.status ) {
							const elCourse = elCourseTrash.closest( '.course' );
							this.updateStatusUI( elCourse, data.status );
						}
					},
					error: ( error ) => {
						lpToastify.show( error.message || error, 'error' );
					},
					completed: () => {
						lpUtils.lpSetLoadingEl( elCourseTrash, 0 );
					},
				};

				window.lpAJAXG.fetchAJAX( dataSend, callBack );
			}
		} );
	}

	draftCourse( args ) {
		const { target } = args;
		const elCourseDraft = target.closest( BuilderTabCourse.selectors.elCourseDraft );
		const elCourseItem = elCourseDraft.closest( BuilderTabCourse.selectors.elCourseItem );

		if ( ! elCourseItem ) {
			return;
		}

		// Check if published to show confirm unpublish modal
		const statusEl = elCourseItem.querySelector( BuilderTabCourse.selectors.elCourseStatus );
		const isPublished = statusEl && statusEl.classList.contains( 'publish' );
		if ( isPublished ) {
			const confirmMsg =
				elCourseDraft.dataset.confirmUnpublish ||
				'Saving as draft will unpublish this item. Are you sure?';

			SweetAlert.fire( {
				title: 'Draft Course',
				text: confirmMsg,
				iconHtml: SWAL_ICON_TRASH_DRAFT,
				customClass: { icon: 'lp-cb-swal-icon-html' },
				showCloseButton: true,
				showCancelButton: true,
				cancelButtonText: lpData.i18n.cancel,
				confirmButtonText: lpData.i18n.yes,
				reverseButtons: true,
			} ).then( ( result ) => {
				if ( result.isConfirmed ) {
					this.draftCourseExecute( elCourseDraft, elCourseItem );
				}
			} );
			return;
		}

		this.draftCourseExecute( elCourseDraft, elCourseItem );
	}

	draftCourseExecute( elCourseDraft, elCourseItem ) {
		lpUtils.lpSetLoadingEl( elCourseDraft, 1 );

		const courseId = elCourseItem.dataset.courseId || '';

		const dataSend = {
			action: 'move_trash_course',
			args: { id_url: 'move-trash-course' },
			course_id: courseId || 0,
			status: 'draft',
		};

		const callBack = {
			success: ( response ) => {
				const { status, message, data } = response;
				lpToastify.show( message, status );

				if ( data?.status ) {
					const elCourse = elCourseDraft.closest( '.course' );
					this.updateStatusUI( elCourse, data.status );
				}
			},
			error: ( error ) => {
				lpToastify.show( error.message || error, 'error' );
			},
			completed: () => {
				lpUtils.lpSetLoadingEl( elCourseDraft, 0 );
			},
		};

		window.lpAJAXG.fetchAJAX( dataSend, callBack );
	}

	deleteCourse( args ) {
		const { target } = args;
		const elCourseDelete = target.closest( BuilderTabCourse.selectors.elCourseDelete );
		const elCourseItem = elCourseDelete.closest( BuilderTabCourse.selectors.elCourseItem );

		if ( ! elCourseItem ) {
			return;
		}

		const courseId = elCourseItem.dataset.courseId || '';

		if ( ! courseId ) {
			return;
		}

		SweetAlert.fire( {
			title: elCourseDelete.dataset.title || 'Delete Course',
			text:
				elCourseDelete.dataset.content ||
				'Are you sure you want to permanently delete this course?',
			iconHtml: SWAL_ICON_DELETE,
			customClass: { icon: 'lp-cb-swal-icon-html' },
			showCloseButton: true,
			showCancelButton: true,
			cancelButtonText: lpData.i18n.cancel,
			confirmButtonText: lpData.i18n.yes,
			reverseButtons: true,
		} ).then( ( result ) => {
			if ( result.isConfirmed ) {
				const dataSend = {
					action: 'move_trash_course',
					args: { id_url: 'move-trash-course' },
					course_id: courseId,
					status: 'delete',
				};

				const callBack = {
					success: ( response ) => {
						const { status, message } = response;
						lpToastify.show( message, status );
						const elCourse = elCourseDelete.closest( '.course' );

						elCourse.style.transition = 'opacity 0.4s ease-out, transform 0.4s ease-out';
						elCourse.style.opacity = '0';
						elCourse.style.transform = 'translateX(160px)';

						setTimeout( () => {
							elCourse.remove();
						}, 400 );
					},
					error: ( error ) => {
						lpToastify.show( error.message || error, 'error' );
					},
				};

				window.lpAJAXG.fetchAJAX( dataSend, callBack );
			}
		} );
	}

	toggleExpandedAction( args ) {
		const { target } = args;
		const elCourseActionExpanded = target.closest(
			BuilderTabCourse.selectors.elCourseActionExpanded
		);

		if ( ! elCourseActionExpanded ) {
			return;
		}

		const elCourseItem = elCourseActionExpanded.closest( BuilderTabCourse.selectors.elCourseItem );

		if ( ! elCourseItem ) {
			return;
		}

		const elExpandedItems = elCourseItem.querySelector(
			BuilderTabCourse.selectors.elCourseExpandedItems
		);

		if ( ! elExpandedItems ) {
			return;
		}

		// Close others
		this.closeAllExpanded( elExpandedItems );

		elExpandedItems.classList.toggle( 'active' );
		elCourseActionExpanded.classList.toggle( 'active' );
	}

	closeAllExpanded( excludeElement = null ) {
		const allExpandedItems = document.querySelectorAll(
			`${ BuilderTabCourse.selectors.elCourseExpandedItems }.active`
		);

		allExpandedItems.forEach( ( item ) => {
			if ( item === excludeElement ) {
				return;
			}

			item.classList.remove( 'active' );

			const courseItem = item.closest( BuilderTabCourse.selectors.elCourseItem );

			if ( ! courseItem ) {
				return;
			}

			const expandedBtn = courseItem.querySelector(
				BuilderTabCourse.selectors.elCourseActionExpanded
			);
			if ( expandedBtn ) {
				expandedBtn.classList.remove( 'active' );
			}
		} );
	}

	updateStatusUI( elCourse, status ) {
		const elStatus = elCourse.querySelector( BuilderTabCourse.selectors.elCourseStatus );
		const elSpanStatus = elCourse.querySelector(
			`${ BuilderTabCourse.selectors.elCourseStatus } span`
		);
		if ( elSpanStatus && elStatus ) {
			elStatus.className = 'course-status ' + status;
			elSpanStatus.textContent = status;
		}
	}
}

```
