PluginProbe
WANotifier for Forms and Actions / 0.1.0
WANotifier for Forms and Actions v0.1.0
3.1.1 3.1.0 3.0.4 2.7.10 2.7.11 2.7.12 2.7.13 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 3.0.0 3.0.1 3.0.2 3.0.3 trunk 0.1.0 0.1.1 1.0.0 1.0.1 1.0.2 All 67 releases
notifier / assets / js / admin.js

admin.js in WANotifier for Forms and Actions 0.1.0, at assets/js/admin.js

661 lines 22.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global waNotifier */
2 (function($) {
3
4 // Show / hide fields as per conditional logic
5 function conditionallyShowFields() {
6 if ($('.meta-fields').length == 0) {
7 return;
8 }
9
10 $('.form-field').each(function() {
11 var thisField = $(this).find(':input');
12
13 // Conditionally show/hide fields
14 var conditions = $(this).attr('data-conditions') || '';
15 if (conditions !== '') {
16 var showField = false;
17 var fieldElem = $(this);
18 var conditionsArray = JSON.parse(conditions);
19
20 conditionsArray.forEach(function(condition) {
21 var fieldClass = '.' + condition.field + '_field';
22 var fieldInput = $(fieldClass + ' :input');
23 var fieldInputType = fieldInput.prop('type');
24
25 // Do not fetch value of hidden fields.
26 if(!$(fieldClass).is(':visible')){
27 return;
28 }
29
30 // Get field value
31 var fieldVal = fieldInput.val();
32
33 // Get field value if it's radio or checkbox
34 if($.inArray(fieldInputType, ['radio', 'checkbox']) !== -1) {
35 fieldVal = $(fieldClass + ' :input:checked').val();
36 }
37
38 var showThis = false;
39 if(condition.operator == '==') {
40 showThis = (fieldVal == condition.value) ? true : false;
41 }
42 else if(condition.operator == '!=') {
43 showThis = (fieldVal != condition.value) ? true : false;
44 }
45 showField = showField || showThis;
46 });
47
48 if(showField){
49 fieldElem.show();
50 }
51 else{
52 fieldElem.hide();
53 }
54 }
55
56 // Apply data limit on fields
57 if (thisField.hasClass('force-text-limit')) {
58 var content = thisField.val();
59 var contentLength = content.length;
60 var limit = thisField.attr('data-limit');
61 if (contentLength >= limit) {
62 thisField.siblings('label').find('.limit-used').text(limit);
63 thisField.val(content.substr(0, limit));
64 } else {
65 thisField.siblings('label').find('.limit-used').text(contentLength);
66 }
67 }
68
69 // Enable select2 for notification receiver contact dropdown
70 if($('.notifier-recipient-contact').length > 0){
71 $('.notifier-recipient-contact').each(function (i, obj) {
72 if($(obj).closest('.row-add-recipient-template').length > 0){
73 return;
74 }
75 if (!$(obj).data('select2')){
76 $(obj).select2({
77 selectOnClose: true,
78 width: '100%',
79 placeholder: 'Search contact...',
80 ajax: {
81 url: waNotifier.ajaxurl,
82 dataType: 'json',
83 delay: 250,
84 method: 'post',
85 data: function (params) {
86 return {
87 s: params.term,
88 action: 'get_wa_contacts_data',
89 };
90 },
91 processResults: function( data ) {
92 var options = [];
93 if ( data ) {
94 $.each( data, function( index, text ) {
95 options.push( { id: index, text: text } );
96 });
97 }
98 return {
99 results: options,
100 };
101 },
102 cache: true,
103 },
104 minimumInputLength: 2,
105 });
106 }
107 });
108 }
109
110 });
111 }
112
113 // Fetch message template data and generate preview
114 function fetcDataAndPreviewTemplate() {
115 let previewData = {};
116 previewData.header_type = $('#notifier_header_type').val();
117 if('text' == previewData.header_type){
118 previewData.header_text = $('#notifier_header_text').val() || 'Header text here';
119 }
120 else if('media' == previewData.header_type){
121 previewData.media_type = $('#notifier_media_type').val() || 'image';
122 }
123
124 previewData.body_text = $('#notifier_body_text').val() || 'Body text here';
125 previewData.footer_text = $('#notifier_footer_text').val() || '';
126 previewData.button_type = $('#notifier_button_type').val();
127
128 previewData.button_num = $('input[name="notifier_button_num"]:checked').val();
129
130 previewData.button_1_type = $('#notifier_button_1_type :selected').val();
131 previewData.button_1_text = $('#notifier_button_1_text').val() || '';
132 previewData.button_2_text = $('#notifier_button_2_text').val() || '';
133
134 // Button
135 if (previewData.button_type != 'none') {
136 if (previewData.button_1_type == 'URL') {
137 if (previewData.button_1_text == '') {
138 previewData.button_1_text = 'Visit Website';
139 }
140 } else if (previewData.button_1_type == 'PHONE_NUMBER') {
141 if (previewData.button_1_text == '') {
142 previewData.button_1_text = 'Call';
143 }
144 }
145
146 if (previewData.button_num == '1') {
147 $('#notifier_button_1_type option').prop('disabled', false);
148 $('#notifier_button_2_type option').prop('disabled', false);
149 } else {
150 $('#notifier_button_1_type option').not('option[value="' + previewData.button_1_type + '"]').prop('disabled', true);
151 $('#notifier_button_2_type option').not('option[value="' + previewData.button_1_type + '"]').prop('selected', true);
152 $('#notifier_button_2_type option[value="' + previewData.button_1_type + '"]').prop('disabled', true);
153 previewData.button_2_type = $('#notifier_button_2_type :selected').val();
154 if (previewData.button_2_type == 'URL') {
155 if (previewData.button_2_text == '') {
156 previewData.button_2_text = 'Visit Website';
157 }
158 } else if (previewData.button_2_type == 'PHONE_NUMBER') {
159 if (previewData.button_2_text == '') {
160 previewData.button_2_text = 'Call';
161 }
162 }
163 }
164 }
165
166 // Render message preview from the data
167 renderMessagePreview(previewData);
168 }
169
170 // Render message preview
171 function renderMessagePreview(previewData) {
172 messageTemplatePreviewData = previewData;
173 // Header
174 $('.wa-template-preview .message-head').hide();
175 switch (previewData.header_type) {
176 case 'text':
177 $('.wa-template-preview .message-head-text').show().text(previewData.header_text);
178 break;
179 case 'media':
180 var media_type = previewData.media_type.toLowerCase();
181 var head_preview_classes = 'message-head message-head-media message-head-'+media_type;
182 $('.wa-template-preview .message-head-media').show().attr('class', head_preview_classes);
183 break;
184 }
185
186 // Body
187 previewData.body_text = previewData.body_text.replace(/(<([^>]+)>)/gi, '')
188 .replace(/(?:\r\n|\r|\n)/g, '<br>')
189 .replace(/(?:\*)(?:(?!\s))((?:(?!\*|\n).)+)(?:\*)/g,'<b>$1</b>')
190 .replace(/(?:_)(?:(?!\s))((?:(?!\n|_).)+)(?:_)/g,'<i>$1</i>')
191 .replace(/(?:~)(?:(?!\s))((?:(?!\n|~).)+)(?:~)/g,'<s>$1</s>')
192 .replace(/(?:--)(?:(?!\s))((?:(?!\n|--).)+)(?:--)/g,'<u>$1</u>')
193 .replace(/(?:```)(?:(?!\s))((?:(?!\n|```).)+)(?:```)/g,'<tt>$1</tt>');
194
195 $('.wa-template-preview .message-body').html(previewData.body_text);
196
197 // Footer
198 if (previewData.footer_text !== '') {
199 $('.wa-template-preview .message-footer').show().text(previewData.footer_text);
200 } else {
201 $('.wa-template-preview .message-footer').hide();
202 }
203
204 // Buttons
205 if (previewData.button_type == 'none') {
206 $('.wa-template-preview .message-buttons').hide();
207 } else {
208 $('.wa-template-preview .message-buttons').show();
209 if (previewData.button_1_type == 'URL') {
210 $('.wa-template-preview .message-button-1 .message-button-img').removeClass('call').addClass('visit');
211 $('.wa-template-preview .message-button-1 .message-button-text').text(previewData.button_1_text);
212 } else if (previewData.button_1_type == 'PHONE_NUMBER') {
213 $('.wa-template-preview .message-button-1 .message-button-img').removeClass('visit').addClass('call');
214 $('.wa-template-preview .message-button-1 .message-button-text').text(previewData.button_1_text);
215 }
216
217 if (previewData.button_num == '1') {
218 $('.wa-template-preview .message-button-2').hide();
219 } else {
220 $('.wa-template-preview .message-button-2').show();
221 if (previewData.button_2_type == 'URL') {
222 $('.wa-template-preview .message-button-2 .message-button-img').removeClass('call').addClass('visit');
223 $('.wa-template-preview .message-button-2 .message-button-text').text(previewData.button_2_text);
224 } else if (previewData.button_2_type == 'PHONE_NUMBER') {
225 $('.wa-template-preview .message-button-2 .message-button-img').removeClass('visit').addClass('call');
226 $('.wa-template-preview .message-button-2 .message-button-text').text(previewData.button_2_text);
227 }
228 }
229 }
230 }
231
232 // Fetch and display send to fields
233 function fetchAndDisplaySendToFields() {
234 const post_id = $('#post_ID').val() || 0;
235 const notification_type = $('#notifier_notification_type').val() || '';
236 const trigger = $('#notifier_notification_trigger').val() || '';
237
238 if('marketing' == notification_type) {
239 return;
240 }
241
242 $('.send-to-fields').html('<div class="loader"></div>');
243
244 $.ajax({
245 type: 'post',
246 dataType: 'json',
247 url: waNotifier.ajaxurl,
248 data: {
249 action: 'fetch_send_to_fields',
250 trigger: trigger,
251 post_id: post_id,
252 },
253 success: function(response) {
254 if (response.status == 'success') {
255 $('.send-to-fields').html(response.html);
256 conditionallyShowFields();
257 }
258 },
259 });
260 }
261
262 // Fetch and display message template
263 function fetchAndDisplayMessageTemplate() {
264 const template_id = $('#notifier_notification_message_template :selected').val();
265 if (template_id == '') {
266 $('#notifier-message-template-preview').removeClass('d-block').addClass('hide');
267 return false;
268 }
269 const post_id = $('#post_ID').val() || 0;
270 const notification_type = $('#notifier_notification_type').val() || '';
271 const trigger = $('#notifier_notification_trigger').val() || '';
272 $.ajax({
273 type: 'post',
274 dataType: 'json',
275 url: waNotifier.ajaxurl,
276 data: {
277 action: 'fetch_message_template_data',
278 notification_type: notification_type,
279 template_id: template_id,
280 post_id: post_id,
281 trigger: trigger,
282 },
283 success: function(response) {
284 if (response.status == 'success') {
285 $('#notifier-message-template-preview').removeClass('hide').addClass('d-block');
286 renderMessagePreview(response.data);
287 }
288 },
289 });
290 }
291
292 // Notifications page - change save button text
293 function updateNotificationSaveButtonText() {
294 var type = $('#notifier_notification_type :checked').val();
295 var when = $('#notifier_notification_when :checked').val();
296 var btnText = '';
297 if(type == 'transactional'){
298 btnText = 'Save';
299 }
300 else {
301 btnText = (when == 'now') ? 'Save & Send' : 'Save & Schedule';
302 }
303 $('#publish').val(btnText);
304 }
305
306 // Uploading media to WP using wp.media
307 var file_frame;
308 function uploadMediaFile( button, preview_media ) {
309 var button_id = button.attr('id');
310 var field_id = button_id.replace( '_button', '' );
311 var preview_id = button_id.replace( '_button', '_preview' );
312
313 // Create the media frame.
314 file_frame = wp.media.frames.file_frame = wp.media({
315 title: button.data( 'uploader_title' ),
316 button: {
317 text: button.data( 'uploader_button_text' ),
318 },
319 library: {
320 type: button.data( 'uploader_supported_file_types' ).split(',')
321 },
322 multiple: false
323 });
324
325 // When an image is selected, run a callback.
326 file_frame.on( 'select', function() {
327 attachment = file_frame.state().get('selection').first().toJSON();
328 jQuery("#"+field_id).val(attachment.id);
329 jQuery("#"+field_id).data('type', attachment.type);
330 jQuery("#"+field_id).data('subtype', attachment.subtype);
331 jQuery("#"+field_id).siblings('.notifier-media-preview').find().hide();
332 if( preview_media ) {
333 if('image' == attachment.type || ('application' == attachment.type && 'pdf' == attachment.subtype) ) {
334 jQuery("#"+field_id).data('url', attachment.sizes.thumbnail.url);
335 jQuery("#"+preview_id+'_image').show().attr('src',attachment.sizes.thumbnail.url);
336 }
337 else if ('video' == attachment.type) {
338 jQuery("#"+field_id).data('url', attachment.url);
339 jQuery("#"+preview_id+'_video').show().find('source').attr('src',attachment.url);
340 }
341 }
342
343 });
344
345 // Finally, open the modal
346 file_frame.open();
347 }
348
349 $(document).on('ready', function() {
350
351 window.messageTemplatePreviewData = {};
352
353 /*****************
354 * Dashboard page
355 ****************/
356
357 // Toggle steps on dashboard page
358 $('.toggle-step').on('click', function() {
359 $(this).closest('.step').toggleClass('active');
360 $(this).closest('.step').siblings().removeClass('active');
361 });
362
363 // Highlight menu items
364 const wan_menu_elem = $('#toplevel_page_notifier');
365 const notifier_cpts = ['wa_message_template', 'wa_contact', 'wa_notification'];
366 const current_cpt = $('#notifier-admin-header').data('post-type') || '';
367 if (notifier_cpts.includes(current_cpt)) {
368 wan_menu_elem
369 .removeClass('wp-not-current-submenu')
370 .addClass('wp-has-current-submenu')
371 .children('a')
372 .removeClass('wp-not-current-submenu')
373 .addClass('wp-has-current-submenu');
374 wan_menu_elem.find('a[href*="' + current_cpt + '"]').addClass('current').closest('li').addClass('current');
375 }
376
377 /*************************
378 * Message Template page
379 *************************/
380
381 // Make the WhatsApp preview sidebar sticky
382 if ($('#notifier-message-template-preview').length > 0) {
383 var wa_preview = $('#notifier-message-template-preview');
384 var wa_preview_top = wa_preview.offset().top - 50;
385 var wa_preview_width = wa_preview.width();
386 wa_preview.width(wa_preview_width);
387 $(window).scroll( function() {
388 if (window.pageYOffset > wa_preview_top && window.innerWidth > 850) {
389 wa_preview.addClass('sticky');
390 } else {
391 wa_preview.removeClass('sticky');
392 }
393 });
394 }
395
396 // Validate the message template name
397 $('#notifier_template_name').on('keyup', function() {
398 var value = $(this).val().trim();
399 $(this).val(value.replaceAll(' ', '_').replaceAll(/[^a-zA-Z0-9_]/g, '').toLowerCase());
400 });
401
402 // Trigger conditional logic and WhatsApp message template preview
403 if ($('#notifier-message-template-data').length > 0) {
404 fetcDataAndPreviewTemplate();
405 $('#notifier-message-template-data :input').on('change keyup', function() {
406 fetcDataAndPreviewTemplate();
407 });
408 }
409
410 // Update template name as per the title value
411 $('.post-type-wa_message_template #title').on('change', function() {
412 const title = $(this).val().trim() || '';
413 const template_name = $('#notifier_template_name').val() || '';
414 if('' !== template_name) {
415 return;
416 }
417 $('#notifier_template_name').val(title.replaceAll(' ', '_').replaceAll(/[^a-zA-Z0-9_]/g, '').toLowerCase());
418 })
419
420 // Message template publish confirmation
421 $('.post-type-wa_message_template #publish').on('click', function() {
422 const template_name = $('#notifier_template_name').val() || '';
423 const body_text = $('#notifier_body_text').val() || '';
424 if ('' === template_name && '' === body_text) {
425 alert('Template name and Body text are required fields.');
426 return false;
427 }
428 if ('' === template_name) {
429 alert('Template name is a required field.');
430 return false;
431 }
432 if ('' === body_text) {
433 alert('Body text is a required field.');
434 return false;
435 }
436 var header_text = $('#notifier_header_text').val() || '';
437 if(header_text.match(/{{.*?}}/g) !== null || body_text.match(/{{.*?}}/g) !== null) {
438 alert('Free version of the plugin does not support variables. Please remove variables like {{}} and try again.');
439 return false;
440 }
441 return confirm('IMPORTANT NOTE:\n\nClicking "OK" will send your template data to WhatsApp for approval. It might take between 30 minutes to 24 hours for them to review it.\n\nYou\'ll get confirmation email from them after they complete their review. You will be able to send this template to your contacts only after their approval.');
442 });
443
444 // Message template delete confirmation
445 $('.post-type-wa_message_template .row-actions .delete').on('click', function() {
446 return confirm('Deleting from here will also delete this template from WhatsApp server.');
447 });
448
449 // Add Refresh Status button to the message template lisitng page
450 var refresh_mt_status_template = $('#notifier-template-wa-mt-refresh').html().trim();
451 $('.edit-php.post-type-wa_message_template .wrap .page-title-action').after(refresh_mt_status_template);
452
453 /***************
454 * Contact page
455 **************/
456
457 // Add Import button and HTML to the Contacts lisitng page
458 var import_contact_template = $('#notifier-template-import-contacts').html().trim();
459 $('.edit-php.post-type-wa_contact .wrap .page-title-action').after(import_contact_template);
460
461 // Show import options
462 $(document).on('click', '#import-contacts', function(e) {
463 e.preventDefault();
464 $('.contact-import-options').toggleClass('hide');
465 });
466
467 // Select import method
468 $(document).on('change', '.csv-import-method', function() {
469 var value = $(this).val();
470 $('.col-import').addClass('hide');
471 $('.col-import-' + value).removeClass('hide');
472 });
473
474 // On submission of CSV import form
475 $(document).on('submit', '#import-contacts-csv', function() {
476 var file = $('#notifier-contacts-csv').val();
477 if (file == '') {
478 alert('Please select a file to upload.');
479 return false;
480 } else {
481 var file_size = $('#notifier-contacts-csv')[0].files[0].size / 1024 / 1024;
482 if (file_size > 24) {
483 alert('Please select CSV file smaller than 24MB.');
484 return false;
485 }
486 var allowedExtension = /(\.csv)$/i;
487 if (!allowedExtension.exec(file)) {
488 alert('Please select a CSV file.');
489 $('#notifier-contacts-csv').val('');
490 return false;
491 }
492 }
493 });
494
495 // On submission of users import form
496 $(document).on('submit', '#import-contacts-users', function() {
497 const wa_contact_list_name = $('#wa_contact_list_name').val() || '';
498 if (wa_contact_list_name == '') {
499 alert('Please enter a Contact List name.');
500 return false;
501 }
502 });
503
504 // Contact publish confirmation
505 $('.post-type-wa_contact #publish').on('click', function() {
506 const first_name = $('#notifier_first_name').val() || '';
507 const last_name = $('#notifier_last_name').val() || '';
508 const wa_number = $('#notifier_wa_number').val() || '';
509
510 if (first_name == '' || last_name == '' || wa_number == '') {
511 alert('First Name, Last Name and Phone Number are required fields.');
512 return false;
513 }
514 });
515
516 /********************
517 * Notification page
518 ********************/
519
520 // Do stuff if on the notification edit page
521 if ($('#notifier-notification-data').length > 0) {
522 updateNotificationSaveButtonText(); // Update button text as per user selection
523 fetchAndDisplaySendToFields(); // Fetch and display send to fields
524 fetchAndDisplayMessageTemplate(); // Fetch and display message template preview + variable mapping fields
525 $('#notifier-notification-data :input').on('change keyup', function(){
526 updateNotificationSaveButtonText();
527
528 if('notifier_notification_trigger' == $(this).attr('name')){
529 fetchAndDisplaySendToFields();
530 fetchAndDisplayMessageTemplate();
531 }
532
533 if('notifier_notification_message_template' == $(this).attr('name')){
534 fetchAndDisplayMessageTemplate();
535 }
536 });
537
538 var dateToday = new Date();
539 $('#notifier_notification_datetime').datetimepicker({
540 minDate: dateToday,
541 defaultDate: 1,
542 });
543 }
544
545 // Notification publish confirmation
546 $('.post-type-wa_notification #publish').on('click', function() {
547 const type = $('#notifier_notification_type').val() || '';
548 const template_name = $('#notifier_notification_message_template').val() || '';
549
550 if ('' === type) {
551 alert('Please select a notification type.');
552 return false;
553 }
554 else if ('transactional' == type) {
555 const trigger = $('#notifier_notification_trigger :selected').val() || '';
556 if ('' === trigger) {
557 alert('Please select a trigger.');
558 return false;
559 }
560
561 var recipientMissing = false;
562 $('.notifier-recipient').each(function(){
563 const recipient = $('option:selected',this).val() || '';
564 if($(this).is(':visible') && '' == recipient){
565 recipientMissing = true;
566 }
567 });
568
569 if(recipientMissing){
570 alert('Recipient field can not be empty.');
571 return false;
572 }
573 }
574 else if ('marketing' == type) {
575 const list = $('#notifier_notification_list :selected').val() || '';
576 if ('' === list) {
577 alert('Please select a contact list.');
578 return false;
579 }
580 }
581
582 if ('' === template_name) {
583 alert('Please select a Message Template.');
584 return false;
585 }
586
587 if( $('.notifier-variable-mapping').length > 0 ){
588 var recipientValue = false;
589 $('.notifier-variable-mapping').each(function(){
590 const value = $('option:selected',this).val() || '';
591 if($(this).is(':visible') && '' == value){
592 recipientValue = true;
593 }
594 });
595 if(recipientValue){
596 alert('Message template variable missing mapped value.');
597 return false;
598 }
599 }
600
601 var header_text = messageTemplatePreviewData.header_text || '';
602 var body_text = messageTemplatePreviewData.body_text || '';
603 if(header_text.match(/{{.*?}}/g) !== null || body_text.match(/{{.*?}}/g) !== null) {
604 alert('Free version of the plugin does not support sending message templates with variables. Please select a message template that does not use variables.');
605 return false;
606 }
607 });
608
609 // Add new Notification Send To receiver fields row
610 $(document).on('click', '.add-recipient', function(e){
611 e.preventDefault();
612 var next = $('.send-to-fields .fields-repeater tr.row').length;
613 var nextRowHtml = $('.row-add-recipient-template').get(0).outerHTML.replaceAll('row_num', next).replace('hide row-add-recipient-template', '');
614 $('.send-to-fields .fields-repeater tbody').append(nextRowHtml);
615 conditionallyShowFields();
616 });
617
618 $(document).on('click', '.delete-repeater-field span', function(e){
619 e.preventDefault();
620 $(this).closest('tr.row').remove();
621 });
622
623 /*****************
624 * Global
625 ****************/
626
627 // Make the top admin header sticky
628 var wpcontent_top = $('#wpcontent').offset().top;
629 $(window).scroll( function() {
630 if (window.pageYOffset > wpcontent_top) {
631 $('#notifier-admin-header').addClass('sticky');
632 } else {
633 $('#notifier-admin-header').removeClass('sticky');
634 }
635 });
636
637 // Show feilds conditionally
638 conditionallyShowFields();
639 $(document).on('change keyup', '.meta-fields :input', function() {
640 conditionallyShowFields();
641 });
642
643 /*****************
644 * Settings page
645 ****************/
646
647 jQuery('.notifier-media-upload-button').click(function() {
648 uploadMediaFile( jQuery(this), true );
649 });
650
651 jQuery('.notifier-media-delete-button').click(function() {
652 jQuery(this).next( '.notifier-media-attachment-id' ).val( '' );
653 jQuery(this).siblings( '.notifier-media-preview' ).find('img').attr('src', '');
654 return false;
655 });
656
657
658 });
659
660 })(jQuery);
661