(function ($) { 'use strict'; window.UWP = window.UWP || {}; UWP.Admin = { mediaFrames: [], init: function () { this.initColorPicker(); this.initImageUploader(); this.initFormHandlers(); this.initMiscHandlers(); this.initTooltips(); this.initFormControls(); this.initUserTypesReorder(); }, /** * Toggle button loading state * * @param {jQuery} element Button element * @param {string} handle State to set ('loading' or 'reset') */ buttonStatus: function (element, handle) { if (handle === "loading") { element.data('text', element.html()); element.prop('disabled', true); element.html(' Loading...'); } else { element.prop('disabled', false); element.html(element.data('text')); } }, /** * Initialize color picker functionality */ initColorPicker: function () { const $colorPicker = $('.uwp-color-picker'); if ($colorPicker.length) { $colorPicker.wpColorPicker(); } }, /** * Initialize image uploader functionality */ initImageUploader: function () { const self = this; // Initialize remove button visibility $('.uwp-upload-img').each(function () { const $wrap = $(this); const field = $wrap.data('field'); if ($(`[name="${field}[id]"]`).length && !$(`[name="${field}[id]"]`).val()) { $('.uwp_remove_image_button', $wrap).hide(); } }); // Upload button handler $(document).on('click', '.uwp_upload_image_button', function (e) { e.preventDefault(); self.handleImageUpload($(this)); }); // Remove button handler $(document).on('click', '.uwp_remove_image_button', function () { self.handleImageRemove($(this)); return false; }); }, /** * Handle image upload process * @param {jQuery} $button Upload button element */ handleImageUpload: function ($button) { const $wrap = $button.closest('.uwp-upload-img'); const field = $wrap.data('field'); if (!field) return; if (this.mediaFrames[field]) { this.mediaFrames[field].open(); return; } this.mediaFrames[field] = wp.media({ title: uwp_admin_ajax.txt_choose_image, button: { text: uwp_admin_ajax.txt_use_image }, multiple: false }); this.mediaFrames[field].on('select', function () { const attachment = this.mediaFrames[field].state().get('selection').first().toJSON(); const thumbnail = attachment.sizes.medium || attachment.sizes.full; if (field) { $(`[name="${field}[id]"]`).val(attachment.id); $(`[name="${field}[src]"]`).val(attachment.url); $(`[name="${field}"]`).val(attachment.id); } $wrap.closest('.form-field.form-invalid').removeClass('form-invalid'); $('.uwp-upload-display', $wrap).find('img') .attr('src', thumbnail.url); $('.uwp_remove_image_button').show(); }.bind(this)); this.mediaFrames[field].open(); }, /** * Handle image removal * @param {jQuery} $button Remove button element */ handleImageRemove: function ($button) { const $wrap = $button.closest('.uwp-upload-img'); const field = $wrap.data('field'); $('.uwp-upload-display', $wrap).find('img') .attr('src', uwp_admin_ajax.img_spacer) .removeAttr('width height sizes alt class srcset'); if (field) { $(`[name="${field}[id]"]`).val(''); $(`[name="${field}[src]"]`).val(''); $(`[name="${field}"]`).val(''); } $button.hide(); }, /** * Initialize form related handlers */ initFormHandlers: function () { const self = this; // Handle large text inputs $('.userswp .forminp .large-text').on({ focus: function () { const $this = $(this); const placeholder = $this.attr('placeholder'); if ($this.val() === '') { $this.val(placeholder); } }, blur: function () { const $this = $(this); const placeholder = $this.attr('placeholder'); if ($this.val() === placeholder) { $this.val(''); } } }); // Handle register form submission $('#uwp_user_type_form').on('submit', function (e) { self.handleRegisterFormSubmit(e, $(this)); }); // Handle register form removal $(document).on('click', '.register-form-remove', function (e) { self.handleRegisterFormRemove($(this)); }); }, /** * Handle register form submission * @param {Event} e Submit event * @param {jQuery} $form Form element */ handleRegisterFormSubmit: function (e, $form) { e.preventDefault(); const { __ } = wp.i18n; const self = this; const error = $form.find('.alert.alert-danger'); const success = $form.find('.alert.alert-success'); const action = $form.find('[name="action"]').val() || 'edit'; const ajaxAction = action === 'edit' ? 'uwp_ajax_update_register' : 'uwp_ajax_create_register'; const data = $form.serialize() + `&action=${ajaxAction}&type=update`; const $button = $("button[type=submit]", $form); const formTitleInput = $form.find('[name="form_title"]'); formTitleInput.on('input', function () { if ($(this).hasClass('is-invalid')) { $(this).removeClass('is-invalid'); } }); if (formTitleInput.val() === '') { formTitleInput.addClass('is-invalid'); formTitleInput.next('.invalid-feedback').text(__('Form title is required.', 'userswp')); return; } else { formTitleInput.removeClass('is-invalid'); } self.buttonStatus($button, 'loading'); $.post(uwp_admin_ajax.url, data, (response) => { self.buttonStatus($button, 'reset'); if (response.success === false) { this.handleError(error, success, response.data.message); } else if (response.success) { this.handleSuccess(error, success, response.data.message); if (response.data.redirect) { setTimeout(() => { window.location.replace(response.data.redirect); }, 1000); } } }, "json") .fail(() => { self.buttonStatus($button, "reset"); self.handleError(error, success, __('There is something that went wrong!', 'userswp')); }); }, /** * Handle error response. * * @param {jQuery} error Error element * @param {jQuery} success Success element * @param {string} message Error message */ handleError: function (error, success, message) { if (success.is(":visible")) success.addClass('d-none'); error.html(message).removeClass('d-none').slideDown(); }, /** * Handle success response. * * @param {jQuery} error Error element * @param {jQuery} success Success element * @param {string} message Error message */ handleSuccess: function (error, success, message) { if (error.is(":visible")) error.addClass('d-none'); success.html(message).removeClass('d-none').slideDown(); }, /** * Handle register form removal * @param {jQuery} $button Remove button element */ handleRegisterFormRemove: function ($button) { const self = this; const formId = $button.attr('data-id'); self.buttonStatus($button, 'loading'); const confirmation = confirm(uwp_admin_ajax.delete_register_form); if (confirmation) { const data = { 'action': 'uwp_ajax_remove_user_type', 'type': 'remove', 'form_id': formId, 'nonce': uwp_admin_ajax.nonces.uwp_delete_user_type }; $.post(uwp_admin_ajax.url, data, function (response) { if (response.status) { window.location.replace(response.redirect); } self.buttonStatus($button, 'reset'); }); } else { self.buttonStatus($button, 'reset'); } }, /** * Initialize miscellaneous handlers */ initMiscHandlers: function () { // Code copy handler $(document).on('click', '.userswp span code', function () { const $code = $(this); $('.userswp span code').removeClass('uwp-tag-copied').find('span').remove(); $code.addClass('uwp-tag-copied').append(''); const $temp = $(""); $("body").append($temp); $temp.val($code.text()).select(); document.execCommand("copy"); $temp.remove(); setTimeout(function () { $('.userswp span code').removeClass('uwp-tag-copied').find('span').remove(); }, 1000); }); // SEO meta separator handler $('input.uwp-seo-meta-separator').on('change', function () { if ($(this).attr("checked") === "checked") { $('input.uwp-seo-meta-separator').parent().removeClass('active'); $(this).parent().addClass('active'); } }).change(); // Font Awesome select handler $(".aui-fa-select2").select2({ templateResult: this.formatFaSelect, templateSelection: this.formatFaSelection, escapeMarkup: function (m) { return m; } }); // Register options toggle $(document).on('click', '.register-show-options', function () { $("#uwp-form-more-options").toggle("fast"); }); }, /** * Initialize user types reordering functionality */ initUserTypesReorder: function () { const table = $('.wp-list-table.usertypes tbody, .wp-list-table.membershiptypes tbody'); table.length && table.sortable({ handle: '.uwp-user-type-handle', axis: 'y', helper: function (e, ui) { ui.children().each(function () { $(this).width($(this).width()); }); ui.addClass('uwp-dragging'); return ui; }, start: function(e, ui) { ui.placeholder.addClass('uwp-drag-placeholder'); }, stop: function(e, ui) { ui.item.removeClass('uwp-dragging'); table.find('.uwp-drag-placeholder').removeClass('uwp-drag-placeholder'); }, update: function (event, ui) { const order = table.find('input[name="user_types[]"]').map(function () { return $(this).val(); }).get(); $.ajax({ url: uwp_admin_ajax.url, type: 'POST', data: { action: 'uwp_ajax_reorder_user_types', order: order, nonce: uwp_admin_ajax.nonces.uwp_reorder_user_types }, success: function (response) { if (response.success) { aui_toast('uwp_reorder_user_types_success', 'success', uwp_admin_ajax.txt_saved); } else { aui_toast('uwp_reorder_user_types_error', 'error', uwp_admin_ajax.txt_saving_error); } }, error: function () { aui_toast('uwp_reorder_user_types_error', 'error', uwp_admin_ajax.txt_saving_error); } }); } }); }, /** * Display an admin notice * * @param {string} message The message to display * @param {string} type The notice type ('success' or 'error') */ showNotice: function (message, type) { const noticeClass = type === 'success' ? 'notice-success' : 'notice-error'; const $notice = $(`
${message}