PluginProbe
UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP / trunk
UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP vtrunk
1.2.72 1.2.71 1.2.70 1.2.69 1.2.68 1.2.67 1.2.66 1.2.65 1.2.64 1.2.63 trunk 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.23 All 172 releases
userswp / admin / assets / js / users-wp-admin.js

users-wp-admin.js in UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP trunk, at admin/assets/js/users-wp-admin.js

578 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function ($) {
2 'use strict';
3
4 window.UWP = window.UWP || {};
5
6 UWP.Admin = {
7 mediaFrames: [],
8
9 init: function () {
10 this.initColorPicker();
11 this.initImageUploader();
12 this.initFormHandlers();
13 this.initMiscHandlers();
14 this.initTooltips();
15 this.initFormControls();
16 this.initUserTypesReorder();
17 },
18
19 /**
20 * Toggle button loading state
21 *
22 * @param {jQuery} element Button element
23 * @param {string} handle State to set ('loading' or 'reset')
24 */
25 buttonStatus: function (element, handle) {
26 if (handle === "loading") {
27 element.data('text', element.html());
28 element.prop('disabled', true);
29 element.html('<i class="fas fa-circle-notch fa-spin ml-2"></i> <span>Loading...</span>');
30 } else {
31 element.prop('disabled', false);
32 element.html(element.data('text'));
33 }
34 },
35
36 /**
37 * Initialize color picker functionality
38 */
39 initColorPicker: function () {
40 const $colorPicker = $('.uwp-color-picker');
41 if ($colorPicker.length) {
42 $colorPicker.wpColorPicker();
43 }
44 },
45
46 /**
47 * Initialize image uploader functionality
48 */
49 initImageUploader: function () {
50 const self = this;
51
52 // Initialize remove button visibility
53 $('.uwp-upload-img').each(function () {
54 const $wrap = $(this);
55 const field = $wrap.data('field');
56 if ($(`[name="${field}[id]"]`).length && !$(`[name="${field}[id]"]`).val()) {
57 $('.uwp_remove_image_button', $wrap).hide();
58 }
59 });
60
61 // Upload button handler
62 $(document).on('click', '.uwp_upload_image_button', function (e) {
63 e.preventDefault();
64 self.handleImageUpload($(this));
65 });
66
67 // Remove button handler
68 $(document).on('click', '.uwp_remove_image_button', function () {
69 self.handleImageRemove($(this));
70 return false;
71 });
72 },
73
74 /**
75 * Handle image upload process
76 * @param {jQuery} $button Upload button element
77 */
78 handleImageUpload: function ($button) {
79 const $wrap = $button.closest('.uwp-upload-img');
80 const field = $wrap.data('field');
81
82 if (!field) return;
83
84 if (this.mediaFrames[field]) {
85 this.mediaFrames[field].open();
86 return;
87 }
88
89 this.mediaFrames[field] = wp.media({
90 title: uwp_admin_ajax.txt_choose_image,
91 button: {
92 text: uwp_admin_ajax.txt_use_image
93 },
94 multiple: false
95 });
96
97 this.mediaFrames[field].on('select', function () {
98 const attachment = this.mediaFrames[field].state().get('selection').first().toJSON();
99 const thumbnail = attachment.sizes.medium || attachment.sizes.full;
100
101 if (field) {
102 $(`[name="${field}[id]"]`).val(attachment.id);
103 $(`[name="${field}[src]"]`).val(attachment.url);
104 $(`[name="${field}"]`).val(attachment.id);
105 }
106
107 $wrap.closest('.form-field.form-invalid').removeClass('form-invalid');
108 $('.uwp-upload-display', $wrap).find('img')
109 .attr('src', thumbnail.url);
110 $('.uwp_remove_image_button').show();
111 }.bind(this));
112
113 this.mediaFrames[field].open();
114 },
115
116 /**
117 * Handle image removal
118 * @param {jQuery} $button Remove button element
119 */
120 handleImageRemove: function ($button) {
121 const $wrap = $button.closest('.uwp-upload-img');
122 const field = $wrap.data('field');
123
124 $('.uwp-upload-display', $wrap).find('img')
125 .attr('src', uwp_admin_ajax.img_spacer)
126 .removeAttr('width height sizes alt class srcset');
127
128 if (field) {
129 $(`[name="${field}[id]"]`).val('');
130 $(`[name="${field}[src]"]`).val('');
131 $(`[name="${field}"]`).val('');
132 }
133
134 $button.hide();
135 },
136
137 /**
138 * Initialize form related handlers
139 */
140 initFormHandlers: function () {
141 const self = this;
142
143 // Handle large text inputs
144 $('.userswp .forminp .large-text').on({
145 focus: function () {
146 const $this = $(this);
147 const placeholder = $this.attr('placeholder');
148 if ($this.val() === '') {
149 $this.val(placeholder);
150 }
151 },
152 blur: function () {
153 const $this = $(this);
154 const placeholder = $this.attr('placeholder');
155 if ($this.val() === placeholder) {
156 $this.val('');
157 }
158 }
159 });
160
161 // Handle register form submission
162 $('#uwp_user_type_form').on('submit', function (e) {
163 self.handleRegisterFormSubmit(e, $(this));
164 });
165
166 // Handle register form removal
167 $(document).on('click', '.register-form-remove', function (e) {
168 self.handleRegisterFormRemove($(this));
169 });
170 },
171
172 /**
173 * Handle register form submission
174 * @param {Event} e Submit event
175 * @param {jQuery} $form Form element
176 */
177 handleRegisterFormSubmit: function (e, $form) {
178 e.preventDefault();
179 const { __ } = wp.i18n;
180 const self = this;
181 const error = $form.find('.alert.alert-danger');
182 const success = $form.find('.alert.alert-success');
183 const action = $form.find('[name="action"]').val() || 'edit';
184 const ajaxAction = action === 'edit' ? 'uwp_ajax_update_register' : 'uwp_ajax_create_register';
185 const data = $form.serialize() + `&action=${ajaxAction}&type=update`;
186 const $button = $("button[type=submit]", $form);
187
188 const formTitleInput = $form.find('[name="form_title"]');
189
190 formTitleInput.on('input', function () {
191 if ($(this).hasClass('is-invalid')) {
192 $(this).removeClass('is-invalid');
193 }
194 });
195
196 if (formTitleInput.val() === '') {
197 formTitleInput.addClass('is-invalid');
198 formTitleInput.next('.invalid-feedback').text(__('Form title is required.', 'userswp'));
199 return;
200 } else {
201 formTitleInput.removeClass('is-invalid');
202 }
203
204 self.buttonStatus($button, 'loading');
205
206 $.post(uwp_admin_ajax.url, data, (response) => {
207 self.buttonStatus($button, 'reset');
208
209 if (response.success === false) {
210 this.handleError(error, success, response.data.message);
211 } else if (response.success) {
212 this.handleSuccess(error, success, response.data.message);
213
214 if (response.data.redirect) {
215 setTimeout(() => {
216 window.location.replace(response.data.redirect);
217 }, 1000);
218 }
219 }
220 }, "json")
221 .fail(() => {
222 self.buttonStatus($button, "reset");
223 self.handleError(error, success, __('There is something that went wrong!', 'userswp'));
224 });
225 },
226
227 /**
228 * Handle error response.
229 *
230 * @param {jQuery} error Error element
231 * @param {jQuery} success Success element
232 * @param {string} message Error message
233 */
234 handleError: function (error, success, message) {
235 if (success.is(":visible")) success.addClass('d-none');
236 error.html(message).removeClass('d-none').slideDown();
237 },
238
239 /**
240 * Handle success response.
241 *
242 * @param {jQuery} error Error element
243 * @param {jQuery} success Success element
244 * @param {string} message Error message
245 */
246 handleSuccess: function (error, success, message) {
247 if (error.is(":visible")) error.addClass('d-none');
248 success.html(message).removeClass('d-none').slideDown();
249 },
250
251 /**
252 * Handle register form removal
253 * @param {jQuery} $button Remove button element
254 */
255 handleRegisterFormRemove: function ($button) {
256 const self = this;
257 const formId = $button.attr('data-id');
258
259 self.buttonStatus($button, 'loading');
260
261 const confirmation = confirm(uwp_admin_ajax.delete_register_form);
262
263 if (confirmation) {
264 const data = {
265 'action': 'uwp_ajax_remove_user_type',
266 'type': 'remove',
267 'form_id': formId,
268 'nonce': uwp_admin_ajax.nonces.uwp_delete_user_type
269 };
270
271 $.post(uwp_admin_ajax.url, data, function (response) {
272 if (response.status) {
273 window.location.replace(response.redirect);
274 }
275
276 self.buttonStatus($button, 'reset');
277 });
278 } else {
279 self.buttonStatus($button, 'reset');
280 }
281 },
282
283 /**
284 * Initialize miscellaneous handlers
285 */
286 initMiscHandlers: function () {
287 // Code copy handler
288 $(document).on('click', '.userswp span code', function () {
289 const $code = $(this);
290 $('.userswp span code').removeClass('uwp-tag-copied').find('span').remove();
291 $code.addClass('uwp-tag-copied').append('<span></span>');
292
293 const $temp = $("<input>");
294 $("body").append($temp);
295 $temp.val($code.text()).select();
296 document.execCommand("copy");
297 $temp.remove();
298
299 setTimeout(function () {
300 $('.userswp span code').removeClass('uwp-tag-copied').find('span').remove();
301 }, 1000);
302 });
303
304 // SEO meta separator handler
305 $('input.uwp-seo-meta-separator').on('change', function () {
306 if ($(this).attr("checked") === "checked") {
307 $('input.uwp-seo-meta-separator').parent().removeClass('active');
308 $(this).parent().addClass('active');
309 }
310 }).change();
311
312 // Font Awesome select handler
313 $(".aui-fa-select2").select2({
314 templateResult: this.formatFaSelect,
315 templateSelection: this.formatFaSelection,
316 escapeMarkup: function (m) {
317 return m;
318 }
319 });
320
321 // Register options toggle
322 $(document).on('click', '.register-show-options', function () {
323 $("#uwp-form-more-options").toggle("fast");
324 });
325 },
326
327 /**
328 * Initialize user types reordering functionality
329 */
330 initUserTypesReorder: function () {
331 const table = $('.wp-list-table.usertypes tbody, .wp-list-table.membershiptypes tbody');
332 table.length && table.sortable({
333 handle: '.uwp-user-type-handle',
334 axis: 'y',
335 helper: function (e, ui) {
336 ui.children().each(function () {
337 $(this).width($(this).width());
338 });
339 ui.addClass('uwp-dragging');
340 return ui;
341 },
342 start: function(e, ui) {
343 ui.placeholder.addClass('uwp-drag-placeholder');
344 },
345 stop: function(e, ui) {
346 ui.item.removeClass('uwp-dragging');
347 table.find('.uwp-drag-placeholder').removeClass('uwp-drag-placeholder');
348 },
349 update: function (event, ui) {
350 const order = table.find('input[name="user_types[]"]').map(function () {
351 return $(this).val();
352 }).get();
353
354 $.ajax({
355 url: uwp_admin_ajax.url,
356 type: 'POST',
357 data: {
358 action: 'uwp_ajax_reorder_user_types',
359 order: order,
360 nonce: uwp_admin_ajax.nonces.uwp_reorder_user_types
361 },
362 success: function (response) {
363 if (response.success) {
364 aui_toast('uwp_reorder_user_types_success', 'success', uwp_admin_ajax.txt_saved);
365 } else {
366 aui_toast('uwp_reorder_user_types_error', 'error', uwp_admin_ajax.txt_saving_error);
367 }
368 },
369 error: function () {
370 aui_toast('uwp_reorder_user_types_error', 'error', uwp_admin_ajax.txt_saving_error);
371 }
372 });
373 }
374 });
375 },
376
377 /**
378 * Display an admin notice
379 *
380 * @param {string} message The message to display
381 * @param {string} type The notice type ('success' or 'error')
382 */
383 showNotice: function (message, type) {
384 const noticeClass = type === 'success' ? 'notice-success' : 'notice-error';
385 const $notice = $(`<div class="notice ${noticeClass} is-dismissible"><p>${message}</p></div>`);
386 $notice.insertAfter('.wp-header-end');
387
388 // Auto-dismiss after 3 seconds
389 setTimeout(function () {
390 $notice.fadeOut(300, function () { $(this).remove(); });
391 }, 3000);
392 },
393
394 /**
395 * Initialize form control handlers
396 */
397 initFormControls: function () {
398 this.initSectionToggles();
399 this.initAdvancedSettings();
400 },
401
402 /**
403 * Initialize section toggle handlers
404 */
405 initSectionToggles: function () {
406 $(document).on('click', '.toggle-arrow', (e) => {
407 this.handleSectionToggle($(e.currentTarget));
408 });
409 },
410
411 /**
412 * Initialize advanced settings toggle
413 */
414 initAdvancedSettings: function () {
415 const $advancedToggle = $('.uwp-advanced-toggle');
416 const $advancedElements = $('.uwp-advanced-setting, #default_location_set_address_button');
417
418 $advancedToggle
419 .off('click')
420 .on('click', function () {
421 $advancedToggle.toggleClass('uwpa-hide');
422 $advancedElements.toggleClass('uwpa-show');
423 $advancedElements.collapse('toggle');
424 });
425 },
426
427 /**
428 * Handle section toggle visibility
429 * @param {jQuery} $toggleElement The clicked toggle element
430 */
431 handleSectionToggle: function ($toggleElement) {
432 const $parentSettings = $toggleElement.parent('.li-settings');
433 const $currentForm = $parentSettings.find('.field_frm').first();
434 const isOpen = !$currentForm.is(':hidden');
435
436 // Hide all forms and reset all arrows
437 $('.field_frm').hide();
438 $('.toggle-arrow')
439 .addClass('fa-caret-down')
440 .removeClass('fa-caret-up');
441
442 if (isOpen) {
443 // Close current section
444 $toggleElement
445 .addClass('fa-caret-down')
446 .removeClass('fa-caret-up');
447 $currentForm
448 .hide()
449 .removeClass('uwp-tab-settings-open');
450 } else {
451 // Open current section
452 $toggleElement
453 .addClass('fa-caret-up')
454 .removeClass('fa-caret-down');
455 $currentForm
456 .show()
457 .addClass('uwp-tab-settings-open');
458 }
459 },
460
461 /**
462 * Handle radio button visibility changes
463 * @param {string} elementId The ID of the radio element
464 * @param {string} showHide Show/hide parameter (unused but kept for backwards compatibility)
465 * @param {string} className The class to toggle visibility on
466 */
467 handleRadioVisibility: function (elementId, showHide, className) {
468 setTimeout(() => {
469 const $element = $(elementId);
470 const $targetElement = $element.closest('.li-settings').find('.' + className);
471 const isChecked = $element.is(':checked');
472
473 $targetElement.toggle(isChecked ? 'fast' : 'fast');
474 }, 100);
475 },
476
477 /**
478 * Format Font Awesome select option
479 * @param {Object} option Select option
480 * @returns {string} Formatted option HTML
481 */
482 formatFaSelect: function (option) {
483 if (!option.id) {
484 return option.text;
485 }
486 const icon = $(option.element).attr('data-fa-icon');
487 return '<i class="fa-lg ' + icon + '"></i> ' + option.text;
488 },
489
490 /**
491 * Format Font Awesome selected option
492 * @param {Object} option Selected option
493 * @returns {string} Formatted option HTML
494 */
495 formatFaSelection: function (option) {
496 if (option.id.length > 0) {
497 const icon = $(option.element).attr('data-fa-icon');
498 return "<i class='fa-lg " + icon + "'></i> " + option.text;
499 }
500 return option.text;
501 },
502
503 /**
504 * Initialize tooltips
505 */
506 initTooltips: function () {
507 const $tooltips = $('.uwp-help-tip').tooltip();
508 const method = this.getTooltipVersion() >= 4 ? 'dispose' : 'destroy';
509
510 $tooltips.tooltip(method).tooltip({
511 content: function () {
512 return $(this).prop('title');
513 },
514 tooltipClass: 'uwp-ui-tooltip',
515 position: {
516 my: 'center top',
517 at: 'center bottom+10',
518 collision: 'flipfit'
519 },
520 show: null,
521 close: function (event, ui) {
522 ui.tooltip.hover(
523 function () {
524 $(this).stop(true).fadeTo(400, 1);
525 },
526 function () {
527 $(this).fadeOut("400", function () {
528 $(this).remove();
529 });
530 }
531 );
532 }
533 });
534 },
535
536 /**
537 * Get Bootstrap tooltip version
538 * @returns {number} Tooltip version number
539 */
540 getTooltipVersion: function () {
541 let version = 0;
542 if (typeof $.fn === 'object' &&
543 typeof $.fn.tooltip === 'function' &&
544 typeof $.fn.tooltip.Constructor === 'function' &&
545 typeof $.fn.tooltip.Constructor.VERSION !== 'undefined') {
546 version = parseFloat($.fn.tooltip.Constructor.VERSION);
547 }
548 return version;
549 },
550 };
551
552 // Global function mappings for backward compatibility
553 window.uwp_show_hide = function ($element) {
554 UWP.Admin.handleSectionToggle($($element));
555 };
556
557 window.uwp_show_hide_radio = function (id, sh, cl) {
558 UWP.Admin.handleRadioVisibility(id, sh, cl);
559 };
560
561 window.uwp_init_advanced_settings = function () {
562 UWP.Admin.initAdvancedSettings();
563 };
564
565 window.uwp_init_tooltips = function () {
566 UWP.Admin.initTooltips();
567 };
568
569 window.uwp_tooltip_version = function () {
570 return UWP.Admin.getTooltipVersion();
571 };
572
573 // Initialize when document is ready
574 $(document).ready(function () {
575 UWP.Admin.init();
576 });
577
578 })(jQuery);