PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 7.9.8
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v7.9.8
8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 7.8.7 All 46 releases
gamipress / assets / js / gamipress.js

gamipress.js in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI 7.9.8, at assets/js/gamipress.js

677 lines 22.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function( $ ) {
2
3 var $body = $( 'body' );
4
5 /**
6 * Achievement list ajax call
7 *
8 * @since 1.0.0
9 * @updated 1.7.9 Added nonce usage
10 */
11 function gamipress_ajax_achievement_list( achievement_list ) {
12
13 // Show the spinner
14 achievement_list.find( '#gamipress-achievements-spinner' ).show();
15
16 var data = {
17 action: 'gamipress_get_achievements',
18 nonce: gamipress.nonce,
19
20 // Achievements atts
21 type: achievement_list.find('input[type="hidden"][name="type"]').val(),
22 limit: achievement_list.find('input[type="hidden"][name="limit"]').val(),
23 current_user: achievement_list.find('input[type="hidden"][name="current_user"]').val(),
24 user_id: achievement_list.find('input[type="hidden"][name="user_id"]').val(),
25 wpms: achievement_list.find('input[type="hidden"][name="wpms"]').val(),
26 offset: achievement_list.find( '#gamipress-achievements-offset' ).val(),
27 count: achievement_list.find( '#gamipress-achievements-count' ).val(),
28 filter: ( ( achievement_list.find( '#achievements_list_filter').length ) ? achievement_list.find('#achievements_list_filter').val() : '' ),
29 search: achievement_list.find('#gamipress-achievements-search-input').val(),
30 orderby: achievement_list.find('input[type="hidden"][name="orderby"]').val(),
31 order: achievement_list.find('input[type="hidden"][name="order"]').val(),
32 include: achievement_list.find('input[type="hidden"][name="include"]').val(),
33 exclude: achievement_list.find('input[type="hidden"][name="exclude"]').val(),
34 showed_ids: []
35 };
36
37 // Single achievement atts
38 for( var i = 0; i < gamipress.achievement_fields.length; i++ ) {
39 var achievement_field = gamipress.achievement_fields[i];
40
41 data[achievement_field] = achievement_list.find('input[type="hidden"][name="' + achievement_field + '"]').val()
42 }
43
44 achievement_list.find('.gamipress-achievement').each(function() {
45 var achievement_id = $(this).attr('id').replace('gamipress-achievement-', '');
46
47 data.showed_ids.push( achievement_id );
48 });
49
50 /**
51 * Allow external functions to add their own data to the array
52 *
53 * @since 1.5.9
54 *
55 * @selector .gamipress-achievements-list
56 * @event gamipress_achievements_list_data
57 *
58 * @param Object data
59 */
60 achievement_list.trigger( 'gamipress_achievements_list_request_data', [ data ] );
61
62 $.ajax( {
63 url: gamipress.ajaxurl,
64 data: data,
65 dataType: 'json',
66 success: function( response ) {
67
68 // Hide the spinner
69 achievement_list.find( '#gamipress-achievements-spinner' ).hide();
70
71 if ( response.data.achievements !== null ) {
72
73 achievement_list.find( '#gamipress-achievements-container' ).append( response.data.achievements );
74 achievement_list.find( '#gamipress-achievements-offset' ).val( response.data.offset );
75 achievement_list.find( '#gamipress-achievements-count' ).val( response.data.achievement_count );
76
77 // Just continue if load more has been enabled
78 if( achievement_list.find( '#gamipress-achievements-load-more').length ) {
79
80 if ( response.data.query_count <= response.data.offset ) {
81
82 // Hide load more button
83 achievement_list.find( '#gamipress-achievements-load-more' ).hide();
84
85 } else {
86
87 // Show load more button
88 achievement_list.find( '#gamipress-achievements-load-more' ).show();
89
90 }
91
92 }
93
94 }
95
96 /**
97 * Allow external functions to add their own functionality
98 *
99 * @since 1.5.9
100 *
101 * @selector .gamipress-achievements-list
102 * @event gamipress_achievements_list_data
103 *
104 * @param Object response
105 */
106 achievement_list.trigger( 'gamipress_achievements_list_request_success', [ response ] );
107 }
108 } );
109 }
110
111 /**
112 * Reset achievements query vars and run an ajax call
113 *
114 * @since 1.0.0
115 */
116 function gamipress_ajax_achievement_list_reset( achievement_list ) {
117 achievement_list.find( '#gamipress-achievements-offset' ).val( 0 );
118 achievement_list.find( '#gamipress-achievements-count' ).val( 0 );
119
120 achievement_list.find( '#gamipress-achievements-container' ).html( '' );
121 achievement_list.find( '#gamipress-achievements-load-more' ).hide();
122
123 gamipress_ajax_achievement_list( achievement_list );
124 }
125
126 /**
127 * Perform an achievements ajax call on change the select filter
128 *
129 * @since 1.0.0
130 */
131 $body.on( 'change', '#achievements_list_filter', function() {
132 gamipress_ajax_achievement_list_reset( $(this).closest('.gamipress-achievements-list') );
133 } );
134
135 /**
136 * Perform an achievements ajax call on submit the search form
137 *
138 * @since 1.0.0
139 */
140 $body.on( 'submit', '#gamipress-achievements-search-form', function( event ) {
141 event.preventDefault();
142
143 gamipress_ajax_achievement_list_reset( $(this).closest('.gamipress-achievements-list') );
144
145 // Disable submit button on submit a search
146 $(this).find('#gamipress-achievements-search-submit').prop('disabled', true);
147 });
148
149 /**
150 * Enable the achievements search button when search input gets the focus
151 *
152 * @since 1.0.0
153 */
154 $body.on( 'focus', '#gamipress-achievements-search-input', function (e) {
155 $(this).closest('.gamipress-achievements-list').find('#gamipress-achievements-search-submit').prop('disabled', false);
156 } );
157
158 /**
159 * Achievements load more button
160 *
161 * @since 1.0.0
162 */
163 $body.on( 'click', '#gamipress-achievements-load-more', function() {
164 gamipress_ajax_achievement_list( $(this).closest('.gamipress-achievements-list') );
165 } );
166
167 /**
168 * Show/hide details link
169 *
170 * @since 1.0.0
171 */
172 $body.on( 'click', '.gamipress-open-close-switch a', function( event ) {
173 event.preventDefault();
174
175 var link = $( this );
176
177 if ( 'close' === link.data( 'action' ) ) {
178 link.parent().siblings( '.gamipress-extras-window' ).slideUp( 300 );
179 link.data( 'action', 'open' ).prop( 'class', 'show-hide-open' ).text( link.data('open-text') );
180 } else {
181 link.parent().siblings( '.gamipress-extras-window' ).slideDown( 300 );
182 link.data( 'action', 'close' ).prop( 'class', 'show-hide-close' ).text( link.data('close-text') );
183 }
184 } );
185
186 /**
187 * Unlock achievement with points
188 *
189 * @since 1.7.8.1
190 * @updated 1.7.9 Added nonce usage
191 */
192 function gamipress_unlock_achievement_with_points( submit_wrap ) {
193
194 var button = submit_wrap.find('.gamipress-achievement-unlock-with-points-button');
195 var spinner = submit_wrap.find('.gamipress-spinner');
196 var achievement_id = submit_wrap.data('id');
197 var confirmation = submit_wrap.find('.gamipress-achievement-unlock-with-points-confirmation');
198
199 // Show the spinner
200 spinner.show();
201
202 /**
203 * Allow external functions to process anything before unlock achievement with points
204 *
205 * @since 1.7.7
206 *
207 * @selector .gamipress-achievement-unlock-with-points-button
208 * @event gamipress_before_unlock_achievement_with_points
209 */
210 submit_wrap.trigger( 'gamipress_before_unlock_achievement_with_points', [] );
211
212 $.ajax( {
213 url: gamipress.ajaxurl,
214 method: 'POST',
215 dataType: 'json',
216 data: {
217 action: 'gamipress_unlock_achievement_with_points',
218 nonce: gamipress.nonce,
219 achievement_id: achievement_id
220 },
221 success: function( response ) {
222
223 // Ensure response wrap
224 if( submit_wrap.find('.gamipress-achievement-unlock-with-points-response').length === 0 )
225 submit_wrap.append('<div class="gamipress-achievement-unlock-with-points-response gamipress-notice" style="display: none;"></div>');
226
227 var response_wrap = submit_wrap.find('.gamipress-achievement-unlock-with-points-response');
228
229 // Add class gamipress-notice-success on successful unlock, if not will add the class gamipress-notice-error
230 response_wrap.addClass( 'gamipress-notice-' + ( response.success === true ? 'success' : 'error' ) );
231
232 // Update and show response messages
233 response_wrap.html( response.data );
234 response_wrap.slideDown();
235
236 // Hide the spinner
237 spinner.hide();
238
239 if( response.success === true ) {
240
241 // Hide confirmation
242 if( confirmation.length )
243 confirmation.slideUp();
244
245 // Hide the button
246 button.slideUp();
247
248 // Add the class earned to the achievement
249 // Single template
250 button.closest('.single-achievement').addClass('user-has-earned');
251 button.closest('.user-has-not-earned[class*="post"]').removeClass('user-has-not-earned').addClass('user-has-earned');
252
253 // Shortcode/Widget template
254 button.closest('.gamipress-achievement.user-has-not-earned').removeClass('user-has-not-earned').addClass('user-has-earned');
255 } else {
256
257 if( confirmation.length ) {
258 // Hide confirmation and enable confirm/cancel buttons
259 confirmation.slideUp();
260 submit_wrap.find('.gamipress-achievement-unlock-with-points-confirm-button').prop( 'disabled', false );
261 submit_wrap.find('.gamipress-achievement-unlock-with-points-cancel-button').prop( 'disabled', false );
262 }
263
264 // Enable the button
265 button.prop( 'disabled', false );
266 }
267
268 /**
269 * Allow external functions to process anything after unlock achievement with points
270 *
271 * @since 1.7.7
272 *
273 * @selector .gamipress-achievement-unlock-with-points-button
274 * @event gamipress_after_unlock_achievement_with_points
275 *
276 * @param Object response Response retrieved from server
277 */
278 submit_wrap.trigger( 'gamipress_after_unlock_achievement_with_points', [ response ] );
279 }
280 });
281
282 }
283
284 /**
285 * Unlock rank with points
286 *
287 * @since 1.7.8.1
288 * @updated 1.7.9 Added nonce usage
289 */
290 function gamipress_unlock_rank_with_points( submit_wrap ) {
291
292 var button = submit_wrap.find('.gamipress-rank-unlock-with-points-button');
293 var spinner = submit_wrap.find('.gamipress-spinner');
294 var rank_id = submit_wrap.data('id');
295 var confirmation = submit_wrap.find('.gamipress-rank-unlock-with-points-confirmation');
296
297 // Show the spinner
298 spinner.show();
299
300 /**
301 * Allow external functions to process anything before unlock rank with points
302 *
303 * @since 1.7.7
304 *
305 * @selector .gamipress-rank-unlock-with-points-button
306 * @event gamipress_before_unlock_rank_with_points
307 */
308 submit_wrap.trigger( 'gamipress_before_unlock_rank_with_points', [] );
309
310 $.ajax( {
311 url: gamipress.ajaxurl,
312 method: 'POST',
313 dataType: 'json',
314 data: {
315 action: 'gamipress_unlock_rank_with_points',
316 nonce: gamipress.nonce,
317 rank_id: rank_id
318 },
319 success: function( response ) {
320
321 // Ensure response wrap
322 if( submit_wrap.find('.gamipress-rank-unlock-with-points-response').length === 0 )
323 submit_wrap.append('<div class="gamipress-rank-unlock-with-points-response gamipress-notice" style="display: none;"></div>');
324
325 var response_wrap = submit_wrap.find('.gamipress-rank-unlock-with-points-response');
326
327 // Add class gamipress-notice-success on successful unlock, if not will add the class gamipress-notice-error
328 response_wrap.addClass( 'gamipress-notice-' + ( response.success === true ? 'success' : 'error' ) );
329
330 // Update and show response messages
331 response_wrap.html( response.data );
332 response_wrap.slideDown();
333
334 // Hide the spinner
335 spinner.hide();
336
337 if( response.success === true ) {
338
339 // Hide confirmation
340 if( confirmation.length )
341 confirmation.slideUp();
342
343 // Hide the button
344 button.slideUp();
345
346 // Add the class earned to the rank
347 // Single template
348 button.closest('.single-rank').addClass('user-has-earned');
349 button.closest('.user-has-not-earned[class*="post"]').removeClass('user-has-not-earned').addClass('user-has-earned');
350
351 // Shortcode/Widget template
352 button.closest('.gamipress-rank.user-has-not-earned').removeClass('user-has-not-earned').addClass('user-has-earned');
353 } else {
354
355 if( confirmation.length ) {
356 // Hide confirmation and enable confirm/cancel buttons
357 confirmation.slideUp();
358 submit_wrap.find('.gamipress-rank-unlock-with-points-confirm-button').prop( 'disabled', false );
359 submit_wrap.find('.gamipress-rank-unlock-with-points-cancel-button').prop( 'disabled', false );
360 }
361
362 // Enable the button
363 button.prop( 'disabled', false );
364 }
365
366 /**
367 * Allow external functions to process anything after unlock rank with points
368 *
369 * @since 1.7.7
370 *
371 * @selector .gamipress-rank-unlock-with-points-button
372 * @event gamipress_after_unlock_rank_with_points
373 *
374 * @param Object response Response retrieved from server
375 */
376 submit_wrap.trigger( 'gamipress_after_unlock_rank_with_points', [ response ] );
377 }
378 });
379
380 }
381
382 /**
383 * Unlock achievement/rank with points button
384 *
385 * @since 1.3.7
386 */
387 $body.on( 'click', '.gamipress-achievement-unlock-with-points-button, .gamipress-rank-unlock-with-points-button', function(e) {
388
389 var button = $(this);
390
391 var selector = ( button.hasClass('gamipress-achievement-unlock-with-points-button') ? 'achievement' : 'rank' );
392
393 var submit_wrap = button.closest('.gamipress-' + selector + '-unlock-with-points');
394 var confirmation = submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-confirmation');
395
396 // Disable the button
397 button.prop( 'disabled', true );
398
399 // Hide previous notices
400 if( submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-response').length )
401 submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-response').slideUp();
402
403 // If has confirmation, show it and return
404 if( confirmation.length ) {
405 confirmation.slideDown();
406 } else {
407 // Perform the ajax request to unlock with points
408 if( selector === 'achievement' )
409 gamipress_unlock_achievement_with_points( submit_wrap );
410 else
411 gamipress_unlock_rank_with_points( submit_wrap );
412 }
413
414 });
415
416 /**
417 * Unlock achievement/rank with points confirmation confirm button
418 *
419 * @since 1.7.8.1
420 */
421 $body.on( 'click', '.gamipress-achievement-unlock-with-points-confirm-button, .gamipress-rank-unlock-with-points-confirm-button', function(e) {
422
423 var $this = $(this);
424 var selector = ( $this.hasClass('gamipress-achievement-unlock-with-points-confirm-button') ? 'achievement' : 'rank' );
425
426 var submit_wrap = $this.closest('.gamipress-' + selector + '-unlock-with-points');
427
428 // Disable the confirm button
429 $this.prop( 'disabled', true );
430 // Disable the cancel button
431 submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-cancel-button').prop( 'disabled', true );
432
433 // Perform the ajax request to unlock with points
434 if( selector === 'achievement' )
435 gamipress_unlock_achievement_with_points( submit_wrap );
436 else
437 gamipress_unlock_rank_with_points( submit_wrap );
438
439 });
440
441 /**
442 * Unlock achievement/rank with points confirmation cancel button
443 *
444 * @since 1.7.8.1
445 */
446 $body.on( 'click', '.gamipress-achievement-unlock-with-points-cancel-button, .gamipress-rank-unlock-with-points-cancel-button', function(e) {
447
448 var $this = $(this);
449 var selector = ( $this.hasClass('gamipress-achievement-unlock-with-points-cancel-button') ? 'achievement' : 'rank' );
450
451 var submit_wrap = $this.closest('.gamipress-' + selector + '-unlock-with-points');
452 var button = submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-button');
453 var confirmation = submit_wrap.find('.gamipress-' + selector + '-unlock-with-points-confirmation');
454
455 // Hide confirmation
456 confirmation.slideUp();
457
458 // Enable the button
459 button.prop( 'disabled', false );
460
461 });
462
463 /**
464 * Share achievement/rank button
465 *
466 * @since 1.8.6
467 */
468 $body.on( 'click', '.gamipress-share-button', function (e) {
469 e.preventDefault();
470
471 var wrapper = $(this).closest('.gamipress-share-buttons');
472 var network = $(this).data('network');
473
474 // URL templates
475 var templates = {
476 facebook: 'https://www.facebook.com/sharer.php?u={url}',
477 twitter: 'https://twitter.com/intent/tweet?text={text}%0A{url}',
478 linkedin: 'https://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={text}&source={url}',
479 pinterest: 'https://www.pinterest.com/pin/create/button/?url={url}&media={image}',
480 };
481
482 // Default dimensions for the new window
483 var width = 640;
484 var height = 480;
485
486 if( templates[network] !== undefined ) {
487
488 var url = wrapper.data('url');
489 var title = wrapper.data('title');
490 var text = wrapper.data('twitter-text');
491 var image = wrapper.data('image');
492
493 // Replace the template (ensuring each element is correctly encoded)
494 var parsed_url = templates[network]
495 .replace( '{url}', encodeURIComponent( url ) )
496 .replace( '{title}', encodeURIComponent( title ) )
497 .replace( '{image}', encodeURIComponent( image ) )
498 .replace( '{text}', encodeURIComponent( text ) );
499
500 // Center the new window at center of the screen
501 var window_top = ( screen.height / 2 ) - ( height / 2 );
502 var window_left = ( screen.width / 2 ) - ( width / 2 );
503
504 var window_parameters = 'toolbar=0,status=0,width=' + width + ',height=' + height + ',top=' + window_top + ',left=' + window_left;
505
506 var share_window = window.open( parsed_url, network, window_parameters );
507
508 // Force focus to the new window
509 if( window.focus ) {
510 share_window.focus();
511 }
512
513 }
514
515 });
516
517 /**
518 * Logs ajax pagination
519 *
520 * @since 1.4.9
521 * @updated 1.7.9 Added nonce usage
522 */
523 $body.on( 'click', '#gamipress-logs-pagination a', function (e) {
524 e.preventDefault();
525
526 var $this = $(this);
527
528 if( $this.hasClass('current') ) {
529 return false;
530 }
531
532 var logs = $this.closest('.gamipress-logs');
533
534 // Regex to match wordpress permalink config (paged={d}|/page/{d})
535 var matches = $this.attr('href').match(/paged=(\d+)|\/page\/(\d+)/);
536 var page = ( matches[1] !== undefined ) ? matches[1] : matches[2];
537
538 var data = {
539 action: 'gamipress_get_logs',
540 nonce: gamipress.nonce,
541 page: page,
542 };
543
544 logs.find('.gamipress-logs-atts input').each(function() {
545 data[$(this).attr('name')] = $(this).val();
546 });
547
548 // Show the spinner
549 logs.find( '#gamipress-logs-spinner' ).show();
550
551 $.ajax( {
552 url: gamipress.ajaxurl,
553 data: data,
554 dataType: 'json',
555 success: function( response ) {
556
557 // Hide the spinner
558 logs.find( '#gamipress-logs-spinner' ).hide();
559
560 var parsed_content = $(response.data);
561
562 logs.find('.gamipress-logs-list').html( parsed_content.find('.gamipress-logs-list').html() );
563 logs.find('.gamipress-logs-pagination').html( parsed_content.find('.gamipress-logs-pagination').html() );
564
565 }
566 } );
567 });
568
569 /**
570 * Earnings ajax pagination
571 *
572 * @since 1.4.9
573 * @updated 1.7.9 Added nonce usage
574 */
575 $body.on( 'click', '#gamipress-earnings-pagination a', function (e) {
576 e.preventDefault();
577
578 var $this = $(this);
579
580 if( $this.hasClass('current') ) {
581 return false;
582 }
583
584 var earnings = $this.closest('.gamipress-earnings');
585
586 // Regex to match wordpress permalink config (paged={d}|/page/{d})
587 var matches = $this.attr('href').match(/paged=(\d+)|\/page\/(\d+)/);
588 var page = ( matches[1] !== undefined ) ? matches[1] : matches[2];
589
590 var data = {
591 action: 'gamipress_get_user_earnings',
592 nonce: gamipress.nonce,
593 page: page,
594 };
595
596 earnings.find('.gamipress-earnings-atts input').each(function() {
597 data[$(this).attr('name')] = $(this).val();
598 });
599
600 // Show the spinner
601 earnings.find( '#gamipress-earnings-spinner' ).show();
602
603 $.ajax( {
604 url: gamipress.ajaxurl,
605 data: data,
606 dataType: 'json',
607 success: function( response ) {
608
609 // Hide the spinner
610 earnings.find( '#gamipress-earnings-spinner' ).hide();
611
612 var parsed_content = $(response.data);
613
614 earnings.find('.gamipress-earnings-table').html( parsed_content.find('.gamipress-earnings-table').html() );
615 earnings.find('.gamipress-earnings-pagination').html( parsed_content.find('.gamipress-earnings-pagination').html() );
616
617 }
618 } );
619 });
620
621 /**
622 * Email settings
623 *
624 * @since 2.2.1
625 */
626 $body.on( 'change', '.gamipress-email-settings input', function (e) {
627
628 var $this = $(this);
629 var form = $this.closest('.gamipress-email-settings');
630 var row = $this.closest('tr');
631 var loader = row.find('.gamipress-email-settings-loader');
632 var value = $this.val();
633 var name = $this.attr('name');
634 var setting = name.replace('gamipress_email_settings[', '').replace(']', '');
635
636 switch( setting ) {
637 case 'all':
638 form.find('input[value="' + value + '"]:not([name="' + name + '"])').prop('checked', true);
639 break;
640 case 'points_types':
641 case 'achievement_types':
642 case 'rank_types':
643 form.find('input[value="' + value + '"][name^="gamipress_email_settings[' + setting + '_"]').prop('checked', true);
644 break;
645 }
646
647 // Show the "Saving..." text
648 loader.find('.gamipress-email-settings-saving').show();
649 loader.find('.gamipress-email-settings-saved').hide();
650 loader.show();
651
652 $.ajax( {
653 url: gamipress.ajaxurl,
654 data: {
655 action: 'gamipress_save_email_settings',
656 nonce: gamipress.nonce,
657 setting: setting,
658 value: value,
659 },
660 dataType: 'json',
661 success: function( response ) {
662
663 // Show the "Saved!" text
664 loader.find('.gamipress-email-settings-saving').hide();
665 loader.find('.gamipress-email-settings-saved').show();
666 loader.show();
667
668 setTimeout( function() {
669 loader.hide();
670 }, 2000 );
671
672 }
673 } );
674
675 });
676
677 } )( jQuery );