PluginProbe ʕ •ᴥ•ʔ
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More / 1.6.4
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More v1.6.4
1.10.1.1 1.10.1 1.10.0.5 trunk 1.1.4 1.1.4.2 1.1.5 1.1.5.1 1.1.6 1.1.6.1 1.1.7 1.1.7.1 1.1.7.2 1.1.8 1.1.8.1 1.1.8.2 1.1.8.3 1.1.8.4 1.10.0.1 1.10.0.2 1.10.0.3 1.10.0.4 1.2.0 1.2.0.1 1.2.1 1.2.2 1.2.2.1 1.2.2.2 1.2.3 1.2.3.1 1.2.3.2 1.2.4 1.2.4.1 1.2.5 1.2.5.1 1.2.6 1.2.7 1.2.8 1.2.8.1 1.2.9 1.3.0 1.3.1 1.3.1.1 1.3.1.2 1.3.2 1.3.3 1.3.5 1.3.6 1.3.6.1 1.3.6.2 1.3.7.2 1.3.7.3 1.3.7.4 1.3.8 1.3.9.1 1.4.0.1 1.4.1.1 1.4.2 1.4.2.1 1.4.2.2 1.4.3 1.4.4 1.4.4.1 1.4.5 1.4.5.1 1.4.5.2 1.4.5.3 1.4.6 1.4.7.1 1.4.7.2 1.4.8.1 1.4.9 1.5.0.1 1.5.0.3 1.5.0.4 1.5.1 1.5.1.1 1.5.1.3 1.5.2.1 1.5.2.2 1.5.2.3 1.5.3 1.5.3.1 1.5.4.1 1.5.4.2 1.5.5 1.5.5.1 1.5.6 1.5.6.2 1.5.7 1.5.8.2 1.5.9.1 1.5.9.4 1.5.9.5 1.6.0.1 1.6.0.2 1.6.1 1.6.2.2 1.6.2.3 1.6.3.1 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.7 1.6.7.1 1.6.7.2 1.6.7.3 1.6.8 1.6.8.1 1.6.9 1.7.0 1.7.1.1 1.7.1.2 1.7.2 1.7.2.1 1.7.3 1.7.4 1.7.4.1 1.7.4.2 1.7.5.1 1.7.5.2 1.7.5.3 1.7.5.5 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.7.9.1 1.8.0.1 1.8.0.2 1.8.1.1 1.8.1.2 1.8.1.3 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.3.1 1.8.4 1.8.4.1 1.8.5.2 1.8.5.3 1.8.5.4 1.8.6.2 1.8.6.3 1.8.6.4 1.8.7.2 1.8.8.2 1.8.8.3 1.8.9.1 1.8.9.2 1.8.9.4 1.8.9.5 1.8.9.6 1.9.0.1 1.9.0.2 1.9.0.3 1.9.0.4 1.9.1.1 1.9.1.2 1.9.1.3 1.9.1.4 1.9.1.5 1.9.1.6 1.9.2.1 1.9.2.2 1.9.2.3 1.9.3.1 1.9.3.2 1.9.4.1 1.9.4.2 1.9.5 1.9.5.1 1.9.5.2 1.9.6 1.9.6.1 1.9.6.2 1.9.7.1 1.9.7.2 1.9.7.3 1.9.8.1 1.9.8.2 1.9.8.4 1.9.8.7 1.9.9.2 1.9.9.3 1.9.9.4
wpforms-lite / assets / js / admin.js
wpforms-lite / assets / js Last commit date
components 5 years ago integrations 5 years ago admin-builder-conditional-logic-core.js 5 years ago admin-builder-providers.js 5 years ago admin-builder.js 5 years ago admin-editor.js 5 years ago admin-notifications.js 5 years ago admin-notifications.min.js 5 years ago admin-utils.js 5 years ago admin.js 5 years ago admin.min.js 5 years ago chart.min.js 5 years ago choices.min.js 5 years ago flatpickr.min.js 5 years ago jquery.conditionals.min.js 5 years ago jquery.inputmask.min.js 5 years ago jquery.insert-at-caret.min.js 5 years ago jquery.jquery-confirm.min.js 5 years ago jquery.matchHeight-min.js 5 years ago jquery.minicolors.min.js 5 years ago jquery.payment.min.js 5 years ago jquery.serialize-object.min.js 5 years ago jquery.timepicker.min.js 5 years ago jquery.tooltipster.min.js 5 years ago jquery.validate.js 5 years ago jquery.validate.min.js 5 years ago list.min.js 5 years ago lity.min.js 5 years ago mailcheck.min.js 5 years ago moment-with-locales.min.js 5 years ago moment.min.js 5 years ago purify.min.js 5 years ago text-limit.js 5 years ago text-limit.min.js 5 years ago wpforms-confirmation.js 5 years ago wpforms.js 5 years ago
admin.js
2183 lines
1 /* global wpforms_admin, jconfirm, wpCookies, Choices, List */
2
3 ;(function($) {
4
5 'use strict';
6
7 // Global settings access.
8 var s;
9
10 // Admin object.
11 var WPFormsAdmin = {
12
13 // Settings.
14 settings: {
15 iconActivate: '<i class="fa fa-toggle-on fa-flip-horizontal" aria-hidden="true"></i>',
16 iconDeactivate: '<i class="fa fa-toggle-on" aria-hidden="true"></i>',
17 iconInstall: '<i class="fa fa-cloud-download" aria-hidden="true"></i>',
18 iconSpinner: '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>',
19 mediaFrame: false
20 },
21
22 /**
23 * Start the engine.
24 *
25 * @since 1.3.9
26 */
27 init: function() {
28
29 // Settings shortcut.
30 s = this.settings;
31
32 // Document ready.
33 $( WPFormsAdmin.ready );
34
35 // Forms Overview.
36 WPFormsAdmin.initFormOverview();
37
38 // Entries Single (Details).
39 WPFormsAdmin.initEntriesSingle();
40
41 // Entries List.
42 WPFormsAdmin.initEntriesList();
43
44 // Welcome activation.
45 WPFormsAdmin.initWelcome();
46
47 // Addons List.
48 $( document ).on( 'wpformsReady', WPFormsAdmin.initAddons );
49
50 // Settings.
51 WPFormsAdmin.initSettings();
52
53 // Tools.
54 WPFormsAdmin.initTools();
55
56 // Upgrades (Tools view).
57 WPFormsAdmin.initUpgrades();
58 },
59
60 /**
61 * Document ready.
62 *
63 * @since 1.3.9
64 */
65 ready: function() {
66
67 // To prevent jumping (since WP core moves the notices with js),
68 // they are hidden initially with CSS, then revealed below with JS,
69 // which runs after they have been moved.
70 $( '.notice' ).show();
71
72 // If there are screen options we have to move them.
73 $( '#screen-meta-links, #screen-meta' ).prependTo( '#wpforms-header-temp' ).show();
74
75 // Init fancy selects via choices.js.
76 WPFormsAdmin.initChoicesJS();
77
78 // Init checkbox multi selects columns.
79 WPFormsAdmin.initCheckboxMultiselectColumns();
80
81 // Init color pickers via minicolors.js.
82 $( '.wpforms-color-picker' ).minicolors();
83
84 // Init fancy File Uploads.
85 $( '.wpforms-file-upload' ).each( function(){
86 var $input = $( this ).find( 'input[type=file]' ),
87 $label = $( this ).find( 'label' ),
88 labelVal = $label.html();
89 $input.on( 'change', function( event ) {
90 var fileName = '';
91 if ( this.files && this.files.length > 1 ) {
92 fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
93 } else if( event.target.value ) {
94 fileName = event.target.value.split( '\\' ).pop();
95 }
96 if ( fileName ) {
97 $label.find( '.fld' ).html( fileName );
98 } else {
99 $label.html( labelVal );
100 }
101 });
102 // Firefox bug fix.
103 $input.on( 'focus', function(){ $input.addClass( 'has-focus' ); }).on( 'blur', function(){ $input.removeClass( 'has-focus' ); });
104 });
105
106 // jquery-confirm defaults.
107 jconfirm.defaults = {
108 closeIcon: true,
109 backgroundDismiss: true,
110 escapeKey: true,
111 animationBounce: 1,
112 useBootstrap: false,
113 theme: 'modern',
114 boxWidth: '400px',
115 animateFromElement: false
116 };
117
118 // Upgrade information modal for upgrade links.
119 $( document ).on( 'click', '.wpforms-upgrade-modal', function() {
120
121 $.alert({
122 title: false,
123 content: wpforms_admin.upgrade_modal,
124 icon: 'fa fa-info-circle',
125 type: 'blue',
126 boxWidth: '565px',
127 buttons: {
128 confirm: {
129 text: wpforms_admin.ok,
130 btnClass: 'btn-confirm',
131 keys: [ 'enter' ],
132 }
133 }
134 });
135 });
136
137 // Lity lightbox.
138 WPFormsAdmin.initLity();
139
140 // Flyout Menu.
141 WPFormsAdmin.initFlyoutMenu();
142
143 // Action available for each binding.
144 $( document ).trigger( 'wpformsReady' );
145 },
146
147 /**
148 * Initialize Choices JS elements.
149 *
150 * @since 1.4.2
151 */
152 initChoicesJS: function() {
153
154 $( '.choicesjs-select' ).each( function() {
155 var $this = $( this ),
156 args = { searchEnabled: false };
157
158 if ( $this.attr( 'multiple' ) ) {
159 args.searchEnabled = true;
160 args.removeItemButton = true;
161 }
162
163 if ( $this.data( 'sorting' ) === 'off' ) {
164 args.shouldSort = false;
165 }
166
167 if ( $this.data( 'search' ) ) {
168 args.searchEnabled = true;
169 }
170
171 // Translate default strings.
172 args.loadingText = wpforms_admin.choicesjs_loading;
173 args.noResultsText = wpforms_admin.choicesjs_no_results;
174 args.noChoicesText = wpforms_admin.choicesjs_no_choices;
175 args.itemSelectText = wpforms_admin.choicesjs_item_select;
176
177 // Function to run once Choices initialises.
178 // We need to reproduce a behaviour like on public-facing area for "Edit Entry" page.
179 args.callbackOnInit = function() {
180
181 var self = this,
182 $element = $( self.passedElement.element ),
183 $input = $( self.input.element ),
184 sizeClass = $element.data( 'size-class' );
185
186 // Add CSS-class for size.
187 if ( sizeClass ) {
188 $( self.containerOuter.element ).addClass( sizeClass );
189 }
190
191 /**
192 * If a multiple select has selected choices - hide a placeholder input.
193 * We use a custom styles like a `.screen-reader-text` for it,
194 * because it avoid an issue with closing a dropdown.
195 */
196 if ( $element.prop( 'multiple' ) ) {
197
198 // On init event.
199 if ( self.getValue( true ).length ) {
200 $input.addClass( self.config.classNames.input + '--hidden' );
201 }
202
203 // On change event.
204 $element.on( 'change', function() {
205
206 self.getValue( true ).length ? $input.addClass( self.config.classNames.input + '--hidden' ) : $input.removeClass( self.config.classNames.input + '--hidden' );
207 } );
208 }
209 };
210
211 $this.data( 'choicesjs', new Choices( $this[0], args ) );
212 } );
213 },
214
215 /**
216 * Initilize checkbox mulit-select columns.
217 *
218 * @since 1.4.2
219 */
220 initCheckboxMultiselectColumns: function() {
221
222 $( document ).on( 'change', '.checkbox-multiselect-columns input', function() {
223
224 var $this = $( this ),
225 $parent = $this.parent(),
226 $container = $this.closest( '.checkbox-multiselect-columns' ),
227 label = $parent.text(),
228 itemID = 'check-item-' + $this.val(),
229 $item = $container.find( '#' + itemID );
230
231 if ( $this.prop( 'checked' ) ) {
232 $this.parent().addClass( 'checked' );
233 if ( ! $item.length ) {
234 $container.find('.second-column ul').append( '<li id="'+itemID+'">'+label+'</li>' );
235 }
236 } else {
237 $this.parent().removeClass( 'checked' );
238 $container.find( '#' + itemID ).remove();
239 }
240 });
241
242 $( document ).on( 'click', '.checkbox-multiselect-columns .all', function( event ) {
243
244 event.preventDefault();
245
246 $( this ).closest( '.checkbox-multiselect-columns' ).find( 'input[type=checkbox]' ).prop( 'checked', true ).trigger( 'change' );
247 $( this ).remove();
248 });
249 },
250
251 //--------------------------------------------------------------------//
252 // Forms Overview
253 //--------------------------------------------------------------------//
254
255 /**
256 * Element bindings for Form Overview page.
257 *
258 * @since 1.3.9
259 */
260 initFormOverview: function() {
261
262 // Confirm form entry deletion and duplications.
263 $( document ).on( 'click', '#wpforms-overview .wp-list-table .delete a, #wpforms-overview .wp-list-table .duplicate a', function( event ) {
264
265 event.preventDefault();
266
267 var url = $( this ).attr( 'href' ),
268 msg = $( this ).parent().hasClass( 'delete' ) ? wpforms_admin.form_delete_confirm : wpforms_admin.form_duplicate_confirm;
269
270 // Trigger alert modal to confirm.
271 $.confirm({
272 title: false,
273 content: msg,
274 backgroundDismiss: false,
275 closeIcon: false,
276 icon: 'fa fa-exclamation-circle',
277 type: 'orange',
278 buttons: {
279 confirm: {
280 text: wpforms_admin.ok,
281 btnClass: 'btn-confirm',
282 keys: [ 'enter' ],
283 action: function(){
284 window.location = url;
285 }
286 },
287 cancel: {
288 text: wpforms_admin.cancel,
289 keys: [ 'esc' ]
290 }
291 }
292 });
293 });
294 },
295
296 //--------------------------------------------------------------------//
297 // Entry Single (Details)
298 //--------------------------------------------------------------------//
299
300 /**
301 * Element bindings for Entries Single (Details) page.
302 *
303 * @since 1.3.9
304 */
305 initEntriesSingle: function() {
306
307 // Entry navigation hotkeys.
308 // We only want to listen on the applicable admin page.
309 if ( 'wpforms-entries' === WPFormsAdmin.getQueryString( 'page' ) && 'details' === WPFormsAdmin.getQueryString( 'view' ) ) {
310 WPFormsAdmin.entryHotkeys();
311 }
312
313 // Confirm entry deletion.
314 $( document ).on( 'click', '#wpforms-entries-single .submitdelete', function( event ) {
315
316 event.preventDefault();
317
318 var url = $( this ).attr( 'href' );
319
320 // Trigger alert modal to confirm.
321 $.confirm({
322 title: false,
323 content: wpforms_admin.entry_delete_confirm,
324 backgroundDismiss: false,
325 closeIcon: false,
326 icon: 'fa fa-exclamation-circle',
327 type: 'orange',
328 buttons: {
329 confirm: {
330 text: wpforms_admin.ok,
331 btnClass: 'btn-confirm',
332 keys: [ 'enter' ],
333 action: function(){
334 window.location = url;
335 }
336 },
337 cancel: {
338 text: wpforms_admin.cancel,
339 keys: [ 'esc' ]
340 }
341 }
342 });
343 });
344
345 // Open Print preview in new window.
346 $( document ).on( 'click', '#wpforms-entries-single .wpforms-entry-print a', function( event ) {
347
348 event.preventDefault();
349
350 window.open( $( this ).attr( 'href' ) );
351 });
352
353 // Toggle displaying empty fields.
354 $( document ).on( 'click', '#wpforms-entries-single .wpforms-empty-field-toggle', function( event ) {
355
356 event.preventDefault();
357
358 // Handle cookie.
359 if ( wpCookies.get( 'wpforms_entry_hide_empty' ) === 'true' ) {
360
361 // User was hiding empty fields, so now display them.
362 wpCookies.remove( 'wpforms_entry_hide_empty' );
363 $( this ).text( wpforms_admin.entry_empty_fields_hide );
364 } else {
365
366 // User was seeing empty fields, so now hide them.
367 wpCookies.set( 'wpforms_entry_hide_empty', 'true', 2592000 ); // 1month.
368 $( this ).text( wpforms_admin.entry_empty_fields_show );
369 }
370
371 $( '.wpforms-entry-field.empty, .wpforms-edit-entry-field.empty' ).toggle();
372 });
373
374 // Display notes editor.
375 $( document ).on( 'click', '#wpforms-entries-single .wpforms-entry-notes-new .add', function( event ) {
376
377 event.preventDefault();
378
379 $( this ).hide().next( 'form' ).slideToggle();
380 });
381
382 // Cancel note.
383 $( document ).on( 'click', '#wpforms-entries-single .wpforms-entry-notes-new .cancel', function( event ) {
384
385 event.preventDefault();
386
387 $( this ).closest( 'form' ).slideToggle();
388 $('.wpforms-entry-notes-new .add').show();
389 });
390
391 // Delete note.
392 $( document ).on( 'click', '#wpforms-entries-single .wpforms-entry-notes-byline .note-delete', function( event ) {
393
394 event.preventDefault();
395
396 var url = $( this ).attr( 'href' );
397
398 // Trigger alert modal to confirm.
399 $.confirm({
400 title: false,
401 content: wpforms_admin.entry_note_delete_confirm,
402 backgroundDismiss: false,
403 closeIcon: false,
404 icon: 'fa fa-exclamation-circle',
405 type: 'orange',
406 buttons: {
407 confirm: {
408 text: wpforms_admin.ok,
409 btnClass: 'btn-confirm',
410 keys: [ 'enter' ],
411 action: function(){
412 window.location = url;
413 }
414 },
415 cancel: {
416 text: wpforms_admin.cancel,
417 keys: [ 'esc' ]
418 }
419 }
420 });
421 });
422 },
423
424 /**
425 * Hotkeys for Entries Single (Details) page.
426 *
427 * j triggers previous entry, k triggers next entry.
428 *
429 * @since 1.4.0
430 */
431 entryHotkeys: function() {
432
433 $( document ).keydown( function( event ) {
434 if ( 74 === event.keyCode && ! WPFormsAdmin.isFormTypeNode( event.target.nodeName ) ) {
435 // j key has been pressed outside of a form element, go to
436 // the previous entry.
437 var prevEntry = $('#wpforms-entry-prev-link').attr( 'href' );
438 if ( '#' !== prevEntry ) {
439 window.location.href = prevEntry;
440 }
441 } else if ( 75 === event.keyCode && ! WPFormsAdmin.isFormTypeNode( event.target.nodeName ) ) {
442 // k key has been pressed outside of a form element, go to
443 // the previous entry.
444 var nextEntry = $('#wpforms-entry-next-link').attr( 'href' );
445 if ( '#' !== nextEntry ) {
446 window.location.href = nextEntry;
447 }
448 }
449 });
450 },
451
452
453 //--------------------------------------------------------------------//
454 // Entry List
455 //--------------------------------------------------------------------//
456
457 /**
458 * Element bindings for Entries List table page.
459 *
460 * @since 1.3.9
461 */
462 initEntriesList: function() {
463
464 $( document ).on( 'click', '#wpforms-entries-table-edit-columns', function( event ) {
465
466 event.preventDefault();
467
468 WPFormsAdmin.entriesListFieldColumn();
469 });
470
471 // Toggle form selector dropdown.
472 $( document ).on( 'click', '#wpforms-entries-list .form-selector .toggle', function( event ) {
473
474 event.preventDefault();
475
476 $( this ).toggleClass( 'active' ).next( '.form-list' ).toggle();
477
478 });
479
480 // Confirm bulk entry deletion.
481 $( document ).on( 'click', '#wpforms-entries-table #doaction', function( event ) {
482
483 var $btn = $( this ),
484 $form = $btn.closest( 'form' ),
485 $table = $form.find( 'table' ),
486 $action = $form.find( 'select[name=action]' ),
487 $checked = $table.find( 'input[name^=entry_id]:checked' );
488
489 if ( 'delete' !== $action.val() || ! $checked.length ) {
490 return;
491 }
492
493 event.preventDefault();
494
495 // Trigger alert modal to confirm.
496 $.confirm( {
497 title: false,
498 content: wpforms_admin.entry_delete_n_confirm.replace( '{entry_count}', $checked.length ),
499 backgroundDismiss: false,
500 closeIcon: false,
501 icon: 'fa fa-exclamation-circle',
502 type: 'orange',
503 buttons: {
504 confirm: {
505 text: wpforms_admin.ok,
506 btnClass: 'btn-confirm',
507 keys: [ 'enter' ],
508 action: function() {
509
510 $form.submit();
511 },
512 },
513 cancel: {
514 text: wpforms_admin.cancel,
515 keys: [ 'esc' ],
516 },
517 },
518 } );
519 } );
520
521 // Confirm entry deletion.
522 $( document ).on( 'click', '#wpforms-entries-list .wp-list-table .delete', function( event ) {
523
524 event.preventDefault();
525
526 var url = $( this ).attr( 'href' );
527
528 // Trigger alert modal to confirm.
529 $.confirm({
530 title: false,
531 content: wpforms_admin.entry_delete_confirm,
532 backgroundDismiss: false,
533 closeIcon: false,
534 icon: 'fa fa-exclamation-circle',
535 type: 'orange',
536 buttons: {
537 confirm: {
538 text: wpforms_admin.ok,
539 btnClass: 'btn-confirm',
540 keys: [ 'enter' ],
541 action: function(){
542 window.location = url;
543 }
544 },
545 cancel: {
546 text: wpforms_admin.cancel,
547 keys: [ 'esc' ]
548 }
549 }
550 });
551 });
552
553 // Toggle entry stars.
554 $( document ).on( 'click', '#wpforms-entries-list .wp-list-table .indicator-star', function( event ) {
555
556 event.preventDefault();
557
558 var $this = $( this ),
559 task = '',
560 total = Number( $( '#wpforms-entries-list .starred-num' ).text() ),
561 id = $this.data( 'id' ),
562 formId = $this.data( 'form-id' );
563
564 if ( $this.hasClass( 'star' ) ) {
565 task = 'star';
566 total++;
567 $this.attr( 'title', wpforms_admin.entry_unstar );
568 } else {
569 task = 'unstar';
570 total--;
571 $this.attr( 'title', wpforms_admin.entry_star );
572 }
573 $this.toggleClass( 'star unstar' );
574 $( '#wpforms-entries-list .starred-num' ).text( total );
575
576 var data = {
577 task : task,
578 action : 'wpforms_entry_list_star',
579 nonce : wpforms_admin.nonce,
580 entryId : id,
581 formId : formId,
582 };
583 $.post( wpforms_admin.ajax_url, data );
584 });
585
586 // Toggle entry read state.
587 $( document ).on( 'click', '#wpforms-entries-list .wp-list-table .indicator-read', function( event ) {
588
589 event.preventDefault();
590
591 var $this = $( this ),
592 task = '',
593 total = Number( $( '#wpforms-entries-list .unread-num' ).text() ),
594 id = $this.data( 'id' );
595
596 if ( $this.hasClass( 'read' ) ) {
597 task = 'read';
598 total--;
599 $this.attr( 'title', wpforms_admin.entry_unread );
600 } else {
601 task = 'unread';
602 total++;
603 $this.attr( 'title', wpforms_admin.entry_read );
604 }
605 $this.toggleClass( 'read unread' );
606 $( '#wpforms-entries-list .unread-num' ).text( total );
607
608 var data = {
609 task : task,
610 action : 'wpforms_entry_list_read',
611 nonce : wpforms_admin.nonce,
612 entryId : id,
613 formId : $this.data( 'form-id' ),
614 };
615 $.post( wpforms_admin.ajax_url, data );
616 });
617
618 // Confirm mass entry deletion - this deletes ALL entries.
619 $( document ).on( 'click', '#wpforms-entries-list .form-details-actions-deleteall', function( event ) {
620
621 event.preventDefault();
622
623 var url = $( this ).attr( 'href' ),
624 $table = $( '#wpforms-entries-table' ),
625 filteredCount = $table.data( 'filtered-count' ) ? parseInt( $table.data( 'filtered-count' ), 10 ) : 0,
626 data = {
627 'action': 'wpforms_entry_list_process_delete_all',
628 'form_id': $table.find( 'input[name="form_id"]' ).val(),
629 'date': $table.find( 'input[name="date"]' ).val(),
630 'search': {
631 'field': $table.find( 'select[name="search[field]"]' ).val(),
632 'comparison': $table.find( 'select[name="search[comparison]"]' ).val(),
633 'term': $table.find( 'input[name="search[term]"]' ).val(),
634 },
635 'nonce': wpforms_admin.nonce,
636 'url': url,
637 };
638
639 // Trigger alert modal to confirm.
640 $.confirm( {
641 title: wpforms_admin.heads_up,
642 content: filteredCount && $( '#wpforms-reset-filter' ).length ? wpforms_admin.entry_delete_n_confirm.replace( '{entry_count}', filteredCount ) : wpforms_admin.entry_delete_all_confirm,
643 backgroundDismiss: false,
644 closeIcon: false,
645 icon: 'fa fa-exclamation-circle',
646 type: 'orange',
647 buttons: {
648 confirm: {
649 text: wpforms_admin.ok,
650 btnClass: 'btn-confirm',
651 keys: [ 'enter' ],
652 action: function() {
653
654 $.get( wpforms_admin.ajax_url, data )
655 .done( function( response ) {
656
657 if ( response.success ) {
658 window.location = ! _.isEmpty( response.data ) ? response.data : url;
659 return;
660 }
661
662 if ( ! _.isEmpty( response.data ) ) {
663 console.error( response.data );
664 }
665 } );
666 }
667 },
668 cancel: {
669 text: wpforms_admin.cancel,
670 keys: [ 'esc' ]
671 }
672 }
673 } );
674 } );
675
676 // Check for new form entries using Heartbeat API.
677 $( document ).on( 'heartbeat-send', function ( event, data ) {
678
679 var $entriesList = $( '#wpforms-entries-list' );
680
681 // Works on entry list page only.
682 if ( ! $entriesList.length || $entriesList.find( '.wpforms-dash-widget' ).length ) {
683 return;
684 }
685
686 var last_entry_id = $entriesList.find( '#wpforms-entries-table' ).data( 'last-entry-id' );
687
688 // When entries list is filtered, there is no data param at all.
689 if ( typeof last_entry_id === 'undefined' ) {
690 return;
691 }
692
693 data.wpforms_new_entries_entry_id = last_entry_id;
694 data.wpforms_new_entries_form_id = $entriesList.find( 'input[name=form_id]' ).val();
695 } );
696
697 // Display entries list notification if Heartbeat API new form entries check is successful.
698 $( document ).on( 'heartbeat-tick', function ( event, data ) {
699
700 var columnCount;
701 var $entriesList = $( '#wpforms-entries-list' );
702
703 // Works on entry list page only.
704 if ( ! $entriesList.length ) {
705 return;
706 }
707
708 if ( ! data.wpforms_new_entries_notification ) {
709 return;
710 }
711
712 columnCount = $entriesList.find( '.wp-list-table thead tr' ).first().children().length;
713
714 if ( ! $entriesList.find( '.new-entries-notification' ).length ) {
715 $entriesList.find( '.wp-list-table thead' )
716 .append( '<tr class="new-entries-notification"><td colspan="' + columnCount + '"><a href=""></a></td></tr>' );
717 }
718
719 $entriesList.find( '.new-entries-notification a' )
720 .text( data.wpforms_new_entries_notification )
721 .slideDown( {
722 duration: 500,
723 start : function () {
724 $( this ).css( {
725 display: 'block'
726 } );
727 }
728 } );
729 } );
730 },
731
732 /**
733 * Display settings to change the entry list field columns/
734 *
735 * @since 1.4.0
736 */
737 entriesListFieldColumn: function() {
738
739 $.alert({
740 title: wpforms_admin.entry_field_columns,
741 boxWidth: '500px',
742 content: s.iconSpinner + $( '#wpforms-field-column-select' ).html(),
743 onContentReady: function() {
744
745 var $modalContent = this.$content,
746 $select = $modalContent.find( 'select' ),
747 choices = new Choices( $select[0], {
748 shouldSort: false,
749 removeItemButton: true,
750 loadingText: wpforms_admin.choicesjs_loading,
751 noResultsText: wpforms_admin.choicesjs_no_results,
752 noChoicesText: wpforms_admin.choicesjs_no_choices,
753 itemSelectText: wpforms_admin.choicesjs_item_select,
754 callbackOnInit: function() {
755 $modalContent.find( '.fa' ).remove();
756 $modalContent.find( 'form' ).show();
757 }
758 });
759
760 $( '.jconfirm-content-pane, .jconfirm-box' ).css( 'overflow','visible' );
761
762 choices.passedElement.element.addEventListener( 'change', function() {
763
764 // Without `true` parameter dropdown will be hidden together with modal window when `Enter` is pressed.
765 choices.hideDropdown( true );
766 }, false );
767 },
768 buttons: {
769 confirm: {
770 text: wpforms_admin.save_refresh,
771 btnClass: 'btn-confirm',
772 keys: [ 'enter' ],
773 action: function() {
774 this.$content.find( 'form' ).submit();
775 }
776 },
777 cancel: {
778 text: wpforms_admin.cancel,
779 keys: [ 'esc' ]
780 }
781 }
782 });
783 },
784
785 //--------------------------------------------------------------------//
786 // Welcome Activation.
787 //--------------------------------------------------------------------//
788
789 /**
790 * Welcome activation page.
791 *
792 * @since 1.3.9
793 */
794 initWelcome: function() {
795
796 // Open modal and play How To video.
797 $( document ).on( 'click', '#wpforms-welcome .play-video', function( event ) {
798
799 event.preventDefault();
800
801 var video = '<div class="video-container"><iframe width="1280" height="720" src="https://www.youtube-nocookie.com/embed/o2nE1P74WxQ?rel=0&amp;showinfo=0&amp;autoplay=1" frameborder="0" allowfullscreen></iframe></div>';
802
803 $.dialog({
804 title: false,
805 content: video,
806 closeIcon: true,
807 boxWidth: '70%'
808 });
809 });
810 },
811
812 //--------------------------------------------------------------------//
813 // Addons List.
814 //--------------------------------------------------------------------//
815
816 /**
817 * Element bindings for Addons List page.
818 *
819 * @since 1.3.9
820 */
821 initAddons: function() {
822
823 // Only run on the addons page.
824 if ( ! $( '#wpforms-admin-addons' ).length ) {
825 return;
826 }
827
828 WPFormsAdmin.matchHeightAddonBlocks();
829
830 // Addons searching.
831 if ( $( '#wpforms-admin-addons-list' ).length ) {
832 var addonSearch = new List( 'wpforms-admin-addons-list', {
833 valueNames: [ 'addon-name' ] } );
834
835 $( '#wpforms-admin-addons-search' ).on( 'keyup', function() {
836 var searchTerm = $( this ).val(),
837 $heading = $( '#addons-heading' );
838
839 if ( searchTerm ) {
840 $heading.text( wpforms_admin.addon_search );
841 } else {
842 $heading.text( $heading.data( 'text' ) );
843 }
844
845 addonSearch.search( searchTerm );
846 } );
847 }
848
849 $( window ).on( 'resize', WPFormsAdmin.matchHeightAddonBlocks );
850
851 // Toggle an addon state.
852 $( document ).on( 'click', '#wpforms-admin-addons .addon-item button', function( event ) {
853
854 event.preventDefault();
855
856 if ( $( this ).hasClass( 'disabled' ) ) {
857 return false;
858 }
859
860 WPFormsAdmin.addonToggle( $( this ) );
861 } );
862 },
863
864 /**
865 * Change plugin/addon state.
866 *
867 * @since 1.6.3
868 *
869 * @param {string} plugin Plugin slug or URL for download.
870 * @param {string} state State status activate|deactivate|install.
871 * @param {string} pluginType Plugin type addon or plugin.
872 * @param {Function} callback Callback for get result from AJAX.
873 */
874 setAddonState: function( plugin, state, pluginType, callback ) {
875
876 var actions = {
877 'activate': 'wpforms_activate_addon',
878 'install': 'wpforms_install_addon',
879 'deactivate': 'wpforms_deactivate_addon',
880 },
881 action = actions[ state ];
882
883 if ( ! action ) {
884 return;
885 }
886
887 var data = {
888 action: action,
889 nonce: wpforms_admin.nonce,
890 plugin: plugin,
891 type: pluginType,
892 };
893
894 $.post( wpforms_admin.ajax_url, data, function( res ) {
895
896 callback( res );
897 } ).fail( function( xhr ) {
898
899 console.log( xhr.responseText );
900 } );
901 },
902
903 /**
904 * Toggle addon state.
905 *
906 * @since 1.3.9
907 */
908 addonToggle: function( $btn ) {
909
910 var $addon = $btn.closest( '.addon-item' ),
911 plugin = $btn.attr( 'data-plugin' ),
912 pluginType = $btn.attr( 'data-type' ),
913 action,
914 cssClass,
915 statusText,
916 buttonText,
917 errorText,
918 successText;
919
920 if ( $btn.hasClass( 'status-go-to-url' ) ) {
921 // Open url in new tab.
922 window.open( $btn.attr('data-plugin'), '_blank' );
923 return;
924 }
925
926 $btn.prop( 'disabled', true ).addClass( 'loading' );
927 $btn.html( s.iconSpinner );
928
929 if ( $btn.hasClass( 'status-active' ) ) {
930 // Deactivate.
931 action = 'wpforms_deactivate_addon';
932 cssClass = 'status-inactive';
933 if ( pluginType === 'plugin' ) {
934 cssClass += ' button button-secondary';
935 }
936 statusText = wpforms_admin.addon_inactive;
937 buttonText = wpforms_admin.addon_activate;
938 errorText = wpforms_admin.addon_deactivate;
939 if ( pluginType === 'addon' ) {
940 buttonText = s.iconActivate + buttonText;
941 errorText = s.iconDeactivate + errorText;
942 }
943
944 } else if ( $btn.hasClass( 'status-inactive' ) ) {
945 // Activate.
946 action = 'wpforms_activate_addon';
947 cssClass = 'status-active';
948 if ( pluginType === 'plugin' ) {
949 cssClass += ' button button-secondary disabled';
950 }
951 statusText = wpforms_admin.addon_active;
952 buttonText = wpforms_admin.addon_deactivate;
953 if ( pluginType === 'addon' ) {
954 buttonText = s.iconDeactivate + buttonText;
955 errorText = s.iconActivate + wpforms_admin.addon_activate;
956 } else if ( pluginType === 'plugin' ) {
957 buttonText = wpforms_admin.addon_activated;
958 errorText = wpforms_admin.addon_activate;
959 }
960
961 } else if ( $btn.hasClass( 'status-download' ) ) {
962 // Install & Activate.
963 action = 'wpforms_install_addon';
964 cssClass = 'status-active';
965 if ( pluginType === 'plugin' ) {
966 cssClass += ' button disabled';
967 }
968 statusText = wpforms_admin.addon_active;
969 buttonText = wpforms_admin.addon_activated;
970 errorText = s.iconInstall;
971 if ( pluginType === 'addon' ) {
972 buttonText = s.iconActivate + wpforms_admin.addon_deactivate;
973 errorText += wpforms_admin.addon_install;
974 }
975
976 } else {
977 return;
978 }
979
980 var data = {
981 action: action,
982 nonce : wpforms_admin.nonce,
983 plugin: plugin,
984 type : pluginType,
985 };
986 $.post( wpforms_admin.ajax_url, data, function( res ) {
987
988 if ( res.success ) {
989 if ( 'wpforms_install_addon' === action ) {
990 $btn.attr( 'data-plugin', res.data.basename );
991 successText = res.data.msg;
992 if ( ! res.data.is_activated ) {
993 statusText = wpforms_admin.addon_inactive;
994 buttonText = 'plugin' === pluginType ? wpforms_admin.addon_activate : s.iconActivate + wpforms_admin.addon_activate;
995 cssClass = 'plugin' === pluginType ? 'status-inactive button button-secondary' : 'status-inactive';
996 }
997 } else {
998 successText = res.data;
999 }
1000 $addon.find( '.actions' ).append( '<div class="msg success">' + successText + '</div>' );
1001 $addon.find( 'span.status-label' )
1002 .removeClass( 'status-active status-inactive status-download' )
1003 .addClass( cssClass )
1004 .removeClass( 'button button-primary button-secondary disabled' )
1005 .text( statusText );
1006 $btn
1007 .removeClass( 'status-active status-inactive status-download' )
1008 .removeClass( 'button button-primary button-secondary disabled' )
1009 .addClass( cssClass ).html( buttonText );
1010 } else {
1011 if ( 'object' === typeof res.data ) {
1012 if ( pluginType === 'addon' ) {
1013 $addon.find( '.actions' ).append( '<div class="msg error">' + wpforms_admin.addon_error + '</div>' );
1014 } else {
1015 $addon.find( '.actions' ).append( '<div class="msg error">' + wpforms_admin.plugin_error + '</div>' );
1016 }
1017 } else {
1018 $addon.find( '.actions' ).append( '<div class="msg error">'+res.data+'</div>' );
1019 }
1020
1021 if ( 'wpforms_install_addon' === action && 'plugin' === pluginType ) {
1022 $btn.addClass( 'status-go-to-url' ).removeClass( 'status-download' );
1023 }
1024
1025 $btn.html( errorText );
1026 }
1027
1028 $btn.prop( 'disabled', false ).removeClass( 'loading' );
1029
1030 // Automatically clear addon messages after 3 seconds.
1031 setTimeout( function() {
1032 $( '.addon-item .msg' ).remove();
1033 }, 3000 );
1034
1035 }).fail( function( xhr ) {
1036 console.log( xhr.responseText );
1037 });
1038 },
1039
1040 /**
1041 * Display all addon boxes as the same height.
1042 *
1043 * @since 1.6.3
1044 */
1045 matchHeightAddonBlocks: function() {
1046
1047 $( '.addon-item .details' ).matchHeight( { byrow: false, property: 'height' } );
1048 },
1049
1050 //--------------------------------------------------------------------//
1051 // Settings.
1052 //--------------------------------------------------------------------//
1053
1054 /**
1055 * Element bindings for Settings page.
1056 *
1057 * @since 1.3.9
1058 */
1059 initSettings: function() {
1060
1061 // On ready events.
1062 $( document ).on( 'wpformsReady', function() {
1063
1064 // Only proceed if we're on the settings page.
1065 if ( ! $( '#wpforms-settings' ).length ) {
1066 return;
1067 }
1068
1069 // Watch for hashes and scroll to if found.
1070 // Display all addon boxes as the same height.
1071 var integrationFocus = WPFormsAdmin.getQueryString( 'wpforms-integration' ),
1072 jumpTo = WPFormsAdmin.getQueryString( 'jump' );
1073
1074 if ( integrationFocus ) {
1075 $( 'body' ).animate({
1076 scrollTop: $( '#wpforms-integration-'+integrationFocus ).offset().top
1077 }, 1000 );
1078 } else if ( jumpTo ) {
1079 $( 'body' ).animate({
1080 scrollTop: $( '#'+jumpTo ).offset().top
1081 }, 1000 );
1082 }
1083
1084 // Settings conditional logic.
1085 $( '.wpforms-admin-settings-form' ).conditions( [
1086 // Misc > Disable User Cookies visibility.
1087 {
1088 conditions: {
1089 element: '#wpforms-setting-gdpr',
1090 type: 'checked',
1091 operator: 'is'
1092 },
1093 actions: {
1094 if: {
1095 element: '#wpforms-setting-row-gdpr-disable-uuid,#wpforms-setting-row-gdpr-disable-details',
1096 action: 'show'
1097 },
1098 else : {
1099 element: '#wpforms-setting-row-gdpr-disable-uuid,#wpforms-setting-row-gdpr-disable-details',
1100 action: 'hide'
1101 }
1102 },
1103 effect: 'appear'
1104 },
1105
1106 // CAPTCHA > Type.
1107 {
1108 conditions: {
1109 element: 'input[name=captcha-provider]:checked',
1110 type: 'value',
1111 operator: '=',
1112 condition: 'hcaptcha',
1113 },
1114 actions: {
1115 if: [
1116 {
1117 element: '.wpforms-setting-row',
1118 action: 'show',
1119 },
1120 {
1121 element: '.wpforms-setting-recaptcha, #wpforms-setting-row-captcha-provider .desc, #wpforms-setting-row-recaptcha-site-key, #wpforms-setting-row-recaptcha-secret-key, #wpforms-setting-row-recaptcha-fail-msg',
1122 action: 'hide',
1123 },
1124 ],
1125 },
1126 effect: 'appear',
1127 },
1128 {
1129 conditions: {
1130 element: 'input[name=captcha-provider]:checked',
1131 type: 'value',
1132 operator: '=',
1133 condition: 'recaptcha',
1134 },
1135 actions: {
1136 if: [
1137 {
1138 element: '.wpforms-setting-row',
1139 action: 'show',
1140 },
1141 {
1142 element: '#wpforms-setting-row-captcha-provider .desc, #wpforms-setting-row-hcaptcha-heading, #wpforms-setting-row-hcaptcha-site-key, #wpforms-setting-row-hcaptcha-secret-key, #wpforms-setting-row-hcaptcha-fail-msg',
1143 action: 'hide',
1144 },
1145 ],
1146 },
1147 effect: 'appear',
1148 },
1149 {
1150 conditions: {
1151 element: 'input[name=captcha-provider]:checked',
1152 type: 'value',
1153 operator: '=',
1154 condition: 'none',
1155 },
1156 actions: {
1157 if: [
1158 {
1159 element: '.wpforms-setting-row',
1160 action: 'hide',
1161 },
1162 {
1163 element: '.wpforms-setting-captcha-heading, #wpforms-setting-row-captcha-provider, #wpforms-setting-row-captcha-provider .desc',
1164 action: 'show',
1165 },
1166 ],
1167 },
1168 effect: 'appear',
1169 },
1170 ] );
1171 });
1172
1173 // Form styles plugin setting.
1174 $( document ).on( 'change', '#wpforms-setting-disable-css', function() {
1175
1176 WPFormsAdmin.settingsFormStylesAlert( $( this ).val() );
1177 });
1178
1179 // Image upload fields.
1180 $( document ).on( 'click', '.wpforms-setting-row-image button', function( event ) {
1181
1182 event.preventDefault();
1183
1184 WPFormsAdmin.imageUploadModal( $( this ) );
1185 });
1186
1187 // Verify license key.
1188 $( document ).on( 'click', '#wpforms-setting-license-key-verify', function( event ) {
1189
1190 event.preventDefault();
1191
1192 WPFormsAdmin.licenseVerify( $( this ) );
1193 });
1194
1195 // Deactivate license key.
1196 $( document ).on( 'click', '#wpforms-setting-license-key-deactivate', function( event ) {
1197
1198 event.preventDefault();
1199
1200 WPFormsAdmin.licenseDeactivate( $( this ) );
1201 });
1202
1203 // Refresh license key.
1204 $( document ).on( 'click', '#wpforms-setting-license-key-refresh', function( event ) {
1205
1206 event.preventDefault();
1207
1208 WPFormsAdmin.licenseRefresh( $( this ) );
1209 });
1210
1211 /**
1212 * @todo Refactor providers settings tab. Code below is legacy.
1213 */
1214
1215 // Integration connect.
1216 $( document ).on( 'click', '.wpforms-settings-provider-connect', function( event ) {
1217
1218 event.preventDefault();
1219
1220 var button = $( this );
1221
1222 WPFormsAdmin.integrationConnect( button );
1223 });
1224
1225 // Integration account disconnect.
1226 $( document ).on( 'click', '.wpforms-settings-provider-accounts-list a', function( event ) {
1227
1228 event.preventDefault();
1229
1230 WPFormsAdmin.integrationDisconnect( $( this ) );
1231 });
1232
1233 // Integration individual display toggling.
1234 $( document ).on( 'click', '.wpforms-settings-provider:not(.focus-out) .wpforms-settings-provider-header:not(.disabled)', function( event ) {
1235
1236 event.preventDefault();
1237
1238 var $this = $( this );
1239
1240 $this
1241 .addClass( 'disabled' )
1242 .parent()
1243 .find( '.wpforms-settings-provider-accounts' )
1244 .slideToggle( '', function() {
1245 $this.removeClass( 'disabled' );
1246 $this.parent().find( '.wpforms-settings-provider-logo i' ).toggleClass( 'fa-chevron-right fa-chevron-down' );
1247 } );
1248 } );
1249
1250 // Integration accounts display toggling.
1251 $( document ).on( 'click', '.wpforms-settings-provider-accounts-toggle a', function( event ) {
1252
1253 event.preventDefault();
1254
1255 var $connectFields = $( this ).parent().next( '.wpforms-settings-provider-accounts-connect' );
1256 $connectFields.find( 'input[type=text], input[type=password]' ).val('');
1257 $connectFields.stop().slideToggle();
1258 });
1259
1260 // CAPTCHA settings page: type toggling.
1261 $( document ).on( 'change', '#wpforms-setting-row-captcha-provider input', function() {
1262
1263 var $preview = $( '#wpforms-setting-row-captcha-preview' );
1264
1265 if ( 'hcaptcha' === this.value ) {
1266 $preview.removeClass( 'wpforms-hidden' );
1267 } else if ( 'none' === this.value ) {
1268 $preview.addClass( 'wpforms-hidden' );
1269 } else {
1270 $( '#wpforms-setting-row-recaptcha-type input:checked' ).trigger( 'change' );
1271 }
1272
1273 if ( $preview.find( '.wpforms-captcha-preview' ).length ) {
1274 $preview.find( '.wpforms-captcha-preview' ).empty();
1275 $preview.find( '.wpforms-captcha-placeholder' ).removeClass( 'wpforms-hidden' );
1276 }
1277 } );
1278
1279 // CAPTCHA settings page: reCATCHA type toggling.
1280 $( document ).on( 'change', '#wpforms-setting-row-recaptcha-type input', function() {
1281
1282 $( '#wpforms-setting-row-captcha-preview' ).toggleClass( 'wpforms-hidden', 'v2' !== this.value );
1283 $( '#wpforms-setting-row-recaptcha-v3-threshold' ).toggleClass( 'wpforms-hidden', 'v3' !== this.value );
1284 } );
1285 },
1286
1287 /**
1288 * Alert users if they change form styles to something that may give
1289 * unexpected results.
1290 *
1291 * @since 1.5.0
1292 */
1293 settingsFormStylesAlert: function( value ) {
1294
1295 if ( '2' === value ) {
1296 var msg = wpforms_admin.settings_form_style_base;
1297 } else if ( '3' === value ) {
1298 var msg = wpforms_admin.settings_form_style_none;
1299 } else {
1300 return;
1301 }
1302
1303 $.alert({
1304 title: wpforms_admin.heads_up,
1305 content: msg,
1306 backgroundDismiss: false,
1307 closeIcon: false,
1308 icon: 'fa fa-exclamation-circle',
1309 type: 'orange',
1310 buttons: {
1311 confirm: {
1312 text: wpforms_admin.ok,
1313 btnClass: 'btn-confirm',
1314 keys: [ 'enter' ],
1315 }
1316 }
1317 });
1318 },
1319
1320 /**
1321 * Image upload modal window.
1322 *
1323 * @since 1.3.0
1324 */
1325 imageUploadModal: function( el ) {
1326
1327 if ( s.media_frame ) {
1328 s.media_frame.open();
1329 return;
1330 }
1331
1332 var $setting = $( el ).closest( '.wpforms-setting-field' );
1333
1334 s.media_frame = wp.media.frames.wpforms_media_frame = wp.media({
1335 className: 'media-frame wpforms-media-frame',
1336 frame: 'select',
1337 multiple: false,
1338 title: wpforms_admin.upload_image_title,
1339 library: {
1340 type: 'image'
1341 },
1342 button: {
1343 text: wpforms_admin.upload_image_button
1344 }
1345 });
1346
1347 s.media_frame.on( 'select', function(){
1348 // Grab our attachment selection and construct a JSON representation of the model.
1349 var media_attachment = s.media_frame.state().get( 'selection' ).first().toJSON();
1350
1351 // Send the attachment URL to our custom input field via jQuery.
1352 $setting.find( 'input[type=text]' ).val( media_attachment.url );
1353 $setting.find( 'img' ).remove();
1354 $setting.prepend( '<img src="'+media_attachment.url+'">' );
1355 });
1356
1357 // Now that everything has been set, let's open up the frame.
1358 s.media_frame.open();
1359 },
1360
1361 /**
1362 * Verify a license key.
1363 *
1364 * @since 1.3.9
1365 */
1366 licenseVerify: function( el ) {
1367
1368 var $this = $( el ),
1369 $row = $this.closest( '.wpforms-setting-row' ),
1370 buttonWidth = $this.outerWidth(),
1371 buttonLabel = $this.text(),
1372 data = {
1373 action: 'wpforms_verify_license',
1374 nonce: wpforms_admin.nonce,
1375 license: $('#wpforms-setting-license-key').val()
1376 };
1377
1378 $this.html( s.iconSpinner ).css( 'width', buttonWidth ).prop( 'disabled', true );
1379
1380 $.post( wpforms_admin.ajax_url, data, function( res ) {
1381
1382 var icon = 'fa fa-check-circle',
1383 color = 'green',
1384 msg;
1385
1386 if ( res.success ){
1387 msg = res.data.msg;
1388 $row.find( '.type, .desc, #wpforms-setting-license-key-deactivate' ).show();
1389 $row.find( '.type strong' ).text( res.data.type );
1390 $('.wpforms-license-notice').remove();
1391 } else {
1392 icon = 'fa fa-exclamation-circle';
1393 color = 'orange';
1394 msg = res.data;
1395 $row.find( '.type, .desc, #wpforms-setting-license-key-deactivate' ).hide();
1396 }
1397
1398 $.alert({
1399 title: false,
1400 content: msg,
1401 icon: icon,
1402 type: color,
1403 buttons: {
1404 confirm: {
1405 text: wpforms_admin.ok,
1406 btnClass: 'btn-confirm',
1407 keys: [ 'enter' ],
1408 }
1409 }
1410 });
1411
1412 $this.html( buttonLabel ).css( 'width', 'auto' ).prop( 'disabled', false );
1413
1414 }).fail( function( xhr ) {
1415 console.log( xhr.responseText );
1416 });
1417 },
1418
1419 /**
1420 * Verify a license key.
1421 *
1422 * @since 1.3.9
1423 */
1424 licenseDeactivate: function( el ) {
1425
1426 var $this = $( el ),
1427 $row = $this.closest( '.wpforms-setting-row' ),
1428 buttonWidth = $this.outerWidth(),
1429 buttonLabel = $this.text(),
1430 data = {
1431 action: 'wpforms_deactivate_license',
1432 nonce: wpforms_admin.nonce
1433 };
1434
1435 $this.html( s.iconSpinner ).css( 'width', buttonWidth ).prop( 'disabled', true );
1436
1437 $.post( wpforms_admin.ajax_url, data, function( res ) {
1438
1439 var icon = 'fa fa-info-circle',
1440 color = 'blue',
1441 msg = res.data;
1442
1443 if ( res.success ){
1444 $row.find( '#wpforms-setting-license-key' ).val('');
1445 $row.find( '.type, .desc, #wpforms-setting-license-key-deactivate' ).hide();
1446 } else {
1447 icon = 'fa fa-exclamation-circle';
1448 color = 'orange';
1449 }
1450
1451 $.alert({
1452 title: false,
1453 content: msg,
1454 icon: icon,
1455 type: color,
1456 buttons: {
1457 confirm: {
1458 text: wpforms_admin.ok,
1459 btnClass: 'btn-confirm',
1460 keys: [ 'enter' ],
1461 }
1462 }
1463 });
1464
1465 $this.html( buttonLabel ).css( 'width', 'auto' ).prop( 'disabled', false );
1466
1467 }).fail( function( xhr ) {
1468 console.log( xhr.responseText );
1469 });
1470 },
1471
1472 /**
1473 * Refresh a license key.
1474 *
1475 * @since 1.3.9
1476 */
1477 licenseRefresh: function( el ) {
1478
1479 var $this = $( el ),
1480 $row = $this.closest( '.wpforms-setting-row' ),
1481 data = {
1482 action: 'wpforms_refresh_license',
1483 nonce: wpforms_admin.nonce,
1484 license: $('#wpforms-setting-license-key').val()
1485 };
1486
1487 $.post( wpforms_admin.ajax_url, data, function( res ) {
1488
1489 var icon = 'fa fa-check-circle',
1490 color = 'green',
1491 msg;
1492
1493 if ( res.success ){
1494 msg = res.data.msg;
1495 $row.find( '.type strong' ).text( res.data.type );
1496 } else {
1497 icon = 'fa fa-exclamation-circle';
1498 color = 'orange';
1499 msg = res.data;
1500 $row.find( '.type, .desc, #wpforms-setting-license-key-deactivate' ).hide();
1501 }
1502
1503 $.alert({
1504 title: false,
1505 content: msg,
1506 icon: icon,
1507 type: color,
1508 buttons: {
1509 confirm: {
1510 text: wpforms_admin.ok,
1511 btnClass: 'btn-confirm',
1512 keys: [ 'enter' ],
1513 }
1514 }
1515 });
1516
1517 }).fail( function( xhr ) {
1518 console.log( xhr.responseText );
1519 });
1520 },
1521
1522 /**
1523 * Connect integration provider account.
1524 *
1525 * @param $btn Button (.wpforms-settings-provider-connect) that was clicked to establish connection.
1526 *
1527 * @since 1.3.9
1528 */
1529 integrationConnect: function( $btn ) {
1530
1531 var buttonWidth = $btn.outerWidth(),
1532 buttonLabel = $btn.text(),
1533 $provider = $btn.closest( '.wpforms-settings-provider' ),
1534 data = {
1535 action : 'wpforms_settings_provider_add_' + $btn.data( 'provider' ),
1536 data : $btn.closest( 'form' ).serialize(),
1537 provider: $btn.data( 'provider' ),
1538 nonce : wpforms_admin.nonce,
1539 },
1540 errorMessage = wpforms_admin.provider_auth_error;
1541
1542 $btn.html( 'Connecting...' ).css( 'width', buttonWidth ).prop( 'disabled', true );
1543
1544 $.post( wpforms_admin.ajax_url, data, function( response ) {
1545
1546 if ( response.success ) {
1547 $provider.find( '.wpforms-settings-provider-accounts-list ul' ).append( response.data.html );
1548 $provider.addClass( 'connected' );
1549 $btn.closest( '.wpforms-settings-provider-accounts-connect' ).slideToggle();
1550
1551 } else {
1552
1553 if (
1554 Object.prototype.hasOwnProperty.call( response, 'data' ) &&
1555 Object.prototype.hasOwnProperty.call( response.data, 'error_msg' )
1556 ) {
1557 errorMessage += '<br>' + response.data.error_msg;
1558 }
1559
1560 WPFormsAdmin.integrationError( errorMessage );
1561 }
1562
1563 } ).fail( function() {
1564
1565 WPFormsAdmin.integrationError( errorMessage );
1566 } ).complete( function() {
1567
1568 $btn.html( buttonLabel ).css( 'width', 'auto' ).prop( 'disabled', false );
1569 } );
1570 },
1571
1572 /**
1573 * Remove integration provider account.
1574 *
1575 * @since 1.3.9
1576 */
1577 integrationDisconnect: function( el ) {
1578
1579 var $this = $( el ),
1580 $provider = $this.parents( '.wpforms-settings-provider' ),
1581 data = {
1582 action : 'wpforms_settings_provider_disconnect_' + $this.data( 'provider' ),
1583 provider: $this.data( 'provider' ),
1584 key : $this.data( 'key' ),
1585 nonce : wpforms_admin.nonce,
1586 },
1587 errorMessage = wpforms_admin.provider_delete_error;
1588
1589 $.confirm( {
1590 title: wpforms_admin.heads_up,
1591 content: wpforms_admin.provider_delete_confirm,
1592 backgroundDismiss: false,
1593 closeIcon: false,
1594 icon: 'fa fa-exclamation-circle',
1595 type: 'orange',
1596 buttons: {
1597 confirm: {
1598 text: wpforms_admin.ok,
1599 btnClass: 'btn-confirm',
1600 keys: [ 'enter' ],
1601 action: function() {
1602
1603 $.post( wpforms_admin.ajax_url, data, function( response ) {
1604
1605 if ( response.success ) {
1606 $this.parent().parent().remove();
1607
1608 // Hide Connected status label if no more integrations are linked.
1609 var numberOfIntegrations = $provider.find( '.wpforms-settings-provider-accounts-list li' ).length;
1610
1611 if ( typeof numberOfIntegrations === 'undefined' || numberOfIntegrations === 0 ) {
1612 $provider.removeClass( 'connected' );
1613 }
1614
1615 } else {
1616
1617 if (
1618 Object.prototype.hasOwnProperty.call( response, 'data' ) &&
1619 Object.prototype.hasOwnProperty.call( response.data, 'error_msg' )
1620 ) {
1621 errorMessage += '<br>' + response.data.error_msg;
1622 }
1623
1624 WPFormsAdmin.integrationError( errorMessage );
1625 }
1626 } ).fail( function() {
1627
1628 WPFormsAdmin.integrationError( errorMessage );
1629 } );
1630 },
1631 },
1632 cancel: {
1633 text: wpforms_admin.cancel,
1634 keys: [ 'esc' ],
1635 },
1636 },
1637 } );
1638 },
1639
1640 /**
1641 * Error handling.
1642 *
1643 * @since 1.6.4
1644 *
1645 * @param {string} error Error message.
1646 */
1647 integrationError: function( error ) {
1648
1649 $.alert( {
1650 title: false,
1651 content: error,
1652 icon: 'fa fa-exclamation-circle',
1653 type: 'orange',
1654 buttons: {
1655 confirm: {
1656 text: wpforms_admin.ok,
1657 btnClass: 'btn-confirm',
1658 keys: [ 'enter' ],
1659 },
1660 },
1661 } );
1662 },
1663
1664 //--------------------------------------------------------------------//
1665 // Tools.
1666 //--------------------------------------------------------------------//
1667
1668 /**
1669 * Element bindings for Tools page.
1670 *
1671 * @since 1.4.2
1672 */
1673 initTools: function() {
1674
1675 // Run import for a specific provider.
1676 $( document ).on( 'click', '#wpforms-ssl-verify', function( event ) {
1677
1678 event.preventDefault();
1679
1680 WPFormsAdmin.verifySSLConnection();
1681 });
1682
1683 // Run import for a specific provider.
1684 $( document ).on( 'click', '#wpforms-importer-forms-submit', function( event ) {
1685
1686 event.preventDefault();
1687
1688 // Check to confirm user as selected a form.
1689 if ( $( '#wpforms-importer-forms input:checked' ).length ) {
1690
1691 var ids = [];
1692 $( '#wpforms-importer-forms input:checked' ).each( function ( i ) {
1693 ids[i] = $( this ).val();
1694 });
1695
1696 if ( ! wpforms_admin.isPro ) {
1697 // We need to analyze the forms before starting the
1698 // actual import.
1699 WPFormsAdmin.analyzeForms( ids );
1700 } else {
1701 // Begin the import process.
1702 WPFormsAdmin.importForms( ids );
1703 }
1704
1705 } else {
1706
1707 // User didn't actually select a form so alert them.
1708 $.alert({
1709 title: false,
1710 content: wpforms_admin.importer_forms_required,
1711 icon: 'fa fa-info-circle',
1712 type: 'blue',
1713 buttons: {
1714 confirm: {
1715 text: wpforms_admin.ok,
1716 btnClass: 'btn-confirm',
1717 keys: [ 'enter' ],
1718 }
1719 }
1720 });
1721 }
1722 });
1723
1724 // Continue import after analyzing.
1725 $( document ).on( 'click', '#wpforms-importer-continue-submit', function( event ) {
1726
1727 event.preventDefault();
1728
1729 WPFormsAdmin.importForms( s.formIDs );
1730 });
1731 },
1732
1733 /**
1734 * Perform test connection to verify that the current web host
1735 * can successfully make outbound SSL connections.
1736 *
1737 * @since 1.4.5
1738 */
1739 verifySSLConnection: function() {
1740
1741 var $btn = $( '#wpforms-ssl-verify' ),
1742 btnLabel = $btn.text(),
1743 btnWidth = $btn.outerWidth(),
1744 $settings = $btn.parent(),
1745 data = {
1746 action: 'wpforms_verify_ssl',
1747 nonce: wpforms_admin.nonce
1748 };
1749
1750 $btn.css( 'width', btnWidth ).prop( 'disabled', true ).text( wpforms_admin.testing );
1751
1752 // Trigger AJAX to test connection
1753 $.post( wpforms_admin.ajax_url, data, function( res ) {
1754
1755 console.log( res );
1756
1757 // Remove any previous alerts.
1758 $settings.find( '.wpforms-alert, .wpforms-ssl-error' ).remove();
1759
1760 if ( res.success ){
1761 $btn.before( '<div class="wpforms-alert wpforms-alert-success">' + res.data.msg + '</div>' );
1762 }
1763
1764 if ( ! res.success && res.data.msg ) {
1765 $btn.before( '<div class="wpforms-alert wpforms-alert-danger">' + res.data.msg + '</div>' );
1766 }
1767
1768 if ( ! res.success && res.data.debug ) {
1769 $btn.before( '<div class="wpforms-ssl-error pre-error">' + res.data.debug + '</div>' );
1770 }
1771
1772 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
1773 });
1774 },
1775
1776 /**
1777 * Begins the process of analyzing the forms.
1778 *
1779 * This runs for non-Pro installs to check if any of the forms to be
1780 * imported contain fields
1781 * not currently available.
1782 *
1783 * @since 1.4.2
1784 */
1785 analyzeForms: function( forms ) {
1786
1787 var $processAnalyze = $( '#wpforms-importer-analyze' );
1788
1789 // Display total number of forms we have to import.
1790 $processAnalyze.find( '.form-total' ).text( forms.length );
1791 $processAnalyze.find( '.form-current' ).text( '1' );
1792
1793 // Hide the form select section.
1794 $( '#wpforms-importer-forms' ).hide();
1795
1796 // Show Analyze status.
1797 $processAnalyze.show();
1798
1799 // Create global analyze queue.
1800 s.analyzeQueue = forms;
1801 s.analyzed = 0;
1802 s.analyzeUpgrade = [];
1803 s.formIDs = forms;
1804
1805 // Analyze the first form in the queue.
1806 WPFormsAdmin.analyzeForm();
1807 },
1808
1809 /**
1810 * Analyze a single form from the queue.
1811 *
1812 * @since 1.4.2
1813 */
1814 analyzeForm: function() {
1815
1816 var $analyzeSettings = $( '#wpforms-importer-analyze' ),
1817 formID = _.first( s.analyzeQueue ),
1818 provider = WPFormsAdmin.getQueryString( 'provider' ),
1819 data = {
1820 action: 'wpforms_import_form_' + provider,
1821 analyze: 1,
1822 form_id: formID,
1823 nonce: wpforms_admin.nonce
1824 };
1825
1826 // Trigger AJAX analyze for this form.
1827 $.post( wpforms_admin.ajax_url, data, function( res ) {
1828
1829 if ( res.success ){
1830
1831 if ( ! _.isEmpty( res.data.upgrade_plain ) || ! _.isEmpty( res.data.upgrade_omit ) ) {
1832 s.analyzeUpgrade.push({
1833 name: res.data.name,
1834 fields: _.union( res.data.upgrade_omit, res.data.upgrade_plain )
1835 });
1836 }
1837
1838 // Remove this form ID from the queue.
1839 s.analyzeQueue = _.without( s.analyzeQueue, formID );
1840 s.analyzed++;
1841
1842 if ( _.isEmpty( s.analyzeQueue ) ) {
1843
1844 if ( _.isEmpty( s.analyzeUpgrade ) ) {
1845 // Continue to import forms as no Pro fields were
1846 // found.
1847 WPFormsAdmin.importForms( s.formIDs );
1848 } else {
1849 // We found Pro fields, so alert the user.
1850 var upgradeDetails = wp.template( 'wpforms-importer-upgrade' );
1851 $analyzeSettings.find( '.upgrade' ).append( upgradeDetails( s.analyzeUpgrade ) );
1852 $analyzeSettings.find( '.upgrade' ).show();
1853 $analyzeSettings.find( '.process-analyze' ).hide();
1854 }
1855
1856 } else {
1857 // Analyze next form in the queue.
1858 $analyzeSettings.find( '.form-current' ).text( s.analyzed+1 );
1859 WPFormsAdmin.analyzeForm();
1860 }
1861 }
1862 });
1863 },
1864
1865 /**
1866 * Begins the process of importing the forms.
1867 *
1868 * @since 1.4.2
1869 */
1870 importForms: function( forms ) {
1871
1872 var $processSettings = $( '#wpforms-importer-process' );
1873
1874 // Display total number of forms we have to import.
1875 $processSettings.find( '.form-total' ).text( forms.length );
1876 $processSettings.find( '.form-current' ).text( '1' );
1877
1878 // Hide the form select and form analyze sections.
1879 $( '#wpforms-importer-forms, #wpforms-importer-analyze' ).hide();
1880
1881 // Show processing status.
1882 $processSettings.show();
1883
1884 // Create global import queue.
1885 s.importQueue = forms;
1886 s.imported = 0;
1887
1888 // Import the first form in the queue.
1889 WPFormsAdmin.importForm();
1890 },
1891
1892 /**
1893 * Imports a single form from the import queue.
1894 *
1895 * @since 1.4.2
1896 */
1897 importForm: function() {
1898
1899 var $processSettings = $( '#wpforms-importer-process' ),
1900 formID = _.first( s.importQueue ),
1901 provider = WPFormsAdmin.getQueryString( 'provider' ),
1902 data = {
1903 action: 'wpforms_import_form_' + provider,
1904 form_id: formID,
1905 nonce: wpforms_admin.nonce
1906 };
1907
1908 // Trigger AJAX import for this form.
1909 $.post( wpforms_admin.ajax_url, data, function( res ) {
1910
1911 if ( res.success ){
1912 var statusUpdate;
1913
1914 if ( res.data.error ) {
1915 statusUpdate = wp.template( 'wpforms-importer-status-error' );
1916 } else {
1917 statusUpdate = wp.template( 'wpforms-importer-status-update' );
1918 }
1919
1920 $processSettings.find( '.status' ).prepend( statusUpdate( res.data ) );
1921 $processSettings.find( '.status' ).show();
1922
1923 // Remove this form ID from the queue.
1924 s.importQueue = _.without( s.importQueue, formID );
1925 s.imported++;
1926
1927 if ( _.isEmpty( s.importQueue ) ) {
1928 $processSettings.find( '.process-count' ).hide();
1929 $processSettings.find( '.forms-completed' ).text( s.imported );
1930 $processSettings.find( '.process-completed' ).show();
1931 } else {
1932 // Import next form in the queue.
1933 $processSettings.find( '.form-current' ).text( s.imported+1 );
1934 WPFormsAdmin.importForm();
1935 }
1936 }
1937 });
1938 },
1939
1940 //--------------------------------------------------------------------//
1941 // Upgrades (Tabs view).
1942 //--------------------------------------------------------------------//
1943
1944 /**
1945 * Element bindings for Tools page.
1946 *
1947 * @since 1.4.3
1948 */
1949 initUpgrades: function() {
1950
1951 // Prepare to run the v1.4.3 upgrade routine.
1952 $( document ).on( 'click', '#wpforms-upgrade-143 button', function( event ) {
1953
1954 event.preventDefault();
1955
1956 var $this = $( this ),
1957 buttonWidth = $this.outerWidth(),
1958 $status = $( '#wpforms-upgrade-143 .status' ),
1959 data = {
1960 action: 'wpforms_upgrade_143',
1961 nonce: wpforms_admin.nonce,
1962 init: true,
1963 incomplete: $this.data( 'incomplete' )
1964 };
1965
1966 // Change the button to indicate we are doing initial processing.
1967 $this.html( s.iconSpinner ).css( 'width', buttonWidth ).prop( 'disabled', true );
1968
1969 // Get the total number of entries, then kick off the routine.
1970 $.post( wpforms_admin.ajax_url, data, function( res ) {
1971 if ( res.success ){
1972
1973 // Set initial values.
1974 s.upgraded = Number( res.data.upgraded );
1975 s.upgradeTotal = Number( res.data.total );
1976 var percent = Math.round( ( Number( s.upgraded ) / Number( s.upgradeTotal ) ) * 100 );
1977
1978 // Show the status area.
1979 $this.remove();
1980 $status.find( '.bar' ).css( 'width', percent + '%' );
1981 $status.show().find( '.total' ).text( s.upgradeTotal );
1982 $status.find( '.current' ).text( s.upgraded );
1983 $status.find( '.percent' ).text( percent + '%' );
1984
1985 // Begin the actual upgrade routine.
1986 WPFormsAdmin.upgrade143();
1987 }
1988 });
1989 });
1990 },
1991
1992 /**
1993 * The v1.4.3 entry fields upgrade routine.
1994 *
1995 * @since 1.4.3
1996 */
1997 upgrade143: function() {
1998
1999 var $status = $( '#wpforms-upgrade-143 .status' ),
2000 data = {
2001 action: 'wpforms_upgrade_143',
2002 nonce: wpforms_admin.nonce,
2003 upgraded: s.upgraded
2004 };
2005
2006 // Get the total number of entries, then kick off the routine.
2007 $.post( wpforms_admin.ajax_url, data, function( res ) {
2008 if ( res.success ){
2009
2010 s.upgraded = Number( s.upgraded ) + Number( res.data.count );
2011 var percent = Math.round( ( Number( s.upgraded ) / Number( s.upgradeTotal ) ) * 100 );
2012
2013 // Update progress bar.
2014 $status.find( '.bar' ).css( 'width', percent + '%' );
2015
2016 if ( Number( res.data.count ) < 10 ) {
2017 // This batch completed the upgrade routine.
2018 $status.find( '.progress-bar' ).addClass( 'complete' );
2019 $status.find( '.msg' ).text( wpforms_admin.upgrade_completed );
2020 } else {
2021
2022 $status.find( '.current' ).text( s.upgraded );
2023 $status.find( '.percent' ).text( percent + '%' );
2024
2025 // Batch the next round of entries.
2026 WPFormsAdmin.upgrade143();
2027 }
2028 }
2029 });
2030 },
2031
2032 /**
2033 * Element bindings for Flyout Menu.
2034 *
2035 * @since 1.5.7
2036 */
2037 initFlyoutMenu: function() {
2038
2039 // Flyout Menu Elements.
2040 var $flyoutMenu = $( '#wpforms-flyout' );
2041
2042 if ( $flyoutMenu.length === 0 ) {
2043 return;
2044 }
2045
2046 var $head = $flyoutMenu.find( '.wpforms-flyout-head' ),
2047 $sullie = $head.find( 'img' ),
2048 menu = {
2049 state: 'inactive',
2050 srcInactive: $sullie.attr( 'src' ),
2051 srcActive: $sullie.data( 'active' ),
2052 };
2053
2054 // Click on the menu head icon.
2055 $head.on( 'click', function( e ) {
2056
2057 e.preventDefault();
2058
2059 if ( menu.state === 'active' ) {
2060 $flyoutMenu.removeClass( 'opened' );
2061 $sullie.attr( 'src', menu.srcInactive );
2062 menu.state = 'inactive';
2063 } else {
2064 $flyoutMenu.addClass( 'opened' );
2065 $sullie.attr( 'src', menu.srcActive );
2066 menu.state = 'active';
2067 }
2068 } );
2069
2070 // Page elements and other values.
2071 var $wpfooter = $( '#wpfooter' );
2072
2073 if ( $wpfooter.length === 0 ) {
2074 return;
2075 }
2076
2077 var $overlap = $( '#wpforms-overview, #wpforms-entries-list, #wpforms-tools.wpforms-tools-tab-action-scheduler' ),
2078 wpfooterTop = $wpfooter.offset().top,
2079 wpfooterBottom = wpfooterTop + $wpfooter.height(),
2080 overlapBottom = $overlap.length > 0 ? $overlap.offset().top + $overlap.height() + 85 : 0;
2081
2082 // Hide menu if scrolled down to the bottom of the page.
2083 $( window ).on( 'resize scroll', _.debounce( function( e ) {
2084
2085 var viewTop = $( window ).scrollTop(),
2086 viewBottom = viewTop + $( window ).height();
2087
2088 if ( wpfooterBottom <= viewBottom && wpfooterTop >= viewTop && overlapBottom > viewBottom ) {
2089 $flyoutMenu.addClass( 'out' );
2090 } else {
2091 $flyoutMenu.removeClass( 'out' );
2092 }
2093 }, 50 ) );
2094
2095 $( window ).trigger( 'scroll' );
2096 },
2097
2098 /**
2099 * Lity improvements.
2100 *
2101 * @since 1.5.8
2102 */
2103 initLity: function() {
2104
2105 // Use `data-lity-srcset` opener's attribute for add srcset to full image in opened lightbox.
2106 $( document ).on( 'lity:ready', function( event, instance ) {
2107
2108 var $el = instance.element(),
2109 $opener = instance.opener(),
2110 srcset = typeof $opener !== 'undefined' ? $opener.data( 'lity-srcset' ) : '';
2111
2112 if ( typeof srcset !== 'undefined' && srcset !== '' ) {
2113 $el.find( '.lity-content img' ).attr( 'srcset', srcset );
2114 }
2115 } );
2116 },
2117
2118 //--------------------------------------------------------------------//
2119 // Helper functions.
2120 //--------------------------------------------------------------------//
2121
2122 /**
2123 * Return if the target nodeName is a form element.
2124 *
2125 * @since 1.4.0
2126 */
2127 isFormTypeNode: function( name ) {
2128
2129 name = name || false;
2130
2131 if ( 'TEXTAREA' === name || 'INPUT' === name || 'SELECT' === name ){
2132 return true;
2133 }
2134
2135 return false;
2136 },
2137
2138 /**
2139 * Get query string in a URL.
2140 *
2141 * @since 1.3.9
2142 */
2143 getQueryString: function( name ) {
2144
2145 var match = new RegExp( '[?&]' + name + '=([^&]*)' ).exec( window.location.search );
2146 return match && decodeURIComponent( match[1].replace(/\+/g, ' ') );
2147 },
2148
2149 /**
2150 * Debug output helper.
2151 *
2152 * @since 1.4.4
2153 * @param msg
2154 */
2155 debug: function( msg ) {
2156
2157 if ( WPFormsAdmin.isDebug() ) {
2158 if ( typeof msg === 'object' || msg.constructor === Array ) {
2159 console.log( 'WPForms Debug:' );
2160 console.log( msg );
2161 } else {
2162 console.log( 'WPForms Debug: ' + msg );
2163 }
2164 }
2165 },
2166
2167 /**
2168 * Is debug mode.
2169 *
2170 * @since 1.4.4
2171 */
2172 isDebug: function() {
2173
2174 return ( window.location.hash && '#wpformsdebug' === window.location.hash );
2175 }
2176 };
2177
2178 WPFormsAdmin.init();
2179
2180 window.WPFormsAdmin = WPFormsAdmin;
2181
2182 })( jQuery );
2183