Contact Form by WPForms – Drag & Drop Form Builder for WordPress - Version 1.3.1

Version Description

  • Added: Smart Tags for author ID, email, and name
  • Added: Carbon Copy (CC) support for form notifications; enable in WPForms Settings
  • Fixed: Field duplication issues
  • Fixed: TinyMCE "Add Form" button not opening modal with dynamic TinyMCE instances
  • Fixed: Email formatting issues when using plain text formatting
  • Fixed: Number field validation tripping when number submitted is zero
  • Fixed: reCAPTCHA validation passing when reCAPTCHA left blank
  • Fixed: Dropdown field size not reflecting in builder
Download this release

Release Info

Developer jaredatch
Plugin Icon 128x128 Contact Form by WPForms – Drag & Drop Form Builder for WordPress
Version 1.3.1
Comparing to
See all releases

Code changes from version 1.3.0 to 1.3.1

assets/css/admin-builder-fields.css CHANGED
@@ -366,7 +366,7 @@
366
 
367
  #wpforms-panel-fields .wpforms-field-option-row-choices ul,
368
  #wpforms-panel-fields .wpforms-field-option-row-questions ul {
369
- margin-bottom: 0;
370
  }
371
 
372
  #wpforms-panel-fields .wpforms-field-option-row-choices li,
@@ -496,13 +496,15 @@
496
  display: none;
497
  }
498
 
499
- /* Payment Multiple Items */
500
 
501
- #wpforms-panel-fields .wpforms-field-option-payment-multiple .wpforms-field-option-row-choices li input[type=text] {
 
502
  width: 46%;
503
  }
504
 
505
- #wpforms-panel-fields .wpforms-field-option-payment-multiple .wpforms-field-option-row-choices li input[type=text].value {
 
506
  display: block;
507
  margin: 0 0 0 5px;
508
  width: 22%;
@@ -587,6 +589,10 @@
587
  opacity: 1;
588
  }
589
 
 
 
 
 
590
  #wpforms-panel-fields .wpforms-field .wpforms-field-delete {
591
  color: #d22222;
592
  position: absolute;
@@ -664,7 +670,7 @@
664
  line-height: 1.3;
665
  }
666
 
667
- #wpforms-panel-fields .wpforms-field input[type=checkbox],
668
  #wpforms-panel-fields .wpforms-field input[type=radio] {
669
  border: 1px solid #ccc;
670
  background-color: #fff;
@@ -794,6 +800,24 @@
794
  margin: 12px 0 0 0;
795
  }
796
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
797
  /* Divider field */
798
  #wpforms-panel-fields .wpforms-field-divider {
799
  border-top: 1px solid #ddd;
366
 
367
  #wpforms-panel-fields .wpforms-field-option-row-choices ul,
368
  #wpforms-panel-fields .wpforms-field-option-row-questions ul {
369
+ margin-bottom: 0;
370
  }
371
 
372
  #wpforms-panel-fields .wpforms-field-option-row-choices li,
496
  display: none;
497
  }
498
 
499
+ /* Payment Multiple Items and Dropdown Items */
500
 
501
+ #wpforms-panel-fields .wpforms-field-option-payment-multiple .wpforms-field-option-row-choices li input[type=text],
502
+ #wpforms-panel-fields .wpforms-field-option-payment-select .wpforms-field-option-row-choices li input[type=text] {
503
  width: 46%;
504
  }
505
 
506
+ #wpforms-panel-fields .wpforms-field-option-payment-multiple .wpforms-field-option-row-choices li input[type=text].value,
507
+ #wpforms-panel-fields .wpforms-field-option-payment-select .wpforms-field-option-row-choices li input[type=text].value {
508
  display: block;
509
  margin: 0 0 0 5px;
510
  width: 22%;
589
  opacity: 1;
590
  }
591
 
592
+ #wpforms-panel-fields .wpforms-field.wpforms-field-pagebreak .wpforms-field-duplicate {
593
+ display: none;
594
+ }
595
+
596
  #wpforms-panel-fields .wpforms-field .wpforms-field-delete {
597
  color: #d22222;
598
  position: absolute;
670
  line-height: 1.3;
671
  }
672
 
673
+ #wpforms-panel-fields .wpforms-field input[type=checkbox],
674
  #wpforms-panel-fields .wpforms-field input[type=radio] {
675
  border: 1px solid #ccc;
676
  background-color: #fff;
800
  margin: 12px 0 0 0;
801
  }
802
 
803
+ /* Dropdown and Dropdown Items payment field */
804
+ #wpforms-panel-fields .wpforms-field-select.size-large .primary-input,
805
+ #wpforms-panel-fields .wpforms-field-payment-select.size-large .primary-input {
806
+ width: 100%;
807
+ }
808
+
809
+ #wpforms-panel-fields .wpforms-field-select .primary-input,
810
+ #wpforms-panel-fields .wpforms-field-select.size-medium .primary-input,
811
+ #wpforms-panel-fields .wpforms-field-payment-select .primary-input,
812
+ #wpforms-panel-fields .wpforms-field-payment-select.size-medium .primary-input {
813
+ width: 65%;
814
+ }
815
+
816
+ #wpforms-panel-fields .wpforms-field-select.size-small .primary-input,
817
+ #wpforms-panel-fields .wpforms-field-payment-select.size-small .primary-input {
818
+ width: 25%;
819
+ }
820
+
821
  /* Divider field */
822
  #wpforms-panel-fields .wpforms-field-divider {
823
  border-top: 1px solid #ddd;
assets/css/flatpickr.min.css CHANGED
@@ -1 +1,13 @@
1
- .flatpickr-input{cursor:pointer;z-index:1}.flatpickr-mobileInput{opacity:0;visibility:hidden;position:absolute;width:0;height:0;box-sizing:border-box;padding:0}.flatpickr-calendar{background:#fff;display:none;text-align:center;padding:0;border:1px solid #e6e6e6;font-size:14px;border-radius:3px;position:absolute;max-width:247px;min-width:200px}.flatpickr-calendar.open{opacity:1;z-index:99999;display:inline-block}.flatpickr-calendar.inline{display:table;margin-top:2px;position:relative}.flatpickr-calendar.static{position:relative}.flatpickr-calendar.static.open{display:block}.flatpickr-calendar.hasWeeks{max-width:300px}.flatpickr-calendar:after,.flatpickr-calendar:before{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-month,.flatpickr-next-month i,.flatpickr-prev-month i{position:relative}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:after,.flatpickr-calendar.arrowTop:before{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:after,.flatpickr-calendar.arrowBottom:before{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-month{background:0 0;color:rgba(0,0,0,.9);fill:rgba(0,0,0,.9);padding:4px 0 0;padding:0\9;text-align:center}.flatpickr-next-month,.flatpickr-prev-month{text-decoration:none;cursor:pointer}.flatpickr-next-month svg,.flatpickr-prev-month svg{width:14px;position:absolute;top:9px;top:0\9}.flatpickr-next-month svg path,.flatpickr-prev-month svg path{fill:inherit}.flatpickr-next-month svg:hover,.flatpickr-prev-month svg:hover{fill:#f99595}.flatpickr-next-month:hover,.flatpickr-prev-month:hover{color:#f99595}.flatpickr-prev-month svg{left:5px}.flatpickr-next-month svg{right:5px}.flatpickr-current-month{font-size:135%;font-weight:300;color:inherit;position:relative;display:inline-block;line-height:1}.flatpickr-current-month .cur-month{font-weight:700;color:inherit}.flatpickr-current-month .cur-year{background:0 0;box-sizing:border-box;color:inherit;cursor:default;padding:0;margin:0;width:3.2em;display:inline;font-size:inherit;font-weight:300;line-height:inherit;height:initial;border:0;border-radius:0;vertical-align:initial}.flatpickr-current-month .cur-year:hover{background:rgba(0,0,0,.05)}.flatpickr-weekdays{background:0 0;text-align:center;overflow:hidden}.flatpickr-days{padding-top:1px;outline:0;text-align:left}.flatpickr-day{background:0 0;border:1px solid transparent;border-radius:150px;box-sizing:border-box;color:#393939;cursor:pointer;display:inline-block;position:relative;font-weight:300;width:35px;height:35px;line-height:35px;margin:0;text-align:center;transition:50ms all ease-out}.flatpickr-day.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.nextMonthDay:focus,.flatpickr-day.nextMonthDay:hover,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.prevMonthDay:hover,.flatpickr-day:focus,.flatpickr-day:hover{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#f99595}.flatpickr-day.today:focus,.flatpickr-day.today:hover{border-color:#f99595;background:#f99595;color:#fff}.flatpickr-day.selected,.flatpickr-day.selected:focus,.flatpickr-day.selected:hover{background:#446cb3;color:#fff;border-color:#446cb3}.flatpickr-day.disabled,.flatpickr-day.disabled:hover,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.nextMonthDay,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.prevMonthDay{color:rgba(57,57,57,.3);background:0 0;border-color:transparent;cursor:default}span.flatpickr-weekday{cursor:default;font-size:90%;color:rgba(0,0,0,.54);height:24px;line-height:24px;margin:0;background:0 0;text-align:center;display:block;float:left;width:14.28%;font-weight:700}.flatpickr-weekwrapper{display:inline-block;float:left}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 .25rem;border-right:1px solid #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%}.flatpickr-weekwrapper span.flatpickr-day{display:block;width:100%}.flatpickr-rContainer{display:inline-block;max-width:247px}.flatpickr-time{overflow:auto;text-align:center;border-top:0;outline:0;display:block;display:flex}.flatpickr-am-pm,.flatpickr-time input,.flatpickr-time-separator{height:38px;display:inline-block;line-height:38px;color:#393939}.flatpickr-time input{-moz-appearance:textfield;background:0 0;box-shadow:none;border:0;border-radius:0;flex:1;width:33%;min-width:33%;text-align:center;margin:0;padding:0;cursor:pointer;font-weight:700}.flatpickr-time input.flatpickr-minute{width:26%;font-weight:300}.flatpickr-time input.flatpickr-second{font-weight:300}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time input:focus,.flatpickr-time input:hover{-moz-appearance:number-input;background:#e6e6e6}.flatpickr-time.has-seconds input[type=number]{width:25%;min-width:25%}.hasTime .flatpickr-days,.hasWeeks .flatpickr-days{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.hasWeeks .flatpickr-days{border-left:0}.flatpickr-rContainer+.flatpickr-time{border-top:1px solid #e6e6e6}.flatpickr-am-pm{outline:0;width:21%;padding:0 2%;cursor:pointer;text-align:left;font-weight:300}.flatpickr-am-pm:focus,.flatpickr-am-pm:hover{background:#f0f0f0}@media all and (-ms-high-contrast:none){.flatpickr-month{padding:0}.flatpickr-month svg{top:0!important}}
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .flatpickr-input{cursor:pointer;z-index:1}.flatpickr-mobileInput{opacity:0;visibility:hidden;position:absolute;width:0;height:0;box-sizing:border-box;padding:0}.flatpickr-calendar{background:#fff;display:none;max-height:0;opacity:0;visibility:hidden;text-align:center;padding:0;animation:none;direction:ltr;border:1px solid #e6e6e6;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:242px;box-sizing:border-box;}.flatpickr-calendar.open{display:inline-block;opacity:1;visibility:visible;max-height:320px;z-index:99999;animation:flatpickrFadeInDown .5s cubic-bezier(0,1,.5,1)}.flatpickr-calendar.inline{opacity:1;visibility:visible;max-height:320px;display:block;position:relative}.flatpickr-calendar.static{display:none;position:relative;}.flatpickr-calendar.static.open{display:block}.flatpickr-calendar.hasWeeks{width:auto}.flatpickr-calendar.dateIsPicked.hasTime .flatpickr-time{height:38px}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-month{background:transparent;color:rgba(0,0,0,0.8);fill:rgba(0,0,0,0.8);height:28px;line-height:24px;text-align:center;position:relative;user-select:none}.flatpickr-prev-month,.flatpickr-next-month{text-decoration:none;cursor:pointer;position:absolute;top:10px;height:16px;line-height:16px;}.flatpickr-prev-month i,.flatpickr-next-month i{position:relative}.flatpickr-prev-month.flatpickr-prev-month,.flatpickr-next-month.flatpickr-prev-month{/*
2
+ /*rtl:begin:ignore*/left:5px;/*
3
+ /*rtl:end:ignore*/}/*
4
+ /*rtl:begin:ignore*/
5
+ /*
6
+ /*rtl:end:ignore*/
7
+ .flatpickr-prev-month.flatpickr-next-month,.flatpickr-next-month.flatpickr-next-month{/*
8
+ /*rtl:begin:ignore*/right:5px;/*
9
+ /*rtl:end:ignore*/}/*
10
+ /*rtl:begin:ignore*/
11
+ /*
12
+ /*rtl:end:ignore*/
13
+ .flatpickr-prev-month svg,.flatpickr-next-month svg{width:14px;}.flatpickr-prev-month svg path,.flatpickr-next-month svg path{transition:fill .1s;fill:inherit}.flatpickr-prev-month svg:hover,.flatpickr-next-month svg:hover{fill:#f64747}.flatpickr-prev-month:hover,.flatpickr-next-month:hover{color:#959ea9}.numInputWrapper{position:relative;height:auto;}.numInputWrapper input,.numInputWrapper span{display:inline-block}.numInputWrapper input{width:100%}.numInputWrapper span{position:absolute;right:0;width:14px;padding:0 4px 0 2px;height:50%;line-height:50%;opacity:0;z-index:9;cursor:pointer;border:1px solid rgba(57,57,57,0.05);box-sizing:border-box;}.numInputWrapper span:hover{background:rgba(0,0,0,0.1)}.numInputWrapper span:active{background:rgba(0,0,0,0.2)}.numInputWrapper span:after{display:block;content:"";position:absolute;top:33%}.numInputWrapper span.arrowUp{top:0;border-bottom:0;}.numInputWrapper span.arrowUp:after{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid rgba(57,57,57,0.6)}.numInputWrapper span.arrowDown{top:50%;}.numInputWrapper span.arrowDown:after{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(57,57,57,0.6)}.numInputWrapper span svg{width:inherit;height:auto;}.numInputWrapper span svg path{fill:rgba(0,0,0,0.5)}.numInputWrapper:hover{background:rgba(0,0,0,0.05);}.numInputWrapper:hover span{opacity:1}.flatpickr-current-month{font-size:135%;line-height:inherit;font-weight:300;color:inherit;position:absolute;width:75%;left:12.5%;top:5px;display:inline-block;text-align:center;}.flatpickr-current-month span.cur-month{font-family:inherit;font-weight:700;color:inherit;display:inline-block;padding-left:7px}.flatpickr-current-month .numInputWrapper{width:6ch;width:7ch\0;display:inline-block;}.flatpickr-current-month .numInputWrapper span.arrowUp:after{border-bottom-color:rgba(0,0,0,0.8)}.flatpickr-current-month .numInputWrapper span.arrowDown:after{border-top-color:rgba(0,0,0,0.8)}.flatpickr-current-month input.cur-year{background:transparent;box-sizing:border-box;color:inherit;cursor:default;padding:0 0 0 .5ch;margin:0;display:inline;font-size:inherit;font-family:inherit;font-weight:300;line-height:inherit;height:initial;border:0;border-radius:0;vertical-align:initial;}.flatpickr-current-month input.cur-year:focus{outline:0}.flatpickr-current-month input.cur-year[disabled],.flatpickr-current-month input.cur-year[disabled]:hover{font-size:100%;color:rgba(0,0,0,0.5);background:transparent;pointer-events:none}.flatpickr-weekdays{background:transparent;text-align:center;overflow:hidden}.flatpickr-days{padding:1px;outline:0;text-align:left;width:240px;box-sizing:border-box;display:inline-block;display:flex;flex-wrap:wrap;}.flatpickr-day{background:none;border:1px solid transparent;border-radius:150px;box-sizing:border-box;color:#393939;cursor:pointer;display:inline-block;display:inline-block\9;position:relative;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;font-weight:300;width:14.2857143%;flex-basis:14.2857143%;max-width:34px;height:34px;line-height:34px;margin:1px 0 0 0;text-align:center;transition:50ms all ease-out;}.flatpickr-day.inRange,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.today.inRange,.flatpickr-day.nextMonthDay.today.inRange,.flatpickr-day:hover,.flatpickr-day.prevMonthDay:hover,.flatpickr-day.nextMonthDay:hover,.flatpickr-day:focus,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.nextMonthDay:focus{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#959ea9;}.flatpickr-day.today:hover,.flatpickr-day.today:focus{border-color:#959ea9;background:#959ea9;color:#fff}.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected:focus,.flatpickr-day.startRange:focus,.flatpickr-day.endRange:focus,.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover,.flatpickr-day.selected.prevMonthDay,.flatpickr-day.startRange.prevMonthDay,.flatpickr-day.endRange.prevMonthDay,.flatpickr-day.selected.nextMonthDay,.flatpickr-day.startRange.nextMonthDay,.flatpickr-day.endRange.nextMonthDay{background:#569ff7;color:#fff;border-color:#569ff7}.flatpickr-day.selected.startRange,.flatpickr-day.startRange.startRange,.flatpickr-day.endRange.startRange{border-radius:50px 0 0 50px}.flatpickr-day.selected.endRange,.flatpickr-day.startRange.endRange,.flatpickr-day.endRange.endRange{border-radius:0 50px 50px 0}.flatpickr-day.inRange{border-radius:0}.flatpickr-day.disabled,.flatpickr-day.disabled:hover,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.notAllowed.nextMonthDay{color:rgba(57,57,57,0.3);background:transparent;border-color:transparent;cursor:default}span.flatpickr-weekday{cursor:default;font-size:90%;color:rgba(0,0,0,0.54);height:24px;line-height:24px;margin:0;background:transparent;text-align:center;display:block;float:left;width:14.28%;font-weight:bold}.flatpickr-weekwrapper{display:inline-block;float:left;}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 12px;border-right:1px solid #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%}.flatpickr-weekwrapper span.flatpickr-day{display:block;width:100%;max-width:none}.flatpickr-innerContainer{display:block;display:flex;}.flatpickr-innerContainer:after{display:inline-block;content:"";clear:both}.flatpickr-rContainer{display:inline-block}.flatpickr-time{text-align:center;border-top:0;outline:0;display:block;height:0;line-height:36px;max-height:36px;box-sizing:border-box;overflow:hidden;transition:height .33s cubic-bezier(0,1,.5,1);display:flex;}.flatpickr-time:after{content:"";display:table;clear:both}.flatpickr-time .numInputWrapper{flex:1;width:40%;height:36px;float:left;}.flatpickr-time .numInputWrapper span.arrowUp:after{border-bottom-color:#393939}.flatpickr-time .numInputWrapper span.arrowDown:after{border-top-color:#393939}.flatpickr-time.hasSeconds .numInputWrapper{width:26%}.flatpickr-time.time24hr .numInputWrapper{width:49%}.flatpickr-time input{background:transparent;box-shadow:none;border:0;border-radius:0;text-align:center;margin:0;padding:0;height:inherit;line-height:inherit;cursor:pointer;color:#393939;font-size:14px;position:relative;box-sizing:border-box;}.flatpickr-time input.flatpickr-hour{font-weight:bold}.flatpickr-time input.flatpickr-minute,.flatpickr-time input.flatpickr-second{font-weight:400}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time .flatpickr-time-separator,.flatpickr-time .flatpickr-am-pm{height:inherit;display:inline-block;float:left;line-height:inherit;color:#393939;font-weight:bold;width:2%}.flatpickr-time .flatpickr-am-pm{outline:0;width:18%;cursor:pointer;text-align:center;font-weight:400;}.flatpickr-time .flatpickr-am-pm:hover,.flatpickr-time .flatpickr-am-pm:focus{background:#f0f0f0}.hasWeeks .flatpickr-days,.hasTime .flatpickr-days{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.hasWeeks .flatpickr-days{border-left:0}.dateIsPicked .flatpickr-innerContainer + .flatpickr-time{border-top:1px solid #e6e6e6}@media all and (-ms-high-contrast:none){.flatpickr-days{width:256px}.flatpickr-month{padding:0;}.flatpickr-month svg{top:0 !important}}@-moz-keyframes flatpickrFadeInDown{from{opacity:0;transform:translate3d(0,-20px,0)}to{opacity:1;transform:none}}@-webkit-keyframes flatpickrFadeInDown{from{opacity:0;transform:translate3d(0,-20px,0)}to{opacity:1;transform:none}}@-o-keyframes flatpickrFadeInDown{from{opacity:0;transform:translate3d(0,-20px,0)}to{opacity:1;transform:none}}@keyframes flatpickrFadeInDown{from{opacity:0;transform:translate3d(0,-20px,0)}to{opacity:1;transform:none}}
assets/js/admin-builder.js CHANGED
@@ -69,12 +69,12 @@
69
  s.formData = $('#wpforms-builder-form').serializeObject();
70
  s.pagebreakTop = $('.wpforms-pagebreak-top').length;
71
  s.pagebreakBottom = $('.wpforms-pagebreak-bottom').length;
72
-
73
  // @todo - performance testing
74
  //wpforms_builder.saved_state = $('#wpforms-builder-form').serializeJSON();
75
  //jQuery.parseJSON(json);
76
  //console.log( $(':input').length);
77
-
78
  // If there is a section configured, display it. Otherwise
79
  // we show the first panel by default.
80
  $('.wpforms-panel').each(function(index, el) {
@@ -97,6 +97,7 @@
97
  WPFormsBuilder.fieldChoiceSortable('radio');
98
  WPFormsBuilder.fieldChoiceSortable('checkbox');
99
  WPFormsBuilder.fieldChoiceSortable('payment-multiple');
 
100
 
101
  // Load match heights
102
  $('.wpforms-template').matchHeight({
@@ -134,7 +135,7 @@
134
 
135
  // Clone form title to setup page
136
  $('#wpforms-setup-name').val($('#wpforms-panel-field-settings-form_title').val());
137
-
138
  // jquery-confirmd defaults
139
  jconfirm.defaults = {
140
  confirmButton: wpforms_builder.ok,
@@ -152,7 +153,7 @@
152
  * @since 1.0.0
153
  */
154
  bindUIActions: function() {
155
-
156
  // General Panels
157
  WPFormsBuilder.bindUIActionsPanels();
158
 
@@ -237,7 +238,7 @@
237
 
238
  // Create smart tags list
239
  var smartTagList = '<ul class="smart-tags-list-display">';
240
-
241
  if (type === 'fields' || type === 'all') {
242
  if (!fields) {
243
  smartTagList += '<li class="heading">'+wpforms_builder.fields_unavailable+'</li>';
@@ -296,7 +297,7 @@
296
  } else {
297
  $input.insertAtCaret('{'+meta+'}');
298
  }
299
-
300
  // remove list, all done!
301
  $list.slideUp(400, function() {
302
  $list.remove();
@@ -316,9 +317,9 @@
316
  $panelBtn = $('.wpforms-panel-'+panel+'-button');
317
 
318
  if (!$panel.hasClass('active')) {
319
-
320
  $(document).trigger('wpformsPanelSwitch', panel);
321
-
322
  if (!wpforms_panel_switch) {
323
  return false;
324
  }
@@ -372,7 +373,7 @@
372
  WPFormsBuilder.setupTitleFocus(e, wpf.getQueryString('view'));
373
  });
374
  $(document).on('wpformsPanelSwitch', WPFormsBuilder.setupTitleFocus);
375
-
376
  // Select and apply a template
377
  $(document).on('click', '.wpforms-template-select', function(e) {
378
  WPFormsBuilder.templateSelect(this, e);
@@ -382,15 +383,15 @@
382
  $(document).on('click', '.wpforms-trigger-blank', function(e) {
383
  e.preventDefault();
384
  $('#wpforms-template-blank .wpforms-template-select').trigger('click');
385
- });
386
 
387
  // Keep Setup title and settings title instances the same
388
  $(document).on('input', '#wpforms-panel-field-settings-form_title', function() {
389
  $('#wpforms-setup-name').val($('#wpforms-panel-field-settings-form_title').val());
390
- });
391
  $(document).on('input', '#wpforms-setup-name', function() {
392
  $('#wpforms-panel-field-settings-form_title').val($('#wpforms-setup-name').val()).trigger('input');
393
- });
394
  },
395
 
396
  /**
@@ -430,7 +431,7 @@
430
  if ($parent.hasClass('pro-modal')){
431
  return;
432
  }
433
-
434
  // Disable all template buttons
435
  $templateBtns.prop('disabled', true);
436
 
@@ -469,7 +470,7 @@
469
  $templateBtns.prop('disabled', false);
470
  $this.html(labelOriginal);
471
  }
472
- });
473
 
474
  // This is a new form
475
  } else {
@@ -512,7 +513,7 @@
512
  * @since 1.0.0
513
  */
514
  bindUIActionsFields: function() {
515
-
516
  // Field sidebar tab toggle
517
  $(document).on('click', '.wpforms-tab a', function(e) {
518
  e.preventDefault();
@@ -551,7 +552,7 @@
551
 
552
  // New field choices should be sortable
553
  $(document).on('wpformsFieldAdd', function(event, id, type) {
554
- if (type == 'select' || type == 'radio' || type == 'checkbox' || type == 'payment-multiple' ) {
555
  WPFormsBuilder.fieldChoiceSortable(type,'#wpforms-field-option-row-' + id + '-choices ul');
556
  }
557
  });
@@ -568,7 +569,7 @@
568
 
569
  // Field choices defaults
570
  $(document).on('change', '.wpforms-field-option-row-choices input[type=radio]', function(e) {
571
- var $this = $(this),
572
  list = $this.parent().parent();
573
  $this.parent().parent().find('input[type=radio]').not(this).prop('checked',false);
574
  WPFormsBuilder.fieldChoiceUpdate(list.data('field-type'),list.data('field-id') );
@@ -632,7 +633,7 @@
632
 
633
  // Real-time updates for "Show Label" field option
634
  $(document).on('input', '.wpforms-field-option-row-label input', function(e) {
635
- var $this = $(this),
636
  value = $this.val(),
637
  id = $this.parent().data('field-id');
638
  $('#wpforms-field-'+id).find('.label-title .text').text(value);
@@ -640,7 +641,7 @@
640
 
641
  // Real-time updates for "Description" field option
642
  $(document).on('input', '.wpforms-field-option-row-description textarea', function(e) {
643
- var $this = $(this),
644
  value = $this.val(),
645
  id = $this.parent().data('field-id');
646
  $('#wpforms-field-'+id).find('.description').html(value);
@@ -661,7 +662,7 @@
661
 
662
  // Real-time updates for "Size" field option
663
  $(document).on('change', '.wpforms-field-option-row-size select', function(e) {
664
- var $this = $(this),
665
  value = $this.val(),
666
  id = $this.parent().data('field-id');
667
  $('#wpforms-field-'+id).removeClass('size-small size-medium size-large').addClass('size-'+value);
@@ -669,7 +670,7 @@
669
 
670
  // Real-time updates for "Placeholder" field option
671
  $(document).on('input', '.wpforms-field-option-row-placeholder input', function(e) {
672
- var $this = $(this),
673
  value = $this.val(),
674
  id = $this.parent().data('field-id'),
675
  $primary = $('#wpforms-field-'+id).find('.primary-input');
@@ -691,7 +692,7 @@
691
 
692
  // Real-time updates for "Confirmation Placeholder" field option
693
  $(document).on('input', '.wpforms-field-option-row-confirmation_placeholder input', function(e) {
694
- var $this = $(this),
695
  value = $this.val(),
696
  id = $this.parent().data('field-id');
697
  $('#wpforms-field-'+id).find('.secondary-input').attr('placeholder', value);
@@ -725,7 +726,7 @@
725
  id = $this.parent().data('field-id');
726
  $('#wpforms-field-'+id).find('.wpforms-address-scheme').addClass('wpforms-hide');
727
  $('#wpforms-field-'+id).find('.wpforms-address-scheme-'+value).removeClass('wpforms-hide');
728
-
729
  if ( $('#wpforms-field-'+id).find('.wpforms-address-scheme-'+value+' .wpforms-country' ).children().length == 0 ) {
730
  $('#wpforms-field-option-'+id).find('.wpforms-field-option-row-country').addClass('wpforms-hidden');
731
  } else {
@@ -773,7 +774,7 @@
773
 
774
  // Real-time updates for "Next" and "Prev" pagebreak field option
775
  $(document).on('input', '.wpforms-field-option-row-next input', function(e) {
776
- var $this = $(this),
777
  value = $this.val(),
778
  id = $this.parent().data('field-id');
779
  if (value) {
@@ -783,7 +784,7 @@
783
  }
784
  });
785
  $(document).on('input', '.wpforms-field-option-row-prev input', function(e) {
786
- var $this = $(this),
787
  value = $this.val(),
788
  id = $this.parent().data('field-id');
789
  if (value) {
@@ -795,7 +796,7 @@
795
 
796
  // Real-time updates for "Page Title" pagebreak field option
797
  $(document).on('input', '.wpforms-field-option-row-title input', function(e) {
798
- var $this = $(this),
799
  value = $this.val(),
800
  id = $this.parent().data('field-id');
801
  if (value) {
@@ -807,7 +808,7 @@
807
 
808
  // Real-time updates for "Page Navigation Alignment" pagebreak field option
809
  $(document).on('change', '.wpforms-field-option-row-nav_align select', function(e) {
810
- var $this = $(this),
811
  value = $this.val();
812
  if (!value) {
813
  value = 'center';
@@ -834,7 +835,7 @@
834
 
835
  // Real-time updates for Single Item field "Item Price" option
836
  $(document).on('input', '.wpforms-field-option-row-price input', function(e) {
837
- var $this = $(this),
838
  value = $this.val(),
839
  id = $this.parent().data('field-id'),
840
  sanitized = wpf.amountSanitize(value),
@@ -851,7 +852,7 @@
851
 
852
  // Real-time updates for payment CC icons
853
  $(document).on('change', '.wpforms-field-option-credit-card .payment-icons input', function(e) {
854
- var $this = $(this),
855
  card = $this.data('card')
856
  id = $this.parent().data('field-id');
857
  $('#wpforms-field-'+id).find('img.icon-'+card).toggleClass('card_hide');
@@ -888,7 +889,7 @@
888
 
889
  $this.toggleClass('wpforms-off wpforms-on');
890
  $this.find('i').toggleClass('fa-toggle-off fa-toggle-on');
891
-
892
  if ($this.hasClass('wpforms-on')) {
893
  $label.text(wpforms_builder.on);
894
  $check.prop('checked', true);
@@ -922,7 +923,7 @@
922
  * @since 1.0.0
923
  */
924
  fieldGroupToggle: function(el, action) {
925
-
926
  if ( 'click' == action ) {
927
 
928
  var $this = $(el),
@@ -972,7 +973,7 @@
972
  title: wpforms_builder.field_locked,
973
  content: wpforms_builder.field_locked_msg,
974
  confirmButton: wpforms_builder.close
975
- });
976
  } else {
977
  $.confirm({
978
  title: false,
@@ -988,7 +989,7 @@
988
  $(document).trigger('wpformsFieldDelete', [id, type ]);
989
  });
990
  }
991
- });
992
  }
993
  },
994
 
@@ -999,15 +1000,15 @@
999
  */
1000
  fieldDuplicate: function(id) {
1001
 
1002
- var $field = $('#wpforms-field-'+id),
1003
- type = $field.data('field-type');
1004
 
1005
  if ($field.hasClass('no-duplicate')) {
1006
  $.alert({
1007
  title: wpforms_builder.field_locked,
1008
  content: wpforms_builder.field_locked_msg,
1009
  confirmButton: wpforms_builder.close
1010
- });
1011
  } else {
1012
  $.confirm({
1013
  title: false,
@@ -1017,17 +1018,17 @@
1017
  confirm: function(){
1018
 
1019
  var $newField = $field.clone(),
1020
- newFieldID = $('#wpforms-field-id').val(),
1021
- nextID = Number(newFieldID)+1,
1022
  $fieldOptions = $('#wpforms-field-option-'+id),
1023
  newFieldOptions = $fieldOptions.html(),
 
1024
  newFieldLabel = $('#wpforms-field-option-'+id+'-label').val()+' '+wpforms_builder.duplicate_copy,
 
1025
  regex_fieldOptionsID = new RegExp( 'ID #'+id, "g"),
1026
  regex_fieldID = new RegExp( 'fields\\['+id+'\\]', "g"),
1027
  regex_dataFieldID = new RegExp( 'data-field-id="'+id+'"', "g"),
1028
  regex_referenceID = new RegExp( 'data-reference="'+id+'"', "g"),
1029
  regex_elementID = new RegExp( '\\b(id|for)="wpforms-(.*?)'+id+'(.*?)"', "ig");
1030
-
1031
  // Toggle visibility states
1032
  $field.after($newField);
1033
  $field.removeClass('active');
@@ -1043,12 +1044,36 @@
1043
  }
1044
  newFieldOptions = newFieldOptions.replace(regex_fieldOptionsID, 'ID #'+newFieldID);
1045
  newFieldOptions = newFieldOptions.replace(regex_fieldID, 'fields['+newFieldID+']');
1046
- newFieldOptions = newFieldOptions.replace(regex_dataFieldID, 'data-field-id="'+newFieldID+'"');
1047
  newFieldOptions = newFieldOptions.replace(regex_referenceID, 'data-reference="'+newFieldID+'"');
1048
  newFieldOptions = newFieldOptions.replace(regex_elementID, regex_elementID_replace);
1049
 
1050
  // Add new field options panel
1051
  $fieldOptions.hide().after('<div class="wpforms-field-option wpforms-field-option-'+type+'" id="wpforms-field-option-'+newFieldID+'" data-field-id="'+newFieldID+'">'+newFieldOptions+'</div>');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1052
 
1053
  // ID adjustments
1054
  $('#wpforms-field-option-'+newFieldID).find('.wpforms-field-option-hidden-id').val(newFieldID);
@@ -1060,11 +1085,11 @@
1060
 
1061
  // Fire field add custom event
1062
  $(document).trigger('wpformsFieldAdd', [newFieldID, type]);
1063
-
1064
  // Lastly, update the next ID stored in database
1065
  $.post(wpforms_builder.ajax_url, {form_id : s.formID, nonce : wpforms_builder.nonce, action : 'wpforms_builder_increase_next_field_id'});
1066
  }
1067
- });
1068
  }
1069
  },
1070
 
@@ -1107,25 +1132,25 @@
1107
 
1108
  // Determine where field gets placed
1109
  if ( 'bottom' === options.position ) {
1110
-
1111
  if ( $lastField.length && $lastField.hasClass('wpforms-field-stick')) {
1112
  // Check to see if the last field we have is configured to
1113
  // be stuck to the bottom, if so add the field above it.
1114
  $('.wpforms-field-wrap').children(':eq('+(totalFields-1)+')').before($newField);
1115
  $('.wpforms-field-options').children(':eq('+(totalFields-1)+')').before($newOptions);
1116
-
1117
  } else {
1118
  // Add field to bottom
1119
  $('.wpforms-field-wrap').append($newField);
1120
  $('.wpforms-field-options').append($newOptions);
1121
  }
1122
-
1123
  if (options.scroll) {
1124
  $preview.animate({ scrollTop: $preview.prop('scrollHeight') - $preview.height() }, 1000);
1125
  }
1126
-
1127
  } else if ( 'top' === options.position ) {
1128
-
1129
  // Add field to top, scroll to
1130
  $('.wpforms-field-wrap').prepend($newField);
1131
  $('.wpforms-field-options').prepend($newOptions);
@@ -1133,9 +1158,9 @@
1133
  if (options.scroll) {
1134
  $preview.animate({ scrollTop: 0 }, 1000);
1135
  }
1136
-
1137
  } else {
1138
-
1139
  if ( options.position === totalFields && $lastField.length && $lastField.hasClass('wpforms-field-stick') ) {
1140
  // Check to see if the user tried to add the field at
1141
  // the end BUT the last field we have is configured to
@@ -1156,7 +1181,7 @@
1156
  }
1157
 
1158
  $newField.fadeIn();
1159
-
1160
  $('#wpforms-builder-form .no-fields, #wpforms-builder-form .no-fields-preview').remove();
1161
  $('#wpforms-field-id').val(res.data.field.id+1);
1162
 
@@ -1164,7 +1189,7 @@
1164
  WPFormsBuilder.loadColorPickers();
1165
 
1166
  $(document).trigger('wpformsFieldAdd', [res.data.field.id, type ]);
1167
-
1168
  } else {
1169
  console.log(res);
1170
  }
@@ -1186,7 +1211,7 @@
1186
  fieldIndexNew,
1187
  field,
1188
  fieldNew;
1189
-
1190
  $('.wpforms-field-wrap').sortable({
1191
  items : '> .wpforms-field:not(.wpforms-field-stick)',
1192
  axis : 'y',
@@ -1198,7 +1223,7 @@
1198
  },
1199
  stop:function(e,ui){
1200
  fieldIndexNew = ui.item.index();
1201
- fieldNew = fieldOptions[0].children[fieldIndexNew];
1202
  if (fieldIndex < fieldIndexNew){
1203
  $(fieldNew).after(field);
1204
  } else {
@@ -1238,7 +1263,7 @@
1238
  var pos = $(this).data('ui-sortable').currentItem.index();
1239
  $el = ui.helper,
1240
  type = $el.attr('data-field-type');
1241
-
1242
  $el.addClass('wpforms-field-drag-over wpforms-field-drag-pending').removeClass('wpforms-field-drag-out').css('width', '100%');
1243
  $el.append('<i class="fa fa-cog fa-spin"></i>');
1244
 
@@ -1313,7 +1338,7 @@
1313
  $.alert({
1314
  title: false,
1315
  content: wpforms_builder.error_choice
1316
- });
1317
  } else {
1318
  $this.parent().remove();
1319
  WPFormsBuilder.fieldChoiceUpdate($list.data('field-type'), $list.data('field-id'));
@@ -1331,7 +1356,7 @@
1331
  fieldChoiceSortable: function(type, selector) {
1332
 
1333
  selector = typeof selector !== 'undefined' ? selector : '.wpforms-field-option-'+type+' .wpforms-field-option-row-choices ul';
1334
-
1335
  $(selector).sortable({
1336
  items : 'li',
1337
  axis : 'y',
@@ -1358,19 +1383,25 @@
1358
  fieldChoiceUpdate: function(type, id) {
1359
 
1360
  var new_choice;
 
1361
  // Multiple payment choices are radio buttons
1362
  if ( type == 'payment-multiple') {
1363
  type = 'radio';
1364
  }
 
 
 
 
 
1365
  if (type == 'select') {
1366
  $('#wpforms-field-'+id+' .primary-input option' ).not('.placeholder').remove();
1367
  new_choice = '<option>{label}</option>';
1368
  } else if (type == 'radio' || type == 'checkbox' ) {
1369
  $('#wpforms-field-'+id+' .primary-input li' ).remove();
1370
  new_choice = '<li><input type="'+type+'" disabled>{label}</li>';
1371
- }
1372
  $('#wpforms-field-option-row-' + id + '-choices li').each( function( index ) {
1373
- var $this = $(this),
1374
  label = $this.find('input.label').val(),
1375
  selected = $this.find('input.default').is(':checked'),
1376
  choice = $( new_choice.replace('{label}',label) );
@@ -1384,7 +1415,7 @@
1384
  case 'checkbox':
1385
  choice.find('input').prop('checked', 'true');
1386
  break;
1387
- }
1388
  }
1389
  });
1390
  },
@@ -1454,7 +1485,7 @@
1454
  });
1455
 
1456
  } else if ( ! s.pagebreakBottom ) {
1457
-
1458
  s.pagebreakBottom = true;
1459
  var options = {
1460
  position: 'bottom',
@@ -1491,7 +1522,7 @@
1491
 
1492
  var pagebreaksRemaining = $('.wpforms-field-pagebreak').not('.wpforms-pagebreak-top, .wpforms-pagebreak-bottom').length;
1493
 
1494
- // All pagebreaks, excluding top/bottom, are gone so we need to
1495
  // remove the top and bottom pagebreak
1496
  if ( !pagebreaksRemaining ) {
1497
  var $top = $('.wpforms-preview-wrap').find('.wpforms-pagebreak-top'),
@@ -1511,7 +1542,7 @@
1511
 
1512
  /**
1513
  * Field Dynamic Choice toggle.
1514
- *
1515
  * @since 1.2.8
1516
  */
1517
  fieldDynamicChoiceToggle: function(el) {
@@ -1532,11 +1563,11 @@
1532
 
1533
  if ( '' == value ) {
1534
  // "Off" - no dynamic populating
1535
-
1536
  // Get original field choices
1537
  var choices = [];
1538
- $('#wpforms-field-option-row-'+id+'-choices .label').each(function(index) {
1539
- choices.push($(this).val());
1540
  });
1541
 
1542
  // Restore field to display original field choices
@@ -1552,7 +1583,7 @@
1552
  if ($field.hasClass('wpforms-field-checkbox')) {
1553
  type = 'checkbox';
1554
  }
1555
-
1556
  // Remove previous items
1557
  $list.empty();
1558
 
@@ -1585,10 +1616,10 @@
1585
  }
1586
  // Hide loading indicator
1587
  wpf.fieldOptionLoading($thisOption, true);
1588
-
1589
  // Re-init tooltips for new field
1590
  WPFormsBuilder.loadTooltips();
1591
-
1592
  // Trigger Dynamic source updates
1593
  $('#wpforms-field-option-'+id+'-dynamic_'+value).find('option:first').prop('selected', true);
1594
  $('#wpforms-field-option-'+id+'-dynamic_'+value).trigger('change');
@@ -1601,7 +1632,7 @@
1601
 
1602
  /**
1603
  * Field Dynamic Choice Source toggle.
1604
- *
1605
  * @since 1.2.8
1606
  */
1607
  fieldDynamicChoiceSource: function(el) {
@@ -1615,7 +1646,7 @@
1615
  $field = $('#wpforms-field-'+id);
1616
  type = $('#wpforms-field-option-'+id+'-dynamic_choices option:selected').val(),
1617
  limit = 20;
1618
-
1619
  // Loading
1620
  wpf.fieldOptionLoading($thisOption);
1621
 
@@ -1650,7 +1681,7 @@
1650
  if ($field.hasClass('wpforms-field-checkbox')) {
1651
  type = 'checkbox';
1652
  }
1653
-
1654
  // Remove previous items
1655
  $list.empty();
1656
 
@@ -1671,7 +1702,7 @@
1671
  $.alert({
1672
  title: wpforms_builder.heads_up,
1673
  content: msg
1674
- });
1675
  }
1676
  } else {
1677
  console.log(res);
@@ -1680,7 +1711,7 @@
1680
  // Toggle elements and hide loading indicator
1681
  $choices.find('ul').addClass('wpforms-hidden');
1682
  wpf.fieldOptionLoading($thisOption, true);
1683
-
1684
  }).fail(function(xhr, textStatus, e) {
1685
  console.log(xhr.responseText);
1686
  });
@@ -1696,7 +1727,7 @@
1696
  * @since 1.0.0
1697
  */
1698
  bindUIActionsSettings: function() {
1699
-
1700
  // Clicking form title/desc opens Settings panel
1701
  $(document).on('click', '.wpforms-title-desc, .wpforms-field-submit-button, .wpforms-center-form-name', function(e) {
1702
  e.preventDefault();
@@ -1910,7 +1941,7 @@
1910
  $.alert({
1911
  title: false,
1912
  content: wpforms_builder.notification_error2
1913
- });
1914
  } else {
1915
  $this.closest('.wpforms-notification').remove();
1916
  }
@@ -1941,7 +1972,7 @@
1941
  title: false,
1942
  content: content,
1943
  confirmButton: wpforms_builder.close
1944
- });
1945
  });
1946
 
1947
  // Save form
@@ -1950,7 +1981,7 @@
1950
  WPFormsBuilder.formSave(false);
1951
  });
1952
 
1953
- // Exit builder
1954
  $(document).on('click', '#wpforms-exit', function(e) {
1955
  e.preventDefault();
1956
  WPFormsBuilder.formExit();
@@ -2022,7 +2053,7 @@
2022
  cancel: function(){
2023
  window.location.href = wpforms_builder.exit_url;
2024
  }
2025
- });
2026
  }
2027
  },
2028
 
@@ -2034,7 +2065,7 @@
2034
  formIsSaved: function() {
2035
 
2036
  var currentState = $('#wpforms-builder-form').serializeJSON();
2037
-
2038
  if ( wpforms_builder.saved_state == currentState ) {
2039
  return true;
2040
  } else {
@@ -2092,7 +2123,7 @@
2092
  sanitized = wpf.amountSanitize(amount),
2093
  formatted = wpf.amountFormat(sanitized);
2094
  $this.val(formatted);
2095
- });
2096
  },
2097
 
2098
  /**
@@ -2140,7 +2171,7 @@
2140
 
2141
  // Apply to all selects with indentifier class
2142
  $('.wpforms-field-map-select').each(function(index, el) {
2143
-
2144
  var $this = $(this),
2145
  selected = $this.find('option:selected').val(),
2146
  allowedFields = $this.data('field-map-allowed'),
@@ -2251,7 +2282,7 @@
2251
  }).keyup(function(e) {
2252
  if (e.keyCode == 17) {
2253
  ctrlDown = false;
2254
- }
2255
  });
2256
  }
2257
  };
69
  s.formData = $('#wpforms-builder-form').serializeObject();
70
  s.pagebreakTop = $('.wpforms-pagebreak-top').length;
71
  s.pagebreakBottom = $('.wpforms-pagebreak-bottom').length;
72
+
73
  // @todo - performance testing
74
  //wpforms_builder.saved_state = $('#wpforms-builder-form').serializeJSON();
75
  //jQuery.parseJSON(json);
76
  //console.log( $(':input').length);
77
+
78
  // If there is a section configured, display it. Otherwise
79
  // we show the first panel by default.
80
  $('.wpforms-panel').each(function(index, el) {
97
  WPFormsBuilder.fieldChoiceSortable('radio');
98
  WPFormsBuilder.fieldChoiceSortable('checkbox');
99
  WPFormsBuilder.fieldChoiceSortable('payment-multiple');
100
+ WPFormsBuilder.fieldChoiceSortable('payment-select');
101
 
102
  // Load match heights
103
  $('.wpforms-template').matchHeight({
135
 
136
  // Clone form title to setup page
137
  $('#wpforms-setup-name').val($('#wpforms-panel-field-settings-form_title').val());
138
+
139
  // jquery-confirmd defaults
140
  jconfirm.defaults = {
141
  confirmButton: wpforms_builder.ok,
153
  * @since 1.0.0
154
  */
155
  bindUIActions: function() {
156
+
157
  // General Panels
158
  WPFormsBuilder.bindUIActionsPanels();
159
 
238
 
239
  // Create smart tags list
240
  var smartTagList = '<ul class="smart-tags-list-display">';
241
+
242
  if (type === 'fields' || type === 'all') {
243
  if (!fields) {
244
  smartTagList += '<li class="heading">'+wpforms_builder.fields_unavailable+'</li>';
297
  } else {
298
  $input.insertAtCaret('{'+meta+'}');
299
  }
300
+
301
  // remove list, all done!
302
  $list.slideUp(400, function() {
303
  $list.remove();
317
  $panelBtn = $('.wpforms-panel-'+panel+'-button');
318
 
319
  if (!$panel.hasClass('active')) {
320
+
321
  $(document).trigger('wpformsPanelSwitch', panel);
322
+
323
  if (!wpforms_panel_switch) {
324
  return false;
325
  }
373
  WPFormsBuilder.setupTitleFocus(e, wpf.getQueryString('view'));
374
  });
375
  $(document).on('wpformsPanelSwitch', WPFormsBuilder.setupTitleFocus);
376
+
377
  // Select and apply a template
378
  $(document).on('click', '.wpforms-template-select', function(e) {
379
  WPFormsBuilder.templateSelect(this, e);
383
  $(document).on('click', '.wpforms-trigger-blank', function(e) {
384
  e.preventDefault();
385
  $('#wpforms-template-blank .wpforms-template-select').trigger('click');
386
+ });
387
 
388
  // Keep Setup title and settings title instances the same
389
  $(document).on('input', '#wpforms-panel-field-settings-form_title', function() {
390
  $('#wpforms-setup-name').val($('#wpforms-panel-field-settings-form_title').val());
391
+ });
392
  $(document).on('input', '#wpforms-setup-name', function() {
393
  $('#wpforms-panel-field-settings-form_title').val($('#wpforms-setup-name').val()).trigger('input');
394
+ });
395
  },
396
 
397
  /**
431
  if ($parent.hasClass('pro-modal')){
432
  return;
433
  }
434
+
435
  // Disable all template buttons
436
  $templateBtns.prop('disabled', true);
437
 
470
  $templateBtns.prop('disabled', false);
471
  $this.html(labelOriginal);
472
  }
473
+ });
474
 
475
  // This is a new form
476
  } else {
513
  * @since 1.0.0
514
  */
515
  bindUIActionsFields: function() {
516
+
517
  // Field sidebar tab toggle
518
  $(document).on('click', '.wpforms-tab a', function(e) {
519
  e.preventDefault();
552
 
553
  // New field choices should be sortable
554
  $(document).on('wpformsFieldAdd', function(event, id, type) {
555
+ if (type == 'select' || type == 'radio' || type == 'checkbox' || type == 'payment-multiple' || type == 'payment-select' ) {
556
  WPFormsBuilder.fieldChoiceSortable(type,'#wpforms-field-option-row-' + id + '-choices ul');
557
  }
558
  });
569
 
570
  // Field choices defaults
571
  $(document).on('change', '.wpforms-field-option-row-choices input[type=radio]', function(e) {
572
+ var $this = $(this),
573
  list = $this.parent().parent();
574
  $this.parent().parent().find('input[type=radio]').not(this).prop('checked',false);
575
  WPFormsBuilder.fieldChoiceUpdate(list.data('field-type'),list.data('field-id') );
633
 
634
  // Real-time updates for "Show Label" field option
635
  $(document).on('input', '.wpforms-field-option-row-label input', function(e) {
636
+ var $this = $(this),
637
  value = $this.val(),
638
  id = $this.parent().data('field-id');
639
  $('#wpforms-field-'+id).find('.label-title .text').text(value);
641
 
642
  // Real-time updates for "Description" field option
643
  $(document).on('input', '.wpforms-field-option-row-description textarea', function(e) {
644
+ var $this = $(this),
645
  value = $this.val(),
646
  id = $this.parent().data('field-id');
647
  $('#wpforms-field-'+id).find('.description').html(value);
662
 
663
  // Real-time updates for "Size" field option
664
  $(document).on('change', '.wpforms-field-option-row-size select', function(e) {
665
+ var $this = $(this),
666
  value = $this.val(),
667
  id = $this.parent().data('field-id');
668
  $('#wpforms-field-'+id).removeClass('size-small size-medium size-large').addClass('size-'+value);
670
 
671
  // Real-time updates for "Placeholder" field option
672
  $(document).on('input', '.wpforms-field-option-row-placeholder input', function(e) {
673
+ var $this = $(this),
674
  value = $this.val(),
675
  id = $this.parent().data('field-id'),
676
  $primary = $('#wpforms-field-'+id).find('.primary-input');
692
 
693
  // Real-time updates for "Confirmation Placeholder" field option
694
  $(document).on('input', '.wpforms-field-option-row-confirmation_placeholder input', function(e) {
695
+ var $this = $(this),
696
  value = $this.val(),
697
  id = $this.parent().data('field-id');
698
  $('#wpforms-field-'+id).find('.secondary-input').attr('placeholder', value);
726
  id = $this.parent().data('field-id');
727
  $('#wpforms-field-'+id).find('.wpforms-address-scheme').addClass('wpforms-hide');
728
  $('#wpforms-field-'+id).find('.wpforms-address-scheme-'+value).removeClass('wpforms-hide');
729
+
730
  if ( $('#wpforms-field-'+id).find('.wpforms-address-scheme-'+value+' .wpforms-country' ).children().length == 0 ) {
731
  $('#wpforms-field-option-'+id).find('.wpforms-field-option-row-country').addClass('wpforms-hidden');
732
  } else {
774
 
775
  // Real-time updates for "Next" and "Prev" pagebreak field option
776
  $(document).on('input', '.wpforms-field-option-row-next input', function(e) {
777
+ var $this = $(this),
778
  value = $this.val(),
779
  id = $this.parent().data('field-id');
780
  if (value) {
784
  }
785
  });
786
  $(document).on('input', '.wpforms-field-option-row-prev input', function(e) {
787
+ var $this = $(this),
788
  value = $this.val(),
789
  id = $this.parent().data('field-id');
790
  if (value) {
796
 
797
  // Real-time updates for "Page Title" pagebreak field option
798
  $(document).on('input', '.wpforms-field-option-row-title input', function(e) {
799
+ var $this = $(this),
800
  value = $this.val(),
801
  id = $this.parent().data('field-id');
802
  if (value) {
808
 
809
  // Real-time updates for "Page Navigation Alignment" pagebreak field option
810
  $(document).on('change', '.wpforms-field-option-row-nav_align select', function(e) {
811
+ var $this = $(this),
812
  value = $this.val();
813
  if (!value) {
814
  value = 'center';
835
 
836
  // Real-time updates for Single Item field "Item Price" option
837
  $(document).on('input', '.wpforms-field-option-row-price input', function(e) {
838
+ var $this = $(this),
839
  value = $this.val(),
840
  id = $this.parent().data('field-id'),
841
  sanitized = wpf.amountSanitize(value),
852
 
853
  // Real-time updates for payment CC icons
854
  $(document).on('change', '.wpforms-field-option-credit-card .payment-icons input', function(e) {
855
+ var $this = $(this),
856
  card = $this.data('card')
857
  id = $this.parent().data('field-id');
858
  $('#wpforms-field-'+id).find('img.icon-'+card).toggleClass('card_hide');
889
 
890
  $this.toggleClass('wpforms-off wpforms-on');
891
  $this.find('i').toggleClass('fa-toggle-off fa-toggle-on');
892
+
893
  if ($this.hasClass('wpforms-on')) {
894
  $label.text(wpforms_builder.on);
895
  $check.prop('checked', true);
923
  * @since 1.0.0
924
  */
925
  fieldGroupToggle: function(el, action) {
926
+
927
  if ( 'click' == action ) {
928
 
929
  var $this = $(el),
973
  title: wpforms_builder.field_locked,
974
  content: wpforms_builder.field_locked_msg,
975
  confirmButton: wpforms_builder.close
976
+ });
977
  } else {
978
  $.confirm({
979
  title: false,
989
  $(document).trigger('wpformsFieldDelete', [id, type ]);
990
  });
991
  }
992
+ });
993
  }
994
  },
995
 
1000
  */
1001
  fieldDuplicate: function(id) {
1002
 
1003
+ var $field = $('#wpforms-field-'+id),
1004
+ type = $field.data('field-type');
1005
 
1006
  if ($field.hasClass('no-duplicate')) {
1007
  $.alert({
1008
  title: wpforms_builder.field_locked,
1009
  content: wpforms_builder.field_locked_msg,
1010
  confirmButton: wpforms_builder.close
1011
+ });
1012
  } else {
1013
  $.confirm({
1014
  title: false,
1018
  confirm: function(){
1019
 
1020
  var $newField = $field.clone(),
 
 
1021
  $fieldOptions = $('#wpforms-field-option-'+id),
1022
  newFieldOptions = $fieldOptions.html(),
1023
+ newFieldID = $('#wpforms-field-id').val(),
1024
  newFieldLabel = $('#wpforms-field-option-'+id+'-label').val()+' '+wpforms_builder.duplicate_copy,
1025
+ nextID = Number(newFieldID)+1,
1026
  regex_fieldOptionsID = new RegExp( 'ID #'+id, "g"),
1027
  regex_fieldID = new RegExp( 'fields\\['+id+'\\]', "g"),
1028
  regex_dataFieldID = new RegExp( 'data-field-id="'+id+'"', "g"),
1029
  regex_referenceID = new RegExp( 'data-reference="'+id+'"', "g"),
1030
  regex_elementID = new RegExp( '\\b(id|for)="wpforms-(.*?)'+id+'(.*?)"', "ig");
1031
+
1032
  // Toggle visibility states
1033
  $field.after($newField);
1034
  $field.removeClass('active');
1044
  }
1045
  newFieldOptions = newFieldOptions.replace(regex_fieldOptionsID, 'ID #'+newFieldID);
1046
  newFieldOptions = newFieldOptions.replace(regex_fieldID, 'fields['+newFieldID+']');
1047
+ newFieldOptions = newFieldOptions.replace(regex_dataFieldID, 'data-field-id="'+newFieldID+'"');
1048
  newFieldOptions = newFieldOptions.replace(regex_referenceID, 'data-reference="'+newFieldID+'"');
1049
  newFieldOptions = newFieldOptions.replace(regex_elementID, regex_elementID_replace);
1050
 
1051
  // Add new field options panel
1052
  $fieldOptions.hide().after('<div class="wpforms-field-option wpforms-field-option-'+type+'" id="wpforms-field-option-'+newFieldID+'" data-field-id="'+newFieldID+'">'+newFieldOptions+'</div>');
1053
+ var $newFieldOptions = $('#wpforms-field-option-'+newFieldID);
1054
+
1055
+ // Copy over values
1056
+ $fieldOptions.find(':input').each(function(index, el) {
1057
+ var $this = $(this);
1058
+ name = $this.attr('name'),
1059
+ newName = name.replace(regex_fieldID, 'fields['+newFieldID+']'),
1060
+ type = $this.attr('type');
1061
+
1062
+ if ( type === 'checkbox' || type === 'radio' ) {
1063
+ if ($this.is(':checked')){
1064
+ $newFieldOptions.find('[name="'+newName+'"]').prop('checked', true);
1065
+ }
1066
+ } else if ($this.is('select')) {
1067
+ if ($this.find('option:selected').length) {
1068
+ var optionVal = $this.find('option:selected').val();
1069
+ $newFieldOptions.find('[name="'+newName+'"]').find('[value="'+optionVal+'"]').prop('selected',true);
1070
+ }
1071
+ } else {
1072
+ if ($this.val() != '') {
1073
+ $newFieldOptions.find('[name="'+newName+'"]').val( $this.val() );
1074
+ }
1075
+ }
1076
+ });
1077
 
1078
  // ID adjustments
1079
  $('#wpforms-field-option-'+newFieldID).find('.wpforms-field-option-hidden-id').val(newFieldID);
1085
 
1086
  // Fire field add custom event
1087
  $(document).trigger('wpformsFieldAdd', [newFieldID, type]);
1088
+
1089
  // Lastly, update the next ID stored in database
1090
  $.post(wpforms_builder.ajax_url, {form_id : s.formID, nonce : wpforms_builder.nonce, action : 'wpforms_builder_increase_next_field_id'});
1091
  }
1092
+ });
1093
  }
1094
  },
1095
 
1132
 
1133
  // Determine where field gets placed
1134
  if ( 'bottom' === options.position ) {
1135
+
1136
  if ( $lastField.length && $lastField.hasClass('wpforms-field-stick')) {
1137
  // Check to see if the last field we have is configured to
1138
  // be stuck to the bottom, if so add the field above it.
1139
  $('.wpforms-field-wrap').children(':eq('+(totalFields-1)+')').before($newField);
1140
  $('.wpforms-field-options').children(':eq('+(totalFields-1)+')').before($newOptions);
1141
+
1142
  } else {
1143
  // Add field to bottom
1144
  $('.wpforms-field-wrap').append($newField);
1145
  $('.wpforms-field-options').append($newOptions);
1146
  }
1147
+
1148
  if (options.scroll) {
1149
  $preview.animate({ scrollTop: $preview.prop('scrollHeight') - $preview.height() }, 1000);
1150
  }
1151
+
1152
  } else if ( 'top' === options.position ) {
1153
+
1154
  // Add field to top, scroll to
1155
  $('.wpforms-field-wrap').prepend($newField);
1156
  $('.wpforms-field-options').prepend($newOptions);
1158
  if (options.scroll) {
1159
  $preview.animate({ scrollTop: 0 }, 1000);
1160
  }
1161
+
1162
  } else {
1163
+
1164
  if ( options.position === totalFields && $lastField.length && $lastField.hasClass('wpforms-field-stick') ) {
1165
  // Check to see if the user tried to add the field at
1166
  // the end BUT the last field we have is configured to
1181
  }
1182
 
1183
  $newField.fadeIn();
1184
+
1185
  $('#wpforms-builder-form .no-fields, #wpforms-builder-form .no-fields-preview').remove();
1186
  $('#wpforms-field-id').val(res.data.field.id+1);
1187
 
1189
  WPFormsBuilder.loadColorPickers();
1190
 
1191
  $(document).trigger('wpformsFieldAdd', [res.data.field.id, type ]);
1192
+
1193
  } else {
1194
  console.log(res);
1195
  }
1211
  fieldIndexNew,
1212
  field,
1213
  fieldNew;
1214
+
1215
  $('.wpforms-field-wrap').sortable({
1216
  items : '> .wpforms-field:not(.wpforms-field-stick)',
1217
  axis : 'y',
1223
  },
1224
  stop:function(e,ui){
1225
  fieldIndexNew = ui.item.index();
1226
+ fieldNew = fieldOptions[0].children[fieldIndexNew];
1227
  if (fieldIndex < fieldIndexNew){
1228
  $(fieldNew).after(field);
1229
  } else {
1263
  var pos = $(this).data('ui-sortable').currentItem.index();
1264
  $el = ui.helper,
1265
  type = $el.attr('data-field-type');
1266
+
1267
  $el.addClass('wpforms-field-drag-over wpforms-field-drag-pending').removeClass('wpforms-field-drag-out').css('width', '100%');
1268
  $el.append('<i class="fa fa-cog fa-spin"></i>');
1269
 
1338
  $.alert({
1339
  title: false,
1340
  content: wpforms_builder.error_choice
1341
+ });
1342
  } else {
1343
  $this.parent().remove();
1344
  WPFormsBuilder.fieldChoiceUpdate($list.data('field-type'), $list.data('field-id'));
1356
  fieldChoiceSortable: function(type, selector) {
1357
 
1358
  selector = typeof selector !== 'undefined' ? selector : '.wpforms-field-option-'+type+' .wpforms-field-option-row-choices ul';
1359
+
1360
  $(selector).sortable({
1361
  items : 'li',
1362
  axis : 'y',
1383
  fieldChoiceUpdate: function(type, id) {
1384
 
1385
  var new_choice;
1386
+
1387
  // Multiple payment choices are radio buttons
1388
  if ( type == 'payment-multiple') {
1389
  type = 'radio';
1390
  }
1391
+ // Dropdown payment choices are selects
1392
+ if ( type == 'payment-select') {
1393
+ type = 'select';
1394
+ }
1395
+
1396
  if (type == 'select') {
1397
  $('#wpforms-field-'+id+' .primary-input option' ).not('.placeholder').remove();
1398
  new_choice = '<option>{label}</option>';
1399
  } else if (type == 'radio' || type == 'checkbox' ) {
1400
  $('#wpforms-field-'+id+' .primary-input li' ).remove();
1401
  new_choice = '<li><input type="'+type+'" disabled>{label}</li>';
1402
+ }
1403
  $('#wpforms-field-option-row-' + id + '-choices li').each( function( index ) {
1404
+ var $this = $(this),
1405
  label = $this.find('input.label').val(),
1406
  selected = $this.find('input.default').is(':checked'),
1407
  choice = $( new_choice.replace('{label}',label) );
1415
  case 'checkbox':
1416
  choice.find('input').prop('checked', 'true');
1417
  break;
1418
+ }
1419
  }
1420
  });
1421
  },
1485
  });
1486
 
1487
  } else if ( ! s.pagebreakBottom ) {
1488
+
1489
  s.pagebreakBottom = true;
1490
  var options = {
1491
  position: 'bottom',
1522
 
1523
  var pagebreaksRemaining = $('.wpforms-field-pagebreak').not('.wpforms-pagebreak-top, .wpforms-pagebreak-bottom').length;
1524
 
1525
+ // All pagebreaks, excluding top/bottom, are gone so we need to
1526
  // remove the top and bottom pagebreak
1527
  if ( !pagebreaksRemaining ) {
1528
  var $top = $('.wpforms-preview-wrap').find('.wpforms-pagebreak-top'),
1542
 
1543
  /**
1544
  * Field Dynamic Choice toggle.
1545
+ *
1546
  * @since 1.2.8
1547
  */
1548
  fieldDynamicChoiceToggle: function(el) {
1563
 
1564
  if ( '' == value ) {
1565
  // "Off" - no dynamic populating
1566
+
1567
  // Get original field choices
1568
  var choices = [];
1569
+ $('#wpforms-field-option-row-'+id+'-choices .label').each(function(index) {
1570
+ choices.push($(this).val());
1571
  });
1572
 
1573
  // Restore field to display original field choices
1583
  if ($field.hasClass('wpforms-field-checkbox')) {
1584
  type = 'checkbox';
1585
  }
1586
+
1587
  // Remove previous items
1588
  $list.empty();
1589
 
1616
  }
1617
  // Hide loading indicator
1618
  wpf.fieldOptionLoading($thisOption, true);
1619
+
1620
  // Re-init tooltips for new field
1621
  WPFormsBuilder.loadTooltips();
1622
+
1623
  // Trigger Dynamic source updates
1624
  $('#wpforms-field-option-'+id+'-dynamic_'+value).find('option:first').prop('selected', true);
1625
  $('#wpforms-field-option-'+id+'-dynamic_'+value).trigger('change');
1632
 
1633
  /**
1634
  * Field Dynamic Choice Source toggle.
1635
+ *
1636
  * @since 1.2.8
1637
  */
1638
  fieldDynamicChoiceSource: function(el) {
1646
  $field = $('#wpforms-field-'+id);
1647
  type = $('#wpforms-field-option-'+id+'-dynamic_choices option:selected').val(),
1648
  limit = 20;
1649
+
1650
  // Loading
1651
  wpf.fieldOptionLoading($thisOption);
1652
 
1681
  if ($field.hasClass('wpforms-field-checkbox')) {
1682
  type = 'checkbox';
1683
  }
1684
+
1685
  // Remove previous items
1686
  $list.empty();
1687
 
1702
  $.alert({
1703
  title: wpforms_builder.heads_up,
1704
  content: msg
1705
+ });
1706
  }
1707
  } else {
1708
  console.log(res);
1711
  // Toggle elements and hide loading indicator
1712
  $choices.find('ul').addClass('wpforms-hidden');
1713
  wpf.fieldOptionLoading($thisOption, true);
1714
+
1715
  }).fail(function(xhr, textStatus, e) {
1716
  console.log(xhr.responseText);
1717
  });
1727
  * @since 1.0.0
1728
  */
1729
  bindUIActionsSettings: function() {
1730
+
1731
  // Clicking form title/desc opens Settings panel
1732
  $(document).on('click', '.wpforms-title-desc, .wpforms-field-submit-button, .wpforms-center-form-name', function(e) {
1733
  e.preventDefault();
1941
  $.alert({
1942
  title: false,
1943
  content: wpforms_builder.notification_error2
1944
+ });
1945
  } else {
1946
  $this.closest('.wpforms-notification').remove();
1947
  }
1972
  title: false,
1973
  content: content,
1974
  confirmButton: wpforms_builder.close
1975
+ });
1976
  });
1977
 
1978
  // Save form
1981
  WPFormsBuilder.formSave(false);
1982
  });
1983
 
1984
+ // Exit builder
1985
  $(document).on('click', '#wpforms-exit', function(e) {
1986
  e.preventDefault();
1987
  WPFormsBuilder.formExit();
2053
  cancel: function(){
2054
  window.location.href = wpforms_builder.exit_url;
2055
  }
2056
+ });
2057
  }
2058
  },
2059
 
2065
  formIsSaved: function() {
2066
 
2067
  var currentState = $('#wpforms-builder-form').serializeJSON();
2068
+
2069
  if ( wpforms_builder.saved_state == currentState ) {
2070
  return true;
2071
  } else {
2123
  sanitized = wpf.amountSanitize(amount),
2124
  formatted = wpf.amountFormat(sanitized);
2125
  $this.val(formatted);
2126
+ });
2127
  },
2128
 
2129
  /**
2171
 
2172
  // Apply to all selects with indentifier class
2173
  $('.wpforms-field-map-select').each(function(index, el) {
2174
+
2175
  var $this = $(this),
2176
  selected = $this.find('option:selected').val(),
2177
  allowedFields = $this.data('field-map-allowed'),
2282
  }).keyup(function(e) {
2283
  if (e.keyCode == 17) {
2284
  ctrlDown = false;
2285
+ }
2286
  });
2287
  }
2288
  };
assets/js/admin-editor.js CHANGED
@@ -10,17 +10,18 @@
10
  $( document.body ).removeClass( 'modal-open' );
11
  };
12
  // Open modal when media button is clicked
13
- $('.wpforms-insert-form-button').click(function(event) {
14
  event.preventDefault();
15
  $('#wpforms-modal-backdrop, #wpforms-modal-wrap').css('display','block');
16
  $( document.body ).addClass( 'modal-open' );
17
  });
18
  // Close modal on close or cancel links
19
- $('#wpforms-modal-close, #wpforms-modal-cancel a').click(function(event) {
 
20
  wpformsModalClose();
21
  });
22
  // Insert shortcode into TinyMCE
23
- $('#wpforms-modal-submit').click(function(event) {
24
  event.preventDefault();
25
  var shortcode;
26
  shortcode = '[wpforms id="' + $('#wpforms-modal-select-form').val() + '"';
10
  $( document.body ).removeClass( 'modal-open' );
11
  };
12
  // Open modal when media button is clicked
13
+ $(document).on('click', '.wpforms-insert-form-button', function(event) {
14
  event.preventDefault();
15
  $('#wpforms-modal-backdrop, #wpforms-modal-wrap').css('display','block');
16
  $( document.body ).addClass( 'modal-open' );
17
  });
18
  // Close modal on close or cancel links
19
+ $(document).on('click', '#wpforms-modal-close, #wpforms-modal-cancel a', function(event) {
20
+ event.preventDefault();
21
  wpformsModalClose();
22
  });
23
  // Insert shortcode into TinyMCE
24
+ $(document).on('click', '#wpforms-modal-submit', function(event) {
25
  event.preventDefault();
26
  var shortcode;
27
  shortcode = '[wpforms id="' + $('#wpforms-modal-select-form').val() + '"';
assets/js/admin-utils.js CHANGED
@@ -71,7 +71,7 @@ var wpf = {
71
  if (!fields) {
72
  return false;
73
  }
74
-
75
  // Find and store the order of forms. The order is lost when javascript
76
  // serilizes the form.
77
  jQuery('.wpforms-field-option').each(function(index, ele) {
@@ -93,7 +93,7 @@ var wpf = {
93
  }
94
  });
95
 
96
- // Preserve the order of field choices
97
  for(var key in fields) {
98
  if (fields[key].choices) {
99
  jQuery('#wpforms-field-option-row-'+fields[key].id+'-choices li').each(function(index, ele) {
@@ -105,7 +105,7 @@ var wpf = {
105
  }
106
  }
107
 
108
- // Preserve the order of fields
109
  for(var key in fieldOrder) {
110
  fieldsOrdered['field_'+fieldOrder[key]] = fields[fieldOrder[key]];
111
  }
@@ -128,7 +128,7 @@ var wpf = {
128
  if (unload) {
129
  $label.find('.wpforms-loading-inline').remove();
130
  $label.find('.wpforms-help-tooltip').show();
131
- $option.find('input,select,textarea').prop('disabled', false);
132
  } else {
133
  $label.append(spinner);
134
  $label.find('.wpforms-help-tooltip').hide();
@@ -177,7 +177,7 @@ var wpf = {
177
  * @deprecated 1.2.8
178
  */
179
  sanitizeString: function(str) {
180
-
181
  return str.trim();
182
  },
183
 
@@ -198,7 +198,7 @@ var wpf = {
198
  else {
199
  hash = url.split('#');
200
  url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
201
- if (typeof hash[1] !== 'undefined' && hash[1] !== null)
202
  url += '#' + hash[1];
203
  return url;
204
  }
@@ -207,7 +207,7 @@ var wpf = {
207
  var separator = url.indexOf('?') !== -1 ? '&' : '?';
208
  hash = url.split('#');
209
  url = hash[0] + separator + key + '=' + value;
210
- if (typeof hash[1] !== 'undefined' && hash[1] !== null)
211
  url += '#' + hash[1];
212
  return url;
213
  }
@@ -222,7 +222,7 @@ var wpf = {
222
  * @since 1.0.0
223
  */
224
  getQueryString: function(name) {
225
-
226
  var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
227
  return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
228
  },
@@ -256,7 +256,7 @@ var wpf = {
256
  amount = amount.replace(wpforms_builder.currency_thousands,'');
257
  }
258
 
259
- return wpf.numberFormat( amount, 2, '.', '' );
260
  },
261
 
262
  /**
@@ -294,7 +294,7 @@ var wpf = {
294
  * @link http://locutus.io/php/number_format/
295
  * @since 1.2.6
296
  */
297
- numberFormat: function (number, decimals, decimalSep, thousandsSep) {
298
 
299
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
300
  var n = !isFinite(+number) ? 0 : +number
@@ -328,7 +328,7 @@ var wpf = {
328
  * @since 1.2.6
329
  */
330
  empty: function(mixedVar) {
331
-
332
  var undef
333
  var key
334
  var i
71
  if (!fields) {
72
  return false;
73
  }
74
+
75
  // Find and store the order of forms. The order is lost when javascript
76
  // serilizes the form.
77
  jQuery('.wpforms-field-option').each(function(index, ele) {
93
  }
94
  });
95
 
96
+ // Preserve the order of field choices
97
  for(var key in fields) {
98
  if (fields[key].choices) {
99
  jQuery('#wpforms-field-option-row-'+fields[key].id+'-choices li').each(function(index, ele) {
105
  }
106
  }
107
 
108
+ // Preserve the order of fields
109
  for(var key in fieldOrder) {
110
  fieldsOrdered['field_'+fieldOrder[key]] = fields[fieldOrder[key]];
111
  }
128
  if (unload) {
129
  $label.find('.wpforms-loading-inline').remove();
130
  $label.find('.wpforms-help-tooltip').show();
131
+ $option.find('input,select,textarea').prop('disabled', false);
132
  } else {
133
  $label.append(spinner);
134
  $label.find('.wpforms-help-tooltip').hide();
177
  * @deprecated 1.2.8
178
  */
179
  sanitizeString: function(str) {
180
+
181
  return str.trim();
182
  },
183
 
198
  else {
199
  hash = url.split('#');
200
  url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
201
+ if (typeof hash[1] !== 'undefined' && hash[1] !== null)
202
  url += '#' + hash[1];
203
  return url;
204
  }
207
  var separator = url.indexOf('?') !== -1 ? '&' : '?';
208
  hash = url.split('#');
209
  url = hash[0] + separator + key + '=' + value;
210
+ if (typeof hash[1] !== 'undefined' && hash[1] !== null)
211
  url += '#' + hash[1];
212
  return url;
213
  }
222
  * @since 1.0.0
223
  */
224
  getQueryString: function(name) {
225
+
226
  var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
227
  return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
228
  },
256
  amount = amount.replace(wpforms_builder.currency_thousands,'');
257
  }
258
 
259
+ return wpf.numberFormat( amount, 2, '.', '' );
260
  },
261
 
262
  /**
294
  * @link http://locutus.io/php/number_format/
295
  * @since 1.2.6
296
  */
297
+ numberFormat: function (number, decimals, decimalSep, thousandsSep) {
298
 
299
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
300
  var n = !isFinite(+number) ? 0 : +number
328
  * @since 1.2.6
329
  */
330
  empty: function(mixedVar) {
331
+
332
  var undef
333
  var key
334
  var i
assets/js/flatpickr.min.js CHANGED
@@ -1,2 +1,1625 @@
1
- /*! flatpickr v2.0, @license MIT */
2
- function Flatpickr(e,t){function n(){$.element=e,$.instanceConfig=t||{},O(),x(),R(),S(),A(),$.isOpen=$.config.inline,$.changeMonth=p,$.clear=f,$.close=m,$.destroy=g,$.formatDate=v,$.jumpToDate=i,$.open=M,$.parseDate=I,$.redraw=L,$.set=F,$.setDate=N,$.toggle=_,$.isMobile=!$.config.disableMobile&&"single"===$.config.mode&&!$.config.disable.length&&!$.config.enable.length&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),$.isMobile||o(),r(),$.selectedDates.length&&z(),j("Ready")}function a(e){$.config.noCalendar&&!$.selectedDates.length&&($.selectedDates=[$.now]),Q(e),z()}function r(){return $.config.wrap&&["open","close","toggle","clear"].forEach(function(e){try{$.element.querySelector("[data-"+e+"]").addEventListener("click",$[e])}catch(e){}}),"createEvent"in document&&($.changeEvent=document.createEvent("HTMLEvents"),$.changeEvent.initEvent("change",!1,!0)),$.isMobile?H():($.debouncedResize=q(C,100),$.triggerChange=function(){return j("Change")},$.debouncedChange=q($.triggerChange,1e3),"range"===$.config.mode&&$.days.addEventListener("mouseover",w),document.addEventListener("keydown",b),window.addEventListener("resize",$.debouncedResize),document.addEventListener("click",h),document.addEventListener("blur",h),$.config.clickOpens&&($.altInput||$.input).addEventListener("focus",M),$.config.noCalendar||($.prevMonthNav.addEventListener("click",function(){return p(-1)}),$.nextMonthNav.addEventListener("click",function(){return p(1)}),$.currentYearElement.addEventListener("wheel",J),$.currentYearElement.addEventListener("focus",function(){$.currentYearElement.select()}),$.currentYearElement.addEventListener("input",function(e){4===e.target.value.length&&$.currentYearElement.blur(),$.currentYear=parseInt(e.target.value,10)||$.currentYear,$.redraw()}),$.days.addEventListener("click",Y)),void($.config.enableTime&&($.timeContainer.addEventListener("wheel",a),$.timeContainer.addEventListener("input",a),$.timeContainer.addEventListener("wheel",$.debouncedChange),$.timeContainer.addEventListener("input",$.triggerChange),$.hourElement.addEventListener("focus",function(){$.hourElement.select()}),$.minuteElement.addEventListener("focus",function(){$.minuteElement.select()}),$.secondElement&&$.secondElement.addEventListener("focus",function(){$.secondElement.select()}),$.amPM&&$.amPM.addEventListener("click",a))))}function i(e){e=e?I(e):P()||$.config.minDate||$.now;try{$.currentYear=e.getFullYear(),$.currentMonth=e.getMonth()}catch(t){console.error(t.stack),console.warn("Invalid date supplied: "+e)}$.redraw()}function o(){var e=document.createDocumentFragment();$.calendarContainer=K("div","flatpickr-calendar"),$.numInputType=navigator.userAgent.indexOf("MSIE 9.0")>0?"text":"number",$.config.noCalendar||(e.appendChild(c()),$.config.weekNumbers&&e.appendChild(d()),$.rContainer=K("div","flatpickr-rContainer"),$.rContainer.appendChild(u()),$.rContainer.appendChild(l()),e.appendChild($.rContainer)),$.config.enableTime&&e.appendChild(s()),$.calendarContainer.appendChild(e),$.config.inline||$.config.static?($.calendarContainer.classList.add($.config.inline?"inline":"static"),T(),$.element.parentNode.insertBefore($.calendarContainer,($.altInput||$.input).nextSibling)):document.body.appendChild($.calendarContainer)}function l(){$.days||($.days=K("div","flatpickr-days"),$.days.tabIndex=-1),$.firstOfMonth=(new Date($.currentYear,$.currentMonth,1).getDay()-Flatpickr.l10n.firstDayOfWeek+7)%7,$.prevMonthDays=$.utils.getDaysinMonth(($.currentMonth-1+12)%12);var e=$.utils.getDaysinMonth(),t=document.createDocumentFragment(),n=$.prevMonthDays+1-$.firstOfMonth,a=void 0,r=void 0;if($.config.weekNumbers&&($.weekNumbers.innerHTML=""),"range"===$.config.mode){var i=$.config.enable.length||$.config.disable.length||$.config.mixDate||$.config.maxDate;i&&$.minRangeDate&&$.maxRangeDate||($.minRangeDate=new Date($.currentYear,$.currentMonth-1,n),$.maxRangeDate=new Date($.currentYear,$.currentMonth+1,(42-$.firstOfMonth)%e))}$.days.innerHTML="";for(var o=0;n<=$.prevMonthDays;o++,n++){var l=new Date($.currentYear,$.currentMonth-1,n,0,0,0,0,0),c=y(l),s=K("span","flatpickr-day prevMonthDay"+(c?"":" disabled")+(W(l)?" inRange":"")+(1===$.selectedDates.length&&(l<$.minRangeDate||l>$.maxRangeDate)?" notAllowed":"")+(U(l)!==!1?" selected":""),n);c?s.tabIndex=0:$.selectedDates[0]&&l>$.minRangeDate&&l<$.selectedDates[0]?$.minRangeDate=l:$.selectedDates[0]&&l<$.maxRangeDate&&l>$.selectedDates[0]&&($.maxRangeDate=l),j("DayCreate",s),t.appendChild(s)}for(n=1;n<=e;n++){a=new Date($.currentYear,$.currentMonth,n,0,0,0,0,0),$.config.weekNumbers&&n%7===1&&$.weekNumbers.insertAdjacentHTML("beforeend","<span class='disabled flatpickr-day'>"+$.getWeek(a)+"</span>"),r=!y(a);var u=K("span",r?"flatpickr-day disabled":"flatpickr-day"+(W(a)?" inRange":"")+(1===$.selectedDates.length&&(a<$.minRangeDate||a>$.maxRangeDate)?" notAllowed":""),n);r?$.selectedDates[0]&&a>$.minRangeDate&&a<$.selectedDates[0]?$.minRangeDate=a:$.selectedDates[0]&&a<$.maxRangeDate&&a>$.selectedDates[0]&&($.maxRangeDate=a):(u.tabIndex=0,V(a,$.now)&&u.classList.add("today"),U(a)&&(u.classList.add("selected"),$.selectedDateElem=u,"range"===$.config.mode&&(u.className+=V(a,$.selectedDates[0])?" startRange":$.selectedDates.length>1?" endRange":""))),j("DayCreate",u),t.appendChild(u)}for(var d=e+1;d<=42-$.firstOfMonth;d++){var p=new Date($.currentYear,$.currentMonth+1,d%e,0,0,0,0,0),f=y(p),m=K("span","flatpickr-day nextMonthDay"+(f?"":" disabled")+(W(p)?" inRange":"")+(1===$.selectedDates.length&&(p<$.minRangeDate||p>$.maxRangeDate)?" notAllowed":"")+(U(p)!==!1?" selected":""),d%e);$.config.weekNumbers&&d%7===1&&$.weekNumbers.insertAdjacentHTML("beforeend","<span class='disabled flatpickr-day'>"+$.getWeek(p)+"</span>"),f?m.tabIndex=0:$.selectedDates[0]&&p>$.minRangeDate&&p<$.selectedDates[0]?$.minRangeDate=p:$.selectedDates[0]&&p<$.maxRangeDate&&p>$.selectedDates[0]&&($.maxRangeDate=p),j("DayCreate",m),t.appendChild(m)}return $.days.appendChild(t),$.days}function c(){var e=document.createDocumentFragment();return $.monthNav=K("div","flatpickr-month"),$.prevMonthNav=K("span","flatpickr-prev-month"),$.prevMonthNav.innerHTML=$.config.prevArrow,$.currentMonthElement=K("span","cur-month"),$.currentYearElement=K("input","cur-year"),$.currentYearElement.type=$.numInputType,$.currentYearElement.title=Flatpickr.l10n.scrollTitle,$.config.minDate&&($.currentYearElement.min=$.config.minDate.getFullYear()),$.config.maxDate&&($.currentYearElement.max=$.config.maxDate.getFullYear()),$.nextMonthNav=K("span","flatpickr-next-month"),$.nextMonthNav.innerHTML=$.config.nextArrow,$.navigationCurrentMonth=K("span","flatpickr-current-month"),$.navigationCurrentMonth.appendChild($.currentMonthElement),$.navigationCurrentMonth.appendChild($.currentYearElement),e.appendChild($.prevMonthNav),e.appendChild($.navigationCurrentMonth),e.appendChild($.nextMonthNav),$.monthNav.appendChild(e),B(),$.monthNav}function s(){$.calendarContainer.classList.add("hasTime"),$.timeContainer=K("div","flatpickr-time"),$.timeContainer.tabIndex=-1;var e=K("span","flatpickr-time-separator",":");return $.hourElement=K("input","flatpickr-hour"),$.minuteElement=K("input","flatpickr-minute"),$.hourElement.tabIndex=$.minuteElement.tabIndex=0,$.hourElement.type=$.minuteElement.type=$.numInputType,$.hourElement.value=E(P()?P().getHours():$.config.defaultHour),$.minuteElement.value=E(P()?P().getMinutes():$.config.defaultMinute),$.hourElement.step=$.config.hourIncrement,$.minuteElement.step=$.config.minuteIncrement,$.hourElement.min=-($.config.time_24hr?1:0),$.hourElement.max=$.config.time_24hr?24:13,$.minuteElement.min=-$.minuteElement.step,$.minuteElement.max=60,$.hourElement.title=$.minuteElement.title=Flatpickr.l10n.scrollTitle,$.timeContainer.appendChild($.hourElement),$.timeContainer.appendChild(e),$.timeContainer.appendChild($.minuteElement),$.config.enableSeconds&&($.timeContainer.classList.add("has-seconds"),$.secondElement=K("input","flatpickr-second"),$.secondElement.type=$.numInputType,$.secondElement.value=P()?E(P().getSeconds()):"00",$.secondElement.step=$.minuteElement.step,$.secondElement.min=$.minuteElement.min,$.secondElement.max=$.minuteElement.max,$.timeContainer.appendChild(K("span","flatpickr-time-separator",":")),$.timeContainer.appendChild($.secondElement)),$.config.time_24hr||($.amPM=K("span","flatpickr-am-pm",["AM","PM"][$.hourElement.value>11|0]),$.amPM.title=Flatpickr.l10n.toggleTitle,$.amPM.tabIndex=0,$.timeContainer.appendChild($.amPM)),$.timeContainer}function u(){$.weekdayContainer||($.weekdayContainer=K("div","flatpickr-weekdays"));var e=Flatpickr.l10n.firstDayOfWeek,t=Flatpickr.l10n.weekdays.shorthand.slice();return e>0&&e<t.length&&(t=[].concat(t.splice(e,t.length),t.splice(0,e))),$.weekdayContainer.innerHTML="\n\t\t<span class=flatpickr-weekday>\n\t\t\t"+t.join("</span><span class=flatpickr-weekday>")+"\n\t\t</span>\n\t\t",$.weekdayContainer}function d(){return $.calendarContainer.classList.add("hasWeeks"),$.weekWrapper=K("div","flatpickr-weekwrapper"),$.weekWrapper.appendChild(K("span","flatpickr-weekday",Flatpickr.l10n.weekAbbreviation)),$.weekNumbers=K("div","flatpickr-weeks"),$.weekWrapper.appendChild($.weekNumbers),$.weekWrapper}function p(e,t){$.currentMonth="undefined"==typeof t||t?($.currentMonth+e+12)%12:e,D(),B(),l(),$.config.noCalendar||$.days.focus()}function f(){$.input.value="",$.altInput&&($.altInput.value=""),$.mobileInput&&($.mobileInput.value=""),$.selectedDates=[],j("Change"),i($.now)}function m(){$.isOpen=!1,$.calendarContainer.classList.remove("open"),($.altInput||$.input).classList.remove("active"),j("Close")}function g(){$.clear(),$.calendarContainer.parentNode.removeChild($.calendarContainer),$.altInput&&($.input.type="text",$.altInput.parentNode.removeChild($.altInput)),$.input.classList.remove("flatpickr-input"),$.input.removeEventListener("focus",M),$.input.removeAttribute("readonly"),document.removeEventListener("keydown",b),window.removeEventListener("resize",$.debouncedResize),document.removeEventListener("click",h),document.removeEventListener("blur",h),delete $.input._flatpickr,delete $.input}function h(e){var t=$.calendarContainer.contains(e.target),n=$.element.contains(e.target)||e.target===$.altInput;!$.isOpen||t||n||($.close(),"range"===$.config.mode&&1===$.selectedDates.length&&($.clear(),$.redraw()))}function v(e,t){var n=e.split("");return n.map(function(e,a){return $.formats[e]&&"\\"!==n[a-1]?$.formats[e](t):"\\"!==e?e:""}).join("")}function D(){($.currentMonth<0||$.currentMonth>11)&&($.currentYear+=$.currentMonth%11,$.currentMonth=($.currentMonth+12)%12)}function y(e){if($.config.minDate&&e<$.config.minDate||$.config.maxDate&&e>$.config.maxDate)return!1;if(!$.config.enable.length&&!$.config.disable.length)return!0;e=I(e,!0);for(var t,n=$.config.enable.length>0,a=n?$.config.enable:$.config.disable,r=0;r<a.length;r++){if(t=a[r],t instanceof Function&&t(e))return n;if((t instanceof Date||"string"==typeof t)&&I(t,!0).getTime()===e.getTime())return n;if("object"===("undefined"==typeof t?"undefined":_typeof(t))&&t.from&&t.to&&e>=I(t.from)&&e<=I(t.to))return n}return!n}function b(e){if($.isOpen)switch(e.which){case 13:$.timeContainer&&$.timeContainer.contains(e.target)?z():Y(e);break;case 27:$.clear(),$.close();break;case 37:e.target!==$.input&e.target!==$.altInput&&p(-1);break;case 38:e.preventDefault(),$.timeContainer&&$.timeContainer.contains(e.target)?a(e):($.currentYear++,$.redraw());break;case 39:e.target!==$.input&e.target!==$.altInput&&p(1);break;case 40:e.preventDefault(),$.timeContainer&&$.timeContainer.contains(e.target)?a(e):($.currentYear--,$.redraw())}}function k(e){return new Date($.currentYear,$.currentMonth+e.classList.contains("nextMonthDay")-e.classList.contains("prevMonthDay"),e.textContent)}function w(e){if(1===$.selectedDates.length&&e.target.classList.contains("flatpickr-day")){for(var t=k(e.target),n=Math.min(t.getTime(),$.selectedDates[0].getTime()),a=Math.max(t.getTime(),$.selectedDates[0].getTime()),r=!1,i=n;i<a;i+=$.utils.duration.DAY)if(!y(new Date(i))){r=!0;break}for(var o=k($.days.childNodes[0]).getTime(),l=0;l<42;l++,o+=$.utils.duration.DAY)o<$.minRangeDate.getTime()||o>$.maxRangeDate.getTime()?($.days.childNodes[l].classList.add("notAllowed"),$.days.childNodes[l].classList.remove("inRange")):!r&&o>Math.max($.minRangeDate.getTime(),n)&&o<Math.min($.maxRangeDate.getTime(),a)?$.days.childNodes[l].classList.add("inRange"):$.days.childNodes[l].classList.remove("inRange")}}function C(){!$.isOpen||$.config.inline||$.config.static||T()}function M(e){return $.isMobile?(e.preventDefault(),e.target.blur(),setTimeout(function(){$.mobileInput.click()},0),void j("Open")):void($.isOpen||($.altInput||$.input).disabled||$.config.inline||($.calendarContainer.classList.add("open"),$.config.static||T(),$.isOpen=!0,$.config.allowInput||(($.altInput||$.input).blur(),($.config.noCalendar?$.timeContainer:$.selectedDateElem?$.selectedDateElem:$.days).focus()),($.altInput||$.input).classList.add("active"),j("Open")))}function E(e){return("0"+e).slice(-2)}function x(){var e=["utc","wrap","weekNumbers","allowInput","clickOpens","time_24hr","enableTime","noCalendar","altInput","shorthandCurrentMonth","inline","static","enableSeconds","disableMobile"];$.config=Object.create(Flatpickr.defaultConfig);var t=_extends({},$.instanceConfig,$.element.dataset||{});Object.defineProperty($.config,"minDate",{get:function(){return this._minDate},set:function(e){this._minDate=I(e,!0),$.days&&L()}}),Object.defineProperty($.config,"maxDate",{get:function(){return this._maxDate},set:function(e){this._maxDate=I(e,!0),$.days&&L()}}),_extends($.config,t);for(var n=0;n<e.length;n++)$.config[e[n]]=$.config[e[n]]===!0||"true"===$.config[e[n]];!t.dateFormat&&t.enableTime&&($.config.dateFormat=$.config.noCalendar?"H:i"+($.config.enableSeconds?":S":""):Flatpickr.defaultConfig.dateFormat+" H:i"+($.config.enableSeconds?":S":"")),t.altInput&&t.enableTime&&!t.altFormat&&($.config.altFormat=$.config.noCalendar?"h:i"+($.config.enableSeconds?":S K":" K"):Flatpickr.defaultConfig.altFormat+(" h:i"+($.config.enableSeconds?":S":"")+" K"))}function I(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!e)return null;var n=/(\d+)/g,a=/^(\d{1,2})[:\s](\d\d)?[:\s](\d\d)?\s?(a|p)?/i,r=e;if("string"==typeof e)if(e=e.trim(),"today"===e)e=new Date,t=!0;else if($.config.parseDate)e=$.config.parseDate(e);else if(a.test(e)){var i=e.match(a),o=i[4]?i[1]%12+("p"===i[4].toLowerCase()?12:0):i[1];e=new Date,e.setHours(o,i[2]||0,i[3]||0)}else if(/Z$/.test(e)||/GMT$/.test(e))e=new Date(e);else if(n.test(e)&&/^[0-9]/.test(e)){var l=e.match(n);e=new Date(l[0]+"/"+(l[1]||1)+"/"+(l[2]||1)+" "+(l[3]||0)+":"+(l[4]||0)+":"+(l[5]||0))}else e=new Date(e);return e instanceof Date?($.config.utc&&!e.fp_isUTC&&(e=e.fp_toUTC()),t&&e.setHours(0,0,0,0),e):(console.warn("flatpickr: invalid date "+r),console.info($.element),null)}function T(){var e=$.calendarContainer.offsetHeight,t=$.altInput||$.input,n=t.getBoundingClientRect(),a=window.innerHeight-n.bottom+t.offsetHeight,r=void 0,i=window.pageXOffset+n.left;a<e?(r=window.pageYOffset-e+n.top-2,$.calendarContainer.classList.remove("arrowTop"),$.calendarContainer.classList.add("arrowBottom")):(r=window.pageYOffset+t.offsetHeight+n.top+2,$.calendarContainer.classList.remove("arrowBottom"),$.calendarContainer.classList.add("arrowTop")),$.config.inline||$.config.static||($.calendarContainer.style.top=r+"px",$.calendarContainer.style.left=i+"px")}function L(){$.config.noCalendar||$.isMobile||(u(),B(),l())}function Y(e){if(e.preventDefault(),e.stopPropagation(),$.config.allowInput&&13===e.which&&(e.target===$.altInput||$.input))return $.setDate(($.altInput||$.input).value),e.target.blur();if(e.target.classList.contains("flatpickr-day")&&!e.target.classList.contains("disabled")&&!e.target.classList.contains("notAllowed")){var t=k(e.target);if($.selectedDateElem=e.target,"single"===$.config.mode)$.selectedDates=[t],$.config.enableTime||$.close();else if("multiple"===$.config.mode){var n=U(t);n?$.selectedDates.splice(n,1):$.selectedDates.push(t)}else"range"===$.config.mode&&(2===$.selectedDates.length&&$.clear(),$.selectedDates.push(t),$.selectedDates.sort(function(e,t){return e.getTime()-t.getTime()}));t.getMonth()!==$.currentMonth&&p(t.getMonth(),!1),z(),l(),j("Change"),"range"===$.config.mode&&1===$.selectedDates.length&&w(e)}}function F(e,t){$.config[e]=t,$.redraw(),i()}function N(e,t){return e?($.selectedDates=(Array.isArray(e)?e.map(I):[I(e)]).filter(function(e){return e instanceof Date}),$.redraw(),i(),z(!1),void(t&&j("Change"))):$.clear()}function S(){$.selectedDates=[],$.now=new Date;var e=$.config.defaultDate||$.input.value;if(Array.isArray(e))$.selectedDates=e.map(I);else if(e){switch($.config.mode){case"single":$.selectedDates=[I(e)];break;case"multiple":$.selectedDates=e.split("; ").map(I);break;case"range":$.selectedDates=e.split(" to ").map(I)}$.selectedDates=$.selectedDates.filter(function(e){return e instanceof Date})}var t=$.selectedDates.length?$.selectedDates[0]:$.config.minDate||$.now;$.currentYear=t.getFullYear(),$.currentMonth=t.getMonth()}function O(){$.formats={D:function(e){return Flatpickr.l10n.weekdays.shorthand[$.formats.w(e)]},F:function(e){return $.utils.monthToStr($.formats.n(e)-1,!1)},H:function(e){return E(e.getHours())},J:function(e){return e.getDate()+Flatpickr.l10n.ordinal(e.getDate())},K:function(e){return e.getHours()>11?"PM":"AM"},M:function(e){return $.utils.monthToStr(e.getMonth(),!0)},S:function(e){return E(e.getSeconds())},U:function(e){return e.getTime()/1e3},Y:function(e){return e.getFullYear()},d:function(e){return E($.formats.j(e))},h:function(e){return e.getHours()%12?e.getHours()%12:12},i:function(e){return E(e.getMinutes())},j:function(e){return e.getDate()},l:function(e){return Flatpickr.l10n.weekdays.longhand[$.formats.w(e)]},m:function(e){return E($.formats.n(e))},n:function(e){return e.getMonth()+1},s:function(e){return e.getSeconds()},w:function(e){return e.getDay()},y:function(e){return String($.formats.Y(e)).substring(2)}}}function A(){$.utils={duration:{DAY:864e5},getDaysinMonth:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:$.currentMonth,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.currentYear;return 1===e&&t%4===0&&t%100!==0||t%400===0?29:Flatpickr.l10n.daysInMonth[e]},monthToStr:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.config.shorthandCurrentMonth;return Flatpickr.l10n.months[(t?"short":"long")+"hand"][e]}}}function R(){$.input=$.config.wrap?$.element.querySelector("[data-input]"):$.element,$.input.classList.add("flatpickr-input"),$.config.altInput&&($.altInput=K($.input.nodeName,"flatpickr-input "+$.config.altInputClass),$.altInput.placeholder=$.input.placeholder,$.altInput.type="text",$.input.type="hidden",$.input.parentNode.insertBefore($.altInput,$.input.nextSibling)),$.config.allowInput||($.altInput||$.input).setAttribute("readonly","readonly")}function H(){var e=$.config.enableTime?$.config.noCalendar?"time":"datetime-local":"date";$.mobileInput=K("input","flatpickr-input flatpickr-mobile"),$.mobileInput.step="any",$.mobileInput.tabIndex=-1,$.mobileInput.type=e,$.mobileFormatStr="datetime-local"===e?"Y-m-d\\TH:i:S":"date"===e?"Y-m-d":"H:i:S",$.selectedDates.length&&($.mobileInput.defaultValue=$.mobileInput.value=v($.mobileFormatStr,$.selectedDates[0])),$.config.minDate&&($.mobileInput.min=v("Y-m-d",$.config.minDate)),$.config.maxDate&&($.mobileInput.max=v("Y-m-d",$.config.maxDate)),$.input.type="hidden",$.config.altInput&&($.altInput.type="hidden");try{$.input.parentNode.insertBefore($.mobileInput,$.input.nextSibling)}catch(e){}$.mobileInput.addEventListener("change",function(e){$.setDate(e.target.value),j("Change"),j("Close")})}function _(){$.isOpen?$.close():$.open()}function j(e,t){if($.config["on"+e])for(var n=Array.isArray($.config["on"+e])?$.config["on"+e]:[$.config["on"+e]],a=0;a<n.length;a++)n[a]($.selectedDates,$.input.value,$,t);if("Change"===e)try{$.input.dispatchEvent(new Event("change",{bubbles:!0}))}catch(e){if("createEvent"in document)return $.input.dispatchEvent($.changeEvent);$.input.fireEvent("onchange")}}function P(){return $.selectedDates.length?$.selectedDates[$.selectedDates.length-1]:null}function U(e){if($.selectedDates.length)for(var t=0;t<$.selectedDates.length;t++)if(V($.selectedDates[t],e))return""+t;return!1}function W(e){return!("range"!==$.config.mode||$.selectedDates.length<2)&&(e>$.selectedDates[0]&&e<$.selectedDates[1])}function B(){if(!$.config.noCalendar&&!$.isMobile&&$.monthNav){if($.currentMonthElement.textContent=$.utils.monthToStr($.currentMonth)+" ",$.currentYearElement.value=$.currentYear,$.config.minDate){$.currentYearElement.min=$.config.minDate.getFullYear();var e=$.currentYear===$.config.minDate.getFullYear()?($.currentMonth+11)%12<$.config.minDate.getMonth():$.currentYear<$.config.minDate.getFullYear();$.prevMonthNav.style.display=e?"none":"block"}else $.currentYearElement.removeAttribute("min"),$.prevMonthNav.style.display="block";if($.config.maxDate){var t=$.currentYear===$.config.maxDate.getFullYear()?$.currentMonth+1>$.config.maxDate.getMonth():$.currentYear>$.config.maxDate.getFullYear();$.nextMonthNav.style.display=t?"none":"block",$.currentYearElement.max=$.config.maxDate.getFullYear()}else $.currentYearElement.removeAttribute("max"),$.nextMonthNav.style.display="block"}}function z(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(!$.selectedDates.length)return $.clear();if($.config.enableTime&&!$.isMobile){var t=void 0,n=void 0,a=void 0;e?(t=parseInt($.hourElement.value,10)||0,n=(60+(parseInt($.minuteElement.value,10)||0))%60,$.config.enableSeconds&&(a=(60+parseInt($.secondElement.value,10)||0)%60),$.config.time_24hr||(t=t%12+12*("PM"===$.amPM.innerHTML)),$.selectedDates[$.selectedDates.length-1].setHours(t,n,a||0,0)):(t=P().getHours(),n=P().getMinutes(),a=P().getSeconds()),$.hourElement.value=E($.config.time_24hr?t:(12+t)%12+12*(t%12===0)),$.minuteElement.value=E(n),$.config.time_24hr||($.amPM.textContent=t>=12?"PM":"AM"),$.config.enableSeconds&&($.secondElement.value=E(a))}switch($.isMobile&&($.mobileInput.value=$.selectedDates.length?v($.mobileFormatStr,P()):""),$.config.mode){case"single":$.input.value=v($.config.dateFormat,P()),$.altInput&&($.altInput.value=v($.config.altFormat,P()));break;case"multiple":$.input.value=$.selectedDates.map(function(e){return v($.config.dateFormat,e)}).join("; "),$.altInput&&($.altInput.value=$.selectedDates.map(function(e){return v($.config.altFormat,e)}).join("; "));break;case"range":2===$.selectedDates.length?($.altInput||$.input).value=$.selectedDates.map(function(e){return v($.config.dateFormat,e)}).join(" to "):($.altInput||$.input).value=v($.config.dateFormat,P())}j("ValueUpdate")}function J(e){e.preventDefault();var t=Math.max(-1,Math.min(1,e.wheelDelta||-e.deltaY));$.currentYear=e.target.value=parseInt(e.target.value,10)+t,$.redraw()}function K(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",a=document.createElement(e);return a.className=t,n&&(a.textContent=n),a}function q(e,t,n){var a=void 0;return function(){for(var r=arguments.length,i=Array(r),o=0;o<r;o++)i[o]=arguments[o];var l=this,c=function(){a=null,n||e.apply(l,i)};clearTimeout(a),a=setTimeout(c,t),n&&!a&&e.apply(l,i)}}function V(e,t){return e instanceof Date&&t instanceof Date&&(e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear())}function Q(e){if(e.preventDefault(),e&&((e.target.value||e.target.textContent).length>=2||"keydown"!==e.type&&"input"!==e.type)&&e.target.blur(),"flatpickr-am-pm"===e.target.className)return e.target.textContent=["AM","PM"]["AM"===e.target.textContent|0],void e.stopPropagation();var t=parseInt(e.target.min,10),n=parseInt(e.target.max,10),a=parseInt(e.target.step,10),r=parseInt(e.target.value,10),i=r;"wheel"===e.type?i=r+a*Math.max(-1,Math.min(1,e.wheelDelta||-e.deltaY)):"keydown"===e.type&&(i=r+a*(38===e.which?1:-1)),i<=t?i=n-a:i>=n&&(i=t+a),e.target.value=E(i)}var $=this;return n(),$}function _flatpickr(e,t){for(var n=[],a=0;a<e.length;a++){e[a]._flatpickr&&e[a]._flatpickr.destroy();try{e[a]._flatpickr=new Flatpickr(e[a],t||{}),n.push(e[a]._flatpickr)}catch(e){console.warn(e,e.stack)}}return 1===n.length?n[0]:n}function flatpickr(e,t){return _flatpickr(document.querySelectorAll(e),t)}var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};Flatpickr.defaultConfig={mode:"single",utc:!1,wrap:!1,weekNumbers:!1,allowInput:!1,clickOpens:!0,time_24hr:!1,enableTime:!1,noCalendar:!1,dateFormat:"Y-m-d",altInput:!1,altInputClass:"",altFormat:"F j, Y",defaultDate:null,minDate:null,maxDate:null,parseDate:null,enable:[],disable:[],shorthandCurrentMonth:!1,inline:!1,static:!1,prevArrow:"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",nextArrow:"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",enableSeconds:!1,hourIncrement:1,minuteIncrement:5,defaultHour:12,defaultMinute:0,disableMobile:!1,onChange:null,onOpen:null,onClose:null,onReady:null,onValueUpdate:null,onDayCreate:null},Flatpickr.l10n={weekdays:{shorthand:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],longhand:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},months:{shorthand:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longhand:["January","February","March","April","May","June","July","August","September","October","November","December"]},daysInMonth:[31,28,31,30,31,30,31,31,30,31,30,31],firstDayOfWeek:0,ordinal:function(e){var t=e%100;if(t>3&&t<21)return"th";switch(t%10){case 1:return"st";case 2:return"nd";case 3:return"rd";default:return"th"}},weekAbbreviation:"Wk",scrollTitle:"Scroll to increment",toggleTitle:"Click to toggle"},Flatpickr.localize=function(e){Object.keys(e).forEach(function(t){return Flatpickr.l10n[t]=e[t]})},"undefined"!=typeof HTMLElement&&(HTMLCollection.prototype.flatpickr=NodeList.prototype.flatpickr=function(e){return _flatpickr(this,e)},HTMLElement.prototype.flatpickr=function(e){return _flatpickr([this],e)}),"undefined"!=typeof jQuery&&(jQuery.fn.flatpickr=function(e){return _flatpickr(this,e)}),Date.prototype.fp_incr=function(e){return new Date(this.getFullYear(),this.getMonth(),this.getDate()+parseInt(e,10))},Date.prototype.fp_isUTC=!1,Date.prototype.fp_toUTC=function(){var e=new Date(this.getUTCFullYear(),this.getUTCMonth(),this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds());return e.fp_isUTC=!0,e},Flatpickr.prototype.getWeek=function(e){var t=new Date(e.getTime());t.setHours(0,0,0,0),t.setDate(t.getDate()+3-(t.getDay()+6)%7);var n=new Date(t.getFullYear(),0,4);return 1+Math.round(((t.getTime()-n.getTime())/864e5-3+(n.getDay()+6)%7)/7)},"classList"in document.documentElement||!Object.defineProperty||"undefined"==typeof HTMLElement||Object.defineProperty(HTMLElement.prototype,"classList",{get:function(){function e(e){return function(n){var a=t.className.split(/\s+/),r=a.indexOf(n);e(a,r,n),t.className=a.join(" ")}}var t=this,n={add:e(function(e,t,n){~t||e.push(n)}),remove:e(function(e,t){~t&&e.splice(t,1)}),toggle:e(function(e,t,n){~t?e.splice(t,1):e.push(n)}),contains:function(e){return!!~t.className.split(/\s+/).indexOf(e)},item:function(e){return t.className.split(/\s+/)[e]||null}};return Object.defineProperty(n,"length",{get:function(){return t.className.split(/\s+/).length}}),n}}),"undefined"!=typeof module&&(module.exports=Flatpickr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
2
+
3
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
+
5
+ /*! flatpickr v2.2.4-modified, @license MIT */
6
+ function Flatpickr(element, config) {
7
+ var self = this;
8
+
9
+ function init() {
10
+ if (element._flatpickr) destroy(element._flatpickr);
11
+
12
+ element._flatpickr = self;
13
+
14
+ self.element = element;
15
+ self.instanceConfig = config || {};
16
+
17
+ setupFormats();
18
+
19
+ parseConfig();
20
+ setupLocale();
21
+ setupInputs();
22
+ setupDates();
23
+
24
+ setupHelperFunctions();
25
+
26
+ self.isOpen = self.config.inline;
27
+ self.changeMonth = changeMonth;
28
+ self.clear = clear;
29
+ self.close = close;
30
+ self.destroy = destroy;
31
+ self.formatDate = formatDate;
32
+ self.jumpToDate = jumpToDate;
33
+ self.open = open;
34
+ self.parseDate = parseDate;
35
+ self.redraw = redraw;
36
+ self.set = set;
37
+ self.setDate = setDate;
38
+ self.toggle = toggle;
39
+
40
+ self.isMobile = !self.config.disableMobile && !self.config.inline && self.config.mode === "single" && !self.config.disable.length && !self.config.enable.length && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
41
+
42
+ if (!self.isMobile) build();
43
+
44
+ bind();
45
+
46
+ self.minDateHasTime = self.config.minDate && (self.config.minDate.getHours() || self.config.minDate.getMinutes() || self.config.minDate.getSeconds());
47
+
48
+ self.maxDateHasTime = self.config.maxDate && (self.config.maxDate.getHours() || self.config.maxDate.getMinutes() || self.config.maxDate.getSeconds());
49
+
50
+ if (!self.isMobile) {
51
+ Object.defineProperty(self, "dateIsPicked", {
52
+ set: function set(bool) {
53
+ if (bool) return self.calendarContainer.classList.add("dateIsPicked");
54
+ self.calendarContainer.classList.remove("dateIsPicked");
55
+ }
56
+ });
57
+ }
58
+
59
+ self.dateIsPicked = self.selectedDates.length > 0 || self.config.noCalendar;
60
+
61
+ if (self.selectedDates.length) {
62
+ if (self.config.enableTime) setHoursFromDate();
63
+ updateValue();
64
+ }
65
+
66
+ if (self.config.weekNumbers) self.calendarContainer.style.width = self.days.offsetWidth + self.weekWrapper.offsetWidth + 2 + "px";
67
+
68
+ triggerEvent("Ready");
69
+ }
70
+
71
+ function updateTime(e) {
72
+ if (self.config.noCalendar && !self.selectedDates.length)
73
+ // picking time only
74
+ self.selectedDates = [self.now];
75
+
76
+ timeWrapper(e);
77
+
78
+ if (!self.selectedDates.length) return;
79
+
80
+ setHoursFromInputs();
81
+ updateValue();
82
+ }
83
+
84
+ function setHoursFromInputs() {
85
+ if (!self.config.enableTime) return;
86
+
87
+ var hours = parseInt(self.hourElement.value, 10) || 0,
88
+ minutes = parseInt(self.minuteElement.value, 10) || 0,
89
+ seconds = self.config.enableSeconds ? parseInt(self.secondElement.value, 10) || 0 : 0;
90
+
91
+ if (self.amPM) hours = hours % 12 + 12 * (self.amPM.innerHTML === "PM");
92
+
93
+ if (self.minDateHasTime && compareDates(latestSelectedDateObj(), self.config.minDate) === 0) {
94
+ hours = Math.max(hours, self.config.minDate.getHours());
95
+ if (hours === self.config.minDate.getHours()) minutes = Math.max(minutes, self.config.minDate.getMinutes());
96
+ } else if (self.maxDateHasTime && compareDates(latestSelectedDateObj(), self.config.maxDate) === 0) {
97
+ hours = Math.min(hours, self.config.maxDate.getHours());
98
+ if (hours === self.config.maxDate.getHours()) minutes = Math.min(minutes, self.config.maxDate.getMinutes());
99
+ }
100
+
101
+ setHours(hours, minutes, seconds);
102
+ }
103
+
104
+ function setHoursFromDate(dateObj) {
105
+ var date = dateObj || latestSelectedDateObj();
106
+
107
+ if (date) setHours(date.getHours(), date.getMinutes(), date.getSeconds());
108
+ }
109
+
110
+ function setHours(hours, minutes, seconds) {
111
+ if (self.selectedDates.length) {
112
+ self.selectedDates[self.selectedDates.length - 1].setHours(hours % 24, minutes, seconds || 0, 0);
113
+ }
114
+
115
+ if (!self.config.enableTime || self.isMobile) return;
116
+
117
+ self.hourElement.value = self.pad(!self.config.time_24hr ? (12 + hours) % 12 + 12 * (hours % 12 === 0) : hours);
118
+
119
+ self.minuteElement.value = self.pad(minutes);
120
+
121
+ if (!self.config.time_24hr && self.selectedDates.length) self.amPM.textContent = latestSelectedDateObj().getHours() >= 12 ? "PM" : "AM";
122
+
123
+ if (self.config.enableSeconds) self.secondElement.value = self.pad(seconds);
124
+ }
125
+
126
+ function bind() {
127
+ if (self.config.wrap) {
128
+ ["open", "close", "toggle", "clear"].forEach(function (el) {
129
+ try {
130
+ self.element.querySelector("[data-" + el + "]").addEventListener("click", self[el]);
131
+ } catch (e) {
132
+ //
133
+ }
134
+ });
135
+ }
136
+
137
+ if ("createEvent" in document) {
138
+ self.changeEvent = document.createEvent("HTMLEvents");
139
+ self.changeEvent.initEvent("change", false, true);
140
+ }
141
+
142
+ if (self.isMobile) return setupMobile();
143
+
144
+ self.debouncedResize = debounce(onResize, 50);
145
+ self.triggerChange = function () {
146
+ return triggerEvent("Change");
147
+ };
148
+ self.debouncedChange = debounce(self.triggerChange, 1000);
149
+
150
+ if (self.config.mode === "range") self.days.addEventListener("mouseover", onMouseOver);
151
+
152
+ document.addEventListener("keydown", onKeyDown);
153
+ window.addEventListener("resize", self.debouncedResize);
154
+
155
+ var clickEvent = typeof window.ontouchstart !== "undefined" ? "touchstart" : "click";
156
+
157
+ document.addEventListener(clickEvent, documentClick);
158
+ document.addEventListener("blur", documentClick);
159
+
160
+ if (self.config.clickOpens) (self.altInput || self.input).addEventListener("focus", open);
161
+
162
+ if (!self.config.noCalendar) {
163
+ self.prevMonthNav.addEventListener("click", function () {
164
+ return changeMonth(-1);
165
+ });
166
+ self.nextMonthNav.addEventListener("click", function () {
167
+ return changeMonth(1);
168
+ });
169
+
170
+ self.currentYearElement.addEventListener("wheel", function (e) {
171
+ return debounce(yearScroll(e), 50);
172
+ });
173
+ self.currentYearElement.addEventListener("focus", function () {
174
+ self.currentYearElement.select();
175
+ });
176
+
177
+ self.currentYearElement.addEventListener("input", function (event) {
178
+ if (event.target.value.length === 4) {
179
+ self.currentYearElement.blur();
180
+ handleYearChange(event.target.value);
181
+ event.target.value = self.currentYear;
182
+ }
183
+ });
184
+
185
+ self.days.addEventListener("click", selectDate);
186
+ }
187
+
188
+ if (self.config.enableTime) {
189
+ self.timeContainer.addEventListener("wheel", function (e) {
190
+ return debounce(updateTime(e), 5);
191
+ });
192
+ self.timeContainer.addEventListener("input", updateTime);
193
+
194
+ self.timeContainer.addEventListener("wheel", self.debouncedChange);
195
+ self.timeContainer.addEventListener("input", self.triggerChange);
196
+
197
+ self.hourElement.addEventListener("focus", function () {
198
+ self.hourElement.select();
199
+ });
200
+ self.minuteElement.addEventListener("focus", function () {
201
+ self.minuteElement.select();
202
+ });
203
+
204
+ if (self.secondElement) {
205
+ self.secondElement.addEventListener("focus", function () {
206
+ self.secondElement.select();
207
+ });
208
+ }
209
+
210
+ if (self.amPM) {
211
+ self.amPM.addEventListener("click", function (e) {
212
+ updateTime(e);
213
+ self.triggerChange(e);
214
+ });
215
+ }
216
+ }
217
+ }
218
+
219
+ function jumpToDate(jumpDate) {
220
+ jumpDate = jumpDate ? parseDate(jumpDate) : latestSelectedDateObj() || (self.config.minDate > self.now ? self.config.minDate : self.now);
221
+
222
+ try {
223
+ self.currentYear = jumpDate.getFullYear();
224
+ self.currentMonth = jumpDate.getMonth();
225
+ } catch (e) {
226
+ console.error(e.stack);
227
+ console.warn("Invalid date supplied: " + jumpDate);
228
+ }
229
+
230
+ self.redraw();
231
+ }
232
+
233
+ function incrementNumInput(e, delta) {
234
+ var input = e.target.parentNode.childNodes[0];
235
+ input.value = parseInt(input.value, 10) + delta * (input.step || 1);
236
+
237
+ try {
238
+ input.dispatchEvent(new Event("input", { "bubbles": true }));
239
+ } catch (e) {
240
+ var ev = document.createEvent("CustomEvent");
241
+ ev.initCustomEvent("input", true, true, {});
242
+ input.dispatchEvent(ev);
243
+ }
244
+ }
245
+
246
+ function createNumberInput(inputClassName) {
247
+ var wrapper = createElement("div", "numInputWrapper"),
248
+ numInput = createElement("input", "numInput " + inputClassName),
249
+ arrowUp = createElement("span", "arrowUp"),
250
+ arrowDown = createElement("span", "arrowDown");
251
+
252
+ numInput.type = "text";
253
+ wrapper.appendChild(numInput);
254
+ wrapper.appendChild(arrowUp);
255
+ wrapper.appendChild(arrowDown);
256
+
257
+ arrowUp.addEventListener("click", function (e) {
258
+ return incrementNumInput(e, 1);
259
+ });
260
+ arrowDown.addEventListener("click", function (e) {
261
+ return incrementNumInput(e, -1);
262
+ });
263
+ return wrapper;
264
+ }
265
+
266
+ function build() {
267
+ var fragment = document.createDocumentFragment();
268
+ self.calendarContainer = createElement("div", "flatpickr-calendar");
269
+ self.numInputType = navigator.userAgent.indexOf("MSIE 9.0") > 0 ? "text" : "number";
270
+
271
+ if (!self.config.noCalendar) {
272
+ fragment.appendChild(buildMonthNav());
273
+ self.innerContainer = createElement("div", "flatpickr-innerContainer");
274
+
275
+ if (self.config.weekNumbers) self.innerContainer.appendChild(buildWeeks());
276
+
277
+ self.rContainer = createElement("div", "flatpickr-rContainer");
278
+ self.rContainer.appendChild(buildWeekdays());
279
+ self.rContainer.appendChild(buildDays());
280
+ self.innerContainer.appendChild(self.rContainer);
281
+ fragment.appendChild(self.innerContainer);
282
+ }
283
+
284
+ if (self.config.enableTime) fragment.appendChild(buildTime());
285
+
286
+ self.calendarContainer.appendChild(fragment);
287
+
288
+ if (self.config.inline || self.config.static) {
289
+ self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
290
+ positionCalendar();
291
+
292
+ if (self.config.appendTo && self.config.appendTo.nodeType) self.config.appendTo.appendChild(self.calendarContainer);else {
293
+ self.element.parentNode.insertBefore(self.calendarContainer, (self.altInput || self.input).nextSibling);
294
+ }
295
+ } else document.body.appendChild(self.calendarContainer);
296
+ }
297
+
298
+ function createDay(className, date, dayNumber) {
299
+ var dateIsEnabled = isEnabled(date),
300
+ dayElement = createElement("span", "flatpickr-day " + className, date.getDate());
301
+
302
+ dayElement.dateObj = date;
303
+
304
+ if (compareDates(date, self.now) === 0) dayElement.classList.add("today");
305
+
306
+ if (dateIsEnabled) {
307
+ dayElement.tabIndex = 0;
308
+
309
+ if (isDateSelected(date)) {
310
+ dayElement.classList.add("selected");
311
+
312
+ if (self.config.mode === "range") {
313
+ dayElement.classList.add(compareDates(date, self.selectedDates[0]) === 0 ? "startRange" : "endRange");
314
+ } else self.selectedDateElem = dayElement;
315
+ }
316
+ } else {
317
+ dayElement.classList.add("disabled");
318
+ if (self.selectedDates[0] && date > self.minRangeDate && date < self.selectedDates[0]) self.minRangeDate = date;else if (self.selectedDates[0] && date < self.maxRangeDate && date > self.selectedDates[0]) self.maxRangeDate = date;
319
+ }
320
+
321
+ if (self.config.mode === "range") {
322
+ if (isDateInRange(date) && !isDateSelected(date)) dayElement.classList.add("inRange");
323
+
324
+ if (self.selectedDates.length === 1 && (date < self.minRangeDate || date > self.maxRangeDate)) dayElement.classList.add("notAllowed");
325
+ }
326
+
327
+ if (self.config.weekNumbers && className !== "prevMonthDay" && dayNumber % 7 === 1) {
328
+ self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='disabled flatpickr-day'>" + self.config.getWeek(date) + "</span>");
329
+ }
330
+
331
+ triggerEvent("DayCreate", dayElement);
332
+
333
+ return dayElement;
334
+ }
335
+
336
+ function buildDays() {
337
+ if (!self.days) {
338
+ self.days = createElement("div", "flatpickr-days");
339
+ self.days.tabIndex = -1;
340
+ }
341
+
342
+ self.firstOfMonth = (new Date(self.currentYear, self.currentMonth, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;
343
+
344
+ self.prevMonthDays = self.utils.getDaysinMonth((self.currentMonth - 1 + 12) % 12);
345
+
346
+ var daysInMonth = self.utils.getDaysinMonth(),
347
+ days = document.createDocumentFragment();
348
+
349
+ var dayNumber = self.prevMonthDays + 1 - self.firstOfMonth;
350
+
351
+ if (self.config.weekNumbers) self.weekNumbers.innerHTML = "";
352
+
353
+ if (self.config.mode === "range") {
354
+ // const dateLimits = self.config.enable.length || self.config.disable.length || self.config.mixDate || self.config.maxDate;
355
+ self.minRangeDate = new Date(self.currentYear, self.currentMonth - 1, dayNumber);
356
+ self.maxRangeDate = new Date(self.currentYear, self.currentMonth + 1, (42 - self.firstOfMonth) % daysInMonth);
357
+ }
358
+
359
+ self.days.innerHTML = "";
360
+
361
+ // prepend days from the ending of previous month
362
+ for (var i = 0; dayNumber <= self.prevMonthDays; i++, dayNumber++) {
363
+ days.appendChild(createDay("prevMonthDay", new Date(self.currentYear, self.currentMonth - 1, dayNumber), dayNumber));
364
+ }
365
+
366
+ // Start at 1 since there is no 0th day
367
+ for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++) {
368
+ days.appendChild(createDay("", new Date(self.currentYear, self.currentMonth, dayNumber), dayNumber));
369
+ }
370
+
371
+ // append days from the next month
372
+ for (var dayNum = daysInMonth + 1; dayNum <= 42 - self.firstOfMonth; dayNum++) {
373
+ days.appendChild(createDay("nextMonthDay", new Date(self.currentYear, self.currentMonth + 1, dayNum % daysInMonth), dayNum));
374
+ }
375
+
376
+ self.days.appendChild(days);
377
+ return self.days;
378
+ }
379
+
380
+ function buildMonthNav() {
381
+ var monthNavFragment = document.createDocumentFragment();
382
+ self.monthNav = createElement("div", "flatpickr-month");
383
+
384
+ self.prevMonthNav = createElement("span", "flatpickr-prev-month");
385
+ self.prevMonthNav.innerHTML = self.config.prevArrow;
386
+
387
+ self.currentMonthElement = createElement("span", "cur-month");
388
+
389
+ var yearInput = createNumberInput("cur-year");
390
+ self.currentYearElement = yearInput.childNodes[0];
391
+ self.currentYearElement.title = self.l10n.scrollTitle;
392
+
393
+ if (self.config.minDate) self.currentYearElement.min = self.config.minDate.getFullYear();
394
+
395
+ if (self.config.maxDate) {
396
+ self.currentYearElement.max = self.config.maxDate.getFullYear();
397
+
398
+ self.currentYearElement.disabled = self.config.minDate && self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
399
+ }
400
+
401
+ self.nextMonthNav = createElement("span", "flatpickr-next-month");
402
+ self.nextMonthNav.innerHTML = self.config.nextArrow;
403
+
404
+ self.navigationCurrentMonth = createElement("span", "flatpickr-current-month");
405
+ self.navigationCurrentMonth.appendChild(self.currentMonthElement);
406
+ self.navigationCurrentMonth.appendChild(yearInput);
407
+
408
+ monthNavFragment.appendChild(self.prevMonthNav);
409
+ monthNavFragment.appendChild(self.navigationCurrentMonth);
410
+ monthNavFragment.appendChild(self.nextMonthNav);
411
+ self.monthNav.appendChild(monthNavFragment);
412
+
413
+ updateNavigationCurrentMonth();
414
+
415
+ return self.monthNav;
416
+ }
417
+
418
+ function buildTime() {
419
+ self.calendarContainer.classList.add("hasTime");
420
+ self.timeContainer = createElement("div", "flatpickr-time");
421
+ self.timeContainer.tabIndex = -1;
422
+ var separator = createElement("span", "flatpickr-time-separator", ":");
423
+
424
+ var hourInput = createNumberInput("flatpickr-hour");
425
+ self.hourElement = hourInput.childNodes[0];
426
+
427
+ var minuteInput = createNumberInput("flatpickr-minute");
428
+ self.minuteElement = minuteInput.childNodes[0];
429
+
430
+ self.hourElement.tabIndex = self.minuteElement.tabIndex = 0;
431
+ self.hourElement.pattern = self.minuteElement.pattern = "\d*";
432
+
433
+ self.hourElement.value = self.pad(latestSelectedDateObj() ? latestSelectedDateObj().getHours() : self.config.defaultHour);
434
+
435
+ self.minuteElement.value = self.pad(latestSelectedDateObj() ? latestSelectedDateObj().getMinutes() : self.config.defaultMinute);
436
+
437
+ self.hourElement.step = self.config.hourIncrement;
438
+ self.minuteElement.step = self.config.minuteIncrement;
439
+
440
+ self.hourElement.min = self.config.time_24hr ? 0 : 1;
441
+ self.hourElement.max = self.config.time_24hr ? 23 : 12;
442
+
443
+ self.minuteElement.min = 0;
444
+ self.minuteElement.max = 59;
445
+
446
+ self.hourElement.title = self.minuteElement.title = self.l10n.scrollTitle;
447
+
448
+ self.timeContainer.appendChild(hourInput);
449
+ self.timeContainer.appendChild(separator);
450
+ self.timeContainer.appendChild(minuteInput);
451
+
452
+ if (self.config.time_24hr) self.timeContainer.classList.add("time24hr");
453
+
454
+ if (self.config.enableSeconds) {
455
+ self.timeContainer.classList.add("hasSeconds");
456
+
457
+ var secondInput = createNumberInput("flatpickr-second");
458
+ self.secondElement = secondInput.childNodes[0];
459
+
460
+ self.secondElement.pattern = self.hourElement.pattern;
461
+ self.secondElement.value = latestSelectedDateObj() ? self.pad(latestSelectedDateObj().getSeconds()) : "00";
462
+
463
+ self.secondElement.step = self.minuteElement.step;
464
+ self.secondElement.min = self.minuteElement.min;
465
+ self.secondElement.max = self.minuteElement.max;
466
+
467
+ self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
468
+ self.timeContainer.appendChild(secondInput);
469
+ }
470
+
471
+ if (!self.config.time_24hr) {
472
+ // add self.amPM if appropriate
473
+ self.amPM = createElement("span", "flatpickr-am-pm", ["AM", "PM"][self.hourElement.value > 11 | 0]);
474
+ self.amPM.title = self.l10n.toggleTitle;
475
+ self.amPM.tabIndex = 0;
476
+ self.timeContainer.appendChild(self.amPM);
477
+ }
478
+
479
+ return self.timeContainer;
480
+ }
481
+
482
+ function buildWeekdays() {
483
+ if (!self.weekdayContainer) self.weekdayContainer = createElement("div", "flatpickr-weekdays");
484
+
485
+ var firstDayOfWeek = self.l10n.firstDayOfWeek;
486
+ var weekdays = self.l10n.weekdays.shorthand.slice();
487
+
488
+ if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
489
+ weekdays = [].concat(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));
490
+ }
491
+
492
+ self.weekdayContainer.innerHTML = "\n\t\t<span class=flatpickr-weekday>\n\t\t\t" + weekdays.join("</span><span class=flatpickr-weekday>") + "\n\t\t</span>\n\t\t";
493
+
494
+ return self.weekdayContainer;
495
+ }
496
+
497
+ function buildWeeks() {
498
+ self.calendarContainer.classList.add("hasWeeks");
499
+ self.weekWrapper = createElement("div", "flatpickr-weekwrapper");
500
+ self.weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
501
+ self.weekNumbers = createElement("div", "flatpickr-weeks");
502
+ self.weekWrapper.appendChild(self.weekNumbers);
503
+
504
+ return self.weekWrapper;
505
+ }
506
+
507
+ function changeMonth(value, is_offset) {
508
+ self.currentMonth = typeof is_offset === "undefined" || is_offset ? self.currentMonth + value : value;
509
+
510
+ handleYearChange();
511
+ updateNavigationCurrentMonth();
512
+ buildDays();
513
+
514
+ if (!self.config.noCalendar) self.days.focus();
515
+
516
+ triggerEvent("MonthChange");
517
+ }
518
+
519
+ function clear() {
520
+ var triggerChangeEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
521
+
522
+ self.input.value = "";
523
+
524
+ if (self.altInput) self.altInput.value = "";
525
+
526
+ if (self.mobileInput) self.mobileInput.value = "";
527
+
528
+ self.selectedDates = [];
529
+ self.dateIsPicked = false;
530
+
531
+ self.redraw();
532
+
533
+ if (triggerChangeEvent !== false)
534
+ // triggerChangeEvent is true (default) or an Event
535
+ triggerEvent("Change");
536
+ }
537
+
538
+ function close() {
539
+ self.isOpen = false;
540
+
541
+ if (!self.isMobile) {
542
+ self.calendarContainer.classList.remove("open");
543
+ (self.altInput || self.input).classList.remove("active");
544
+ }
545
+
546
+ triggerEvent("Close");
547
+ }
548
+
549
+ function destroy(instance) {
550
+ instance = instance || self;
551
+ instance.clear(false);
552
+
553
+ document.removeEventListener("keydown", onKeyDown);
554
+ window.removeEventListener("resize", instance.debouncedResize);
555
+
556
+ document.removeEventListener("click", documentClick);
557
+ document.removeEventListener("blur", documentClick);
558
+
559
+ if (instance.isMobile && instance.mobileInput && instance.mobileInput.parentNode) instance.mobileInput.parentNode.removeChild(instance.mobileInput);else if (instance.calendarContainer && instance.calendarContainer.parentNode) instance.calendarContainer.parentNode.removeChild(instance.calendarContainer);
560
+
561
+ if (instance.altInput) {
562
+ instance.input.type = "text";
563
+ if (instance.altInput.parentNode) instance.altInput.parentNode.removeChild(instance.altInput);
564
+ }
565
+
566
+ instance.input.classList.remove("flatpickr-input");
567
+ instance.input.removeEventListener("focus", open);
568
+ instance.input.removeAttribute("readonly");
569
+ }
570
+
571
+ function isCalendarElem(elem) {
572
+ var e = elem;
573
+ while (e) {
574
+ if (/flatpickr-day|flatpickr-calendar/.test(e.className)) return true;
575
+ e = e.parentNode;
576
+ }
577
+
578
+ return false;
579
+ }
580
+
581
+ function documentClick(e) {
582
+ var isInput = self.element.contains(e.target) || e.target === self.input || e.target === self.altInput;
583
+
584
+ if (self.isOpen && !isCalendarElem(e.target) && !isInput) {
585
+ self.close();
586
+
587
+ if (self.config.mode === "range" && self.selectedDates.length === 1) {
588
+ self.clear();
589
+ self.redraw();
590
+ }
591
+ }
592
+ }
593
+
594
+ function formatDate(frmt, dateObj) {
595
+ if (self.config.formatDate) return self.config.formatDate(frmt, dateObj);
596
+
597
+ var chars = frmt.split("");
598
+ return chars.map(function (c, i) {
599
+ return self.formats[c] && chars[i - 1] !== "\\" ? self.formats[c](dateObj) : c !== "\\" ? c : "";
600
+ }).join("");
601
+ }
602
+
603
+ function handleYearChange(newYear) {
604
+ if (self.currentMonth < 0 || self.currentMonth > 11) {
605
+ self.currentYear += self.currentMonth % 11;
606
+ self.currentMonth = (self.currentMonth + 12) % 12;
607
+ triggerEvent("YearChange");
608
+ } else if (newYear && (!self.currentYearElement.min || newYear >= self.currentYearElement.min) && (!self.currentYearElement.max || newYear <= self.currentYearElement.max)) {
609
+ self.currentYear = parseInt(newYear, 10) || self.currentYear;
610
+
611
+ if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) {
612
+ self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
613
+ } else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) {
614
+ self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
615
+ }
616
+
617
+ self.redraw();
618
+ triggerEvent("YearChange");
619
+ }
620
+ }
621
+
622
+ function isEnabled(dateToCheck) {
623
+ if (self.config.minDate && compareDates(dateToCheck, self.config.minDate) < 0 || self.config.maxDate && compareDates(dateToCheck, self.config.maxDate) > 0) return false;
624
+
625
+ if (!self.config.enable.length && !self.config.disable.length) return true;
626
+
627
+ dateToCheck = parseDate(dateToCheck, true); // timeless
628
+
629
+ var bool = self.config.enable.length > 0,
630
+ array = bool ? self.config.enable : self.config.disable;
631
+
632
+ for (var i = 0, d; i < array.length; i++) {
633
+ d = array[i];
634
+
635
+ if (d instanceof Function && d(dateToCheck)) // disabled by function
636
+ return bool;else if ((d instanceof Date || typeof d === "string") && parseDate(d, true).getTime() === dateToCheck.getTime())
637
+ // disabled by date string
638
+ return bool;else if ( // disabled by range
639
+ (typeof d === "undefined" ? "undefined" : _typeof(d)) === "object" && d.from && d.to && dateToCheck >= parseDate(d.from) && dateToCheck <= parseDate(d.to)) return bool;
640
+ }
641
+
642
+ return !bool;
643
+ }
644
+
645
+ function onKeyDown(e) {
646
+ if (self.isOpen) {
647
+ switch (e.which) {
648
+ case 13:
649
+ if (self.timeContainer && self.timeContainer.contains(e.target)) updateValue();else selectDate(e);
650
+
651
+ break;
652
+
653
+ case 27:
654
+ // escape
655
+ self.clear();
656
+ self.redraw();
657
+ self.close();
658
+ break;
659
+
660
+ case 37:
661
+ if (e.target !== self.input & e.target !== self.altInput) changeMonth(-1);
662
+ break;
663
+
664
+ case 38:
665
+ e.preventDefault();
666
+
667
+ if (self.timeContainer && self.timeContainer.contains(e.target)) updateTime(e);else {
668
+ self.currentYear++;
669
+ self.redraw();
670
+ }
671
+
672
+ break;
673
+
674
+ case 39:
675
+ if (e.target !== self.input & e.target !== self.altInput) changeMonth(1);
676
+ break;
677
+
678
+ case 40:
679
+ e.preventDefault();
680
+ if (self.timeContainer && self.timeContainer.contains(e.target)) updateTime(e);else {
681
+ self.currentYear--;
682
+ self.redraw();
683
+ }
684
+
685
+ break;
686
+
687
+ default:
688
+ break;
689
+ }
690
+ }
691
+ }
692
+
693
+ function onMouseOver(e) {
694
+ if (self.selectedDates.length !== 1 || !e.target.classList.contains("flatpickr-day")) return;
695
+
696
+ var hoverDate = e.target.dateObj,
697
+ initialDate = parseDate(self.selectedDates[0], true),
698
+ rangeStartDate = Math.min(hoverDate.getTime(), self.selectedDates[0].getTime()),
699
+ rangeEndDate = Math.max(hoverDate.getTime(), self.selectedDates[0].getTime()),
700
+ containsDisabled = false;
701
+
702
+ for (var t = rangeStartDate; t < rangeEndDate; t += self.utils.duration.DAY) {
703
+ if (!isEnabled(new Date(t))) {
704
+ containsDisabled = true;
705
+ break;
706
+ }
707
+ }
708
+
709
+ for (var timestamp = self.days.childNodes[0].dateObj.getTime(), i = 0; i < 42; i++, timestamp += self.utils.duration.DAY) {
710
+ var outOfRange = timestamp < self.minRangeDate.getTime() || timestamp > self.maxRangeDate.getTime();
711
+
712
+ if (outOfRange) {
713
+ self.days.childNodes[i].classList.add("notAllowed");
714
+ self.days.childNodes[i].classList.remove("inRange", "startRange", "endRange");
715
+ continue;
716
+ } else if (containsDisabled && !outOfRange) continue;
717
+
718
+ self.days.childNodes[i].classList.remove("startRange", "inRange", "endRange", "notAllowed");
719
+
720
+ var minRangeDate = Math.max(self.minRangeDate.getTime(), rangeStartDate),
721
+ maxRangeDate = Math.min(self.maxRangeDate.getTime(), rangeEndDate);
722
+
723
+ e.target.classList.add(hoverDate < self.selectedDates[0] ? "startRange" : "endRange");
724
+
725
+ if (initialDate > hoverDate && timestamp === initialDate.getTime()) self.days.childNodes[i].classList.add("endRange");else if (initialDate < hoverDate && timestamp === initialDate.getTime()) self.days.childNodes[i].classList.add("startRange");else if (timestamp > minRangeDate && timestamp < maxRangeDate) self.days.childNodes[i].classList.add("inRange");
726
+ }
727
+ }
728
+
729
+ function onResize() {
730
+ if (self.isOpen && !self.config.static && !self.config.inline) positionCalendar();
731
+ }
732
+
733
+ function open(e) {
734
+ if (self.isMobile) {
735
+ if (e) {
736
+ e.preventDefault();
737
+ e.target.blur();
738
+ }
739
+
740
+ setTimeout(function () {
741
+ self.mobileInput.click();
742
+ }, 0);
743
+
744
+ triggerEvent("Open");
745
+ return;
746
+ } else if (self.isOpen || (self.altInput || self.input).disabled || self.config.inline) return;
747
+
748
+ self.calendarContainer.classList.add("open");
749
+
750
+ if (!self.config.static && !self.config.inline) positionCalendar();
751
+
752
+ self.isOpen = true;
753
+
754
+ if (!self.config.allowInput) {
755
+ (self.altInput || self.input).blur();
756
+ (self.config.noCalendar ? self.timeContainer : self.selectedDateElem ? self.selectedDateElem : self.days).focus();
757
+ }
758
+
759
+ (self.altInput || self.input).classList.add("active");
760
+ triggerEvent("Open");
761
+ }
762
+
763
+ function parseConfig() {
764
+ var boolOpts = ["utc", "wrap", "weekNumbers", "allowInput", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"];
765
+ self.config = Object.create(Flatpickr.defaultConfig);
766
+ var userConfig = _extends({}, self.instanceConfig, self.element.dataset || {});
767
+
768
+ Object.defineProperty(self.config, "minDate", {
769
+ get: function get() {
770
+ return this._minDate;
771
+ },
772
+ set: function set(date) {
773
+ this._minDate = parseDate(date);
774
+
775
+ if (self.days) redraw();
776
+
777
+ if (!self.currentYearElement) return;
778
+
779
+ if (date && this._minDate instanceof Date) {
780
+ self.minDateHasTime = this._minDate.getHours() || this._minDate.getMinutes() || this._minDate.getSeconds();
781
+
782
+ self.currentYearElement.min = this._minDate.getFullYear();
783
+ } else self.currentYearElement.removeAttribute("min");
784
+
785
+ self.currentYearElement.disabled = this._maxDate && this._minDate && this._maxDate.getFullYear() === this._minDate.getFullYear();
786
+ }
787
+ });
788
+
789
+ Object.defineProperty(self.config, "maxDate", {
790
+ get: function get() {
791
+ return this._maxDate;
792
+ },
793
+ set: function set(date) {
794
+ this._maxDate = parseDate(date);
795
+ if (self.days) redraw();
796
+
797
+ if (!self.currentYearElement) return;
798
+
799
+ if (date && this._maxDate instanceof Date) {
800
+ self.currentYearElement.max = this._maxDate.getFullYear();
801
+ self.maxDateHasTime = this._maxDate.getHours() || this._maxDate.getMinutes() || this._maxDate.getSeconds();
802
+ } else self.currentYearElement.removeAttribute("max");
803
+
804
+ self.currentYearElement.disabled = this._maxDate && this._minDate && this._maxDate.getFullYear() === this._minDate.getFullYear();
805
+ }
806
+ });
807
+
808
+ _extends(self.config, userConfig);
809
+
810
+ for (var i = 0; i < boolOpts.length; i++) {
811
+ self.config[boolOpts[i]] = self.config[boolOpts[i]] === true || self.config[boolOpts[i]] === "true";
812
+ }if (!userConfig.dateFormat && userConfig.enableTime) {
813
+ self.config.dateFormat = self.config.noCalendar ? "H:i" + (self.config.enableSeconds ? ":S" : "") : Flatpickr.defaultConfig.dateFormat + " H:i" + (self.config.enableSeconds ? ":S" : "");
814
+ }
815
+
816
+ if (userConfig.altInput && userConfig.enableTime && !userConfig.altFormat) {
817
+ self.config.altFormat = self.config.noCalendar ? "h:i" + (self.config.enableSeconds ? ":S K" : " K") : Flatpickr.defaultConfig.altFormat + (" h:i" + (self.config.enableSeconds ? ":S" : "") + " K");
818
+ }
819
+ }
820
+
821
+ function setupLocale() {
822
+ if (_typeof(self.config.locale) !== "object" && typeof Flatpickr.l10ns[self.config.locale] === "undefined") console.warn("flatpickr: invalid locale " + self.config.locale);
823
+
824
+ self.l10n = _extends(Object.create(Flatpickr.l10ns.default), _typeof(self.config.locale) === "object" ? self.config.locale : self.config.locale !== "default" ? Flatpickr.l10ns[self.config.locale] || {} : {});
825
+ }
826
+
827
+ function parseDate(date) {
828
+ var timeless = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
829
+
830
+ if (!date) return null;
831
+
832
+ var dateTimeRegex = /(\d+)/g,
833
+ timeRegex = /^(\d{1,2})[:\s](\d\d)?[:\s]?(\d\d)?\s?(a|p)?/i,
834
+ timestamp = /^(\d+)$/g,
835
+ date_orig = date;
836
+
837
+ if (date.toFixed) // timestamp
838
+ date = new Date(date);else if (typeof date === "string") {
839
+ date = date.trim();
840
+
841
+ if (date === "today") {
842
+ date = new Date();
843
+ timeless = true;
844
+ } else if (self.config.parseDate) date = self.config.parseDate(date);else if (timeRegex.test(date)) {
845
+ // time picker
846
+ var m = date.match(timeRegex),
847
+ hours = !m[4] ? m[1] // military time, no conversion needed
848
+ : m[1] % 12 + (m[4].toLowerCase() === "p" ? 12 : 0); // am/pm
849
+
850
+ date = new Date();
851
+ date.setHours(hours, m[2] || 0, m[3] || 0);
852
+ } else if (/Z$/.test(date) || /GMT$/.test(date)) // datestrings w/ timezone
853
+ date = new Date(date);else if (dateTimeRegex.test(date) && /^[0-9]/.test(date)) {
854
+ var d = date.match(dateTimeRegex);
855
+ date = new Date(d[0] + "/" + (d[1] || 1) + "/" + (d[2] || 1) + " " + (d[3] || 0) + ":" + (d[4] || 0) + ":" + (d[5] || 0));
856
+ } else // fallback
857
+ date = new Date(date);
858
+ }
859
+
860
+ if (!(date instanceof Date)) {
861
+ console.warn("flatpickr: invalid date " + date_orig);
862
+ console.info(self.element);
863
+ return null;
864
+ }
865
+
866
+ if (self.config.utc && !date.fp_isUTC) date = date.fp_toUTC();
867
+
868
+ if (timeless) date.setHours(0, 0, 0, 0);
869
+
870
+ return date;
871
+ }
872
+
873
+ function positionCalendar() {
874
+ var calendarHeight = self.calendarContainer.offsetHeight,
875
+ input = self.altInput || self.input,
876
+ inputBounds = input.getBoundingClientRect(),
877
+ distanceFromBottom = window.innerHeight - inputBounds.bottom + input.offsetHeight;
878
+
879
+ var top = void 0,
880
+ left = window.pageXOffset + inputBounds.left;
881
+
882
+ if (distanceFromBottom < calendarHeight) {
883
+ top = window.pageYOffset - calendarHeight + inputBounds.top - 2;
884
+ self.calendarContainer.classList.remove("arrowTop");
885
+ self.calendarContainer.classList.add("arrowBottom");
886
+ } else {
887
+ top = window.pageYOffset + input.offsetHeight + inputBounds.top + 2;
888
+ self.calendarContainer.classList.remove("arrowBottom");
889
+ self.calendarContainer.classList.add("arrowTop");
890
+ }
891
+
892
+ if (!self.config.static && !self.config.inline) {
893
+ self.calendarContainer.style.top = top + "px";
894
+ self.calendarContainer.style.left = left + "px";
895
+ }
896
+ }
897
+
898
+ function redraw() {
899
+ if (self.config.noCalendar || self.isMobile) return;
900
+
901
+ buildWeekdays();
902
+ updateNavigationCurrentMonth();
903
+ buildDays();
904
+ }
905
+
906
+ function selectDate(e) {
907
+ if (self.config.allowInput && e.which === 13 && e.target === (self.altInput || self.input)) return self.setDate((self.altInput || self.input).value), e.target.blur();
908
+
909
+ if (!e.target.classList.contains("flatpickr-day") || e.target.classList.contains("disabled") || e.target.classList.contains("notAllowed")) return;
910
+
911
+ var selectedDate = e.target.dateObj;
912
+ self.selectedDateElem = e.target;
913
+
914
+ if (self.config.mode === "single") {
915
+ self.selectedDates = [selectedDate];
916
+
917
+ if (!self.config.enableTime) self.close();
918
+ } else if (self.config.mode === "multiple") {
919
+ var selectedIndex = isDateSelected(selectedDate);
920
+ if (selectedIndex) self.selectedDates.splice(selectedIndex, 1);else self.selectedDates.push(selectedDate);
921
+ } else if (self.config.mode === "range") {
922
+ if (self.selectedDates.length === 2) self.clear();
923
+
924
+ self.selectedDates.push(selectedDate);
925
+ self.selectedDates.sort(function (a, b) {
926
+ return a.getTime() - b.getTime();
927
+ });
928
+ }
929
+
930
+ setHoursFromInputs();
931
+
932
+ if (selectedDate.getMonth() !== self.currentMonth && self.config.mode !== "range") {
933
+ self.currentYear = selectedDate.getFullYear();
934
+ self.currentMonth = selectedDate.getMonth();
935
+ updateNavigationCurrentMonth();
936
+ }
937
+
938
+ buildDays();
939
+
940
+ if (self.minDateHasTime && self.config.enableTime && compareDates(selectedDate, self.config.minDate) === 0) setHoursFromDate(self.config.minDate);
941
+
942
+ updateValue();
943
+
944
+ setTimeout(function () {
945
+ return self.dateIsPicked = true;
946
+ }, 50);
947
+
948
+ if (self.config.mode === "range" && self.selectedDates.length === 1) onMouseOver(e);
949
+
950
+ triggerEvent("Change");
951
+ }
952
+
953
+ function set(option, value) {
954
+ self.config[option] = value;
955
+ self.redraw();
956
+ jumpToDate();
957
+ }
958
+
959
+ function setDate(date, triggerChange) {
960
+ if (!date) return self.clear();
961
+
962
+ self.selectedDates = (Array.isArray(date) ? date.map(parseDate) : [parseDate(date)]).filter(function (d) {
963
+ return d instanceof Date && isEnabled(d);
964
+ });
965
+ self.redraw();
966
+ jumpToDate();
967
+
968
+ setHoursFromDate();
969
+ updateValue();
970
+
971
+ self.dateIsPicked = self.selectedDates.length > 0;
972
+
973
+ if (triggerChange) triggerEvent("Change");
974
+ }
975
+
976
+ function setupDates() {
977
+ self.selectedDates = [];
978
+ self.now = new Date();
979
+ var inputDate = self.config.defaultDate || self.input.value;
980
+
981
+ if (Array.isArray(inputDate)) self.selectedDates = inputDate.map(parseDate);else if (inputDate) {
982
+ switch (self.config.mode) {
983
+ case "single":
984
+ self.selectedDates = [parseDate(inputDate)];
985
+ break;
986
+
987
+ case "multiple":
988
+ self.selectedDates = inputDate.split("; ").map(parseDate);
989
+ break;
990
+
991
+ case "range":
992
+ self.selectedDates = inputDate.split(self.l10n.rangeSeparator).map(parseDate);
993
+ break;
994
+
995
+ default:
996
+ break;
997
+ }
998
+ }
999
+
1000
+ self.selectedDates = self.selectedDates.filter(function (d) {
1001
+ return d instanceof Date && d.getTime() && isEnabled(d);
1002
+ });
1003
+
1004
+ var initialDate = self.selectedDates.length ? self.selectedDates[0] : self.config.minDate > self.now ? self.config.minDate : self.now;
1005
+
1006
+ self.currentYear = initialDate.getFullYear();
1007
+ self.currentMonth = initialDate.getMonth();
1008
+ }
1009
+
1010
+ function setupHelperFunctions() {
1011
+ self.utils = {
1012
+ duration: {
1013
+ DAY: 86400000
1014
+ },
1015
+ getDaysinMonth: function getDaysinMonth() {
1016
+ var month = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : self.currentMonth;
1017
+ var yr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : self.currentYear;
1018
+
1019
+ if (month === 1 && (yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0)) return 29;
1020
+ return self.l10n.daysInMonth[month];
1021
+ },
1022
+
1023
+ monthToStr: function monthToStr(monthNumber) {
1024
+ var short = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : self.config.shorthandCurrentMonth;
1025
+ return self.l10n.months[(short ? "short" : "long") + "hand"][monthNumber];
1026
+ }
1027
+ };
1028
+ }
1029
+
1030
+ function setupFormats() {
1031
+ self.formats = {
1032
+ // weekday name, short, e.g. Thu
1033
+ D: function D(date) {
1034
+ return self.l10n.weekdays.shorthand[self.formats.w(date)];
1035
+ },
1036
+
1037
+ // full month name e.g. January
1038
+ F: function F(date) {
1039
+ return self.utils.monthToStr(self.formats.n(date) - 1, false);
1040
+ },
1041
+
1042
+ // hours with leading zero e.g. 03
1043
+ H: function H(date) {
1044
+ return Flatpickr.prototype.pad(date.getHours());
1045
+ },
1046
+
1047
+ // day (1-30) with ordinal suffix e.g. 1st, 2nd
1048
+ J: function J(date) {
1049
+ return date.getDate() + self.l10n.ordinal(date.getDate());
1050
+ },
1051
+
1052
+ // AM/PM
1053
+ K: function K(date) {
1054
+ return date.getHours() > 11 ? "PM" : "AM";
1055
+ },
1056
+
1057
+ // shorthand month e.g. Jan, Sep, Oct, etc
1058
+ M: function M(date) {
1059
+ return self.utils.monthToStr(date.getMonth(), true);
1060
+ },
1061
+
1062
+ // seconds 00-59
1063
+ S: function S(date) {
1064
+ return Flatpickr.prototype.pad(date.getSeconds());
1065
+ },
1066
+
1067
+ // unix timestamp
1068
+ U: function U(date) {
1069
+ return date.getTime() / 1000;
1070
+ },
1071
+
1072
+ // full year e.g. 2016
1073
+ Y: function Y(date) {
1074
+ return date.getFullYear();
1075
+ },
1076
+
1077
+ // day in month, padded (01-30)
1078
+ d: function d(date) {
1079
+ return Flatpickr.prototype.pad(self.formats.j(date));
1080
+ },
1081
+
1082
+ // hour from 1-12 (am/pm)
1083
+ h: function h(date) {
1084
+ return date.getHours() % 12 ? date.getHours() % 12 : 12;
1085
+ },
1086
+
1087
+ // minutes, padded with leading zero e.g. 09
1088
+ i: function i(date) {
1089
+ return Flatpickr.prototype.pad(date.getMinutes());
1090
+ },
1091
+
1092
+ // day in month (1-30)
1093
+ j: function j(date) {
1094
+ return date.getDate();
1095
+ },
1096
+
1097
+ // weekday name, full, e.g. Thursday
1098
+ l: function l(date) {
1099
+ return self.l10n.weekdays.longhand[self.formats.w(date)];
1100
+ },
1101
+
1102
+ // padded month number (01-12)
1103
+ m: function m(date) {
1104
+ return Flatpickr.prototype.pad(self.formats.n(date));
1105
+ },
1106
+
1107
+ // the month number (1-12)
1108
+ n: function n(date) {
1109
+ return date.getMonth() + 1;
1110
+ },
1111
+
1112
+ // seconds 0-59
1113
+ s: function s(date) {
1114
+ return date.getSeconds();
1115
+ },
1116
+
1117
+ // number of the day of the week
1118
+ w: function w(date) {
1119
+ return date.getDay();
1120
+ },
1121
+
1122
+ // last two digits of year e.g. 16 for 2016
1123
+ y: function y(date) {
1124
+ return String(self.formats.Y(date)).substring(2);
1125
+ }
1126
+ };
1127
+ }
1128
+
1129
+ function setupInputs() {
1130
+ self.input = self.config.wrap ? self.element.querySelector("[data-input]") : self.element;
1131
+
1132
+ self.input.classList.add("flatpickr-input");
1133
+ if (self.config.altInput) {
1134
+ // replicate self.element
1135
+ self.altInput = createElement(self.input.nodeName, self.config.altInputClass);
1136
+ self.altInput.placeholder = self.input.placeholder;
1137
+ self.altInput.type = "text";
1138
+
1139
+ self.input.type = "hidden";
1140
+ if (self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
1141
+ }
1142
+
1143
+ if (!self.config.allowInput) (self.altInput || self.input).setAttribute("readonly", "readonly");
1144
+ }
1145
+
1146
+ function setupMobile() {
1147
+
1148
+ if (self.input.parentNode) {
1149
+ var inputPrevious = self.input.parentNode.querySelector('.flatpickr-mobile');
1150
+ if (inputPrevious)
1151
+ self.input.parentNode.removeChild(inputPrevious);
1152
+ }
1153
+
1154
+ var inputType = self.config.enableTime ? self.config.noCalendar ? "time" : "datetime-local" : "date";
1155
+
1156
+ self.mobileInput = createElement("input", "flatpickr-input flatpickr-mobile");
1157
+ self.mobileInput.step = "any";
1158
+ self.mobileInput.tabIndex = -1;
1159
+ self.mobileInput.type = inputType;
1160
+ self.mobileInput.disabled = self.input.disabled;
1161
+
1162
+ self.mobileFormatStr = inputType === "datetime-local" ? "Y-m-d\\TH:i:S" : inputType === "date" ? "Y-m-d" : "H:i:S";
1163
+
1164
+ if (self.selectedDates.length) {
1165
+ self.mobileInput.defaultValue = self.mobileInput.value = formatDate(self.mobileFormatStr, self.selectedDates[0]);
1166
+ }
1167
+
1168
+ if (self.config.minDate) self.mobileInput.min = formatDate("Y-m-d", self.config.minDate);
1169
+
1170
+ if (self.config.maxDate) self.mobileInput.max = formatDate("Y-m-d", self.config.maxDate);
1171
+
1172
+ self.input.type = "hidden";
1173
+ if (self.config.altInput) self.altInput.type = "hidden";
1174
+
1175
+ try {
1176
+ self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
1177
+ } catch (e) {
1178
+ //
1179
+ }
1180
+
1181
+ self.mobileInput.addEventListener("change", function (e) {
1182
+ self.setDate(e.target.value);
1183
+ triggerEvent("Change");
1184
+ triggerEvent("Close");
1185
+ });
1186
+ }
1187
+
1188
+ function toggle() {
1189
+ if (self.isOpen) self.close();else self.open();
1190
+ }
1191
+
1192
+ function triggerEvent(event, data) {
1193
+ if (self.config["on" + event]) {
1194
+ var hooks = Array.isArray(self.config["on" + event]) ? self.config["on" + event] : [self.config["on" + event]];
1195
+
1196
+ for (var i = 0; i < hooks.length; i++) {
1197
+ hooks[i](self.selectedDates, self.input.value, self, data);
1198
+ }
1199
+ }
1200
+
1201
+ if (event === "Change") {
1202
+ try {
1203
+ self.input.dispatchEvent(new Event("change", { "bubbles": true }));
1204
+
1205
+ // many front-end frameworks bind to the input event
1206
+ self.input.dispatchEvent(new Event("input", { "bubbles": true }));
1207
+ } catch (e) {
1208
+ if ("createEvent" in document) return self.input.dispatchEvent(self.changeEvent);
1209
+
1210
+ self.input.fireEvent("onchange");
1211
+ }
1212
+ }
1213
+ }
1214
+
1215
+ function latestSelectedDateObj() {
1216
+ if (self.selectedDates.length) return self.selectedDates[self.selectedDates.length - 1];
1217
+ return null;
1218
+ }
1219
+
1220
+ function isDateSelected(date) {
1221
+ for (var i = 0; i < self.selectedDates.length; i++) {
1222
+ if (compareDates(self.selectedDates[i], date) === 0) return "" + i;
1223
+ }
1224
+
1225
+ return false;
1226
+ }
1227
+
1228
+ function isDateInRange(date) {
1229
+ if (self.config.mode !== "range" || self.selectedDates.length < 2) return false;
1230
+ return compareDates(date, self.selectedDates[0]) >= 0 && compareDates(date, self.selectedDates[1]) <= 0;
1231
+ }
1232
+
1233
+ function updateNavigationCurrentMonth() {
1234
+ if (self.config.noCalendar || self.isMobile || !self.monthNav) return;
1235
+
1236
+ self.currentMonthElement.textContent = self.utils.monthToStr(self.currentMonth) + " ";
1237
+ self.currentYearElement.value = self.currentYear;
1238
+
1239
+ if (self.config.minDate) {
1240
+ var hidePrevMonthArrow = self.currentYear === self.config.minDate.getFullYear() ? (self.currentMonth + 11) % 12 < self.config.minDate.getMonth() : self.currentYear < self.config.minDate.getFullYear();
1241
+
1242
+ self.prevMonthNav.style.display = hidePrevMonthArrow ? "none" : "block";
1243
+ } else self.prevMonthNav.style.display = "block";
1244
+
1245
+ if (self.config.maxDate) {
1246
+ var hideNextMonthArrow = self.currentYear === self.config.maxDate.getFullYear() ? self.currentMonth + 1 > self.config.maxDate.getMonth() : self.currentYear > self.config.maxDate.getFullYear();
1247
+
1248
+ self.nextMonthNav.style.display = hideNextMonthArrow ? "none" : "block";
1249
+ } else self.nextMonthNav.style.display = "block";
1250
+ }
1251
+
1252
+ function updateValue() {
1253
+ if (!self.selectedDates.length) return self.clear();
1254
+
1255
+ if (self.isMobile) {
1256
+ self.mobileInput.value = self.selectedDates.length ? formatDate(self.mobileFormatStr, latestSelectedDateObj()) : "";
1257
+ }
1258
+
1259
+ var joinChar = self.config.mode !== "range" ? "; " : self.l10n.rangeSeparator;
1260
+
1261
+ self.input.value = self.selectedDates.map(function (dObj) {
1262
+ return formatDate(self.config.dateFormat, dObj);
1263
+ }).join(joinChar);
1264
+
1265
+ if (self.config.altInput) {
1266
+ self.altInput.value = self.selectedDates.map(function (dObj) {
1267
+ return formatDate(self.config.altFormat, dObj);
1268
+ }).join(joinChar);
1269
+ }
1270
+
1271
+ triggerEvent("ValueUpdate");
1272
+ }
1273
+
1274
+ function yearScroll(e) {
1275
+ e.preventDefault();
1276
+
1277
+ var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY)),
1278
+ newYear = parseInt(e.target.value, 10) + delta;
1279
+
1280
+ handleYearChange(newYear);
1281
+ e.target.value = self.currentYear;
1282
+ }
1283
+
1284
+ function createElement(tag) {
1285
+ var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
1286
+ var content = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
1287
+
1288
+ var e = document.createElement(tag);
1289
+ e.className = className;
1290
+
1291
+ if (content) e.innerHTML = content;
1292
+
1293
+ return e;
1294
+ }
1295
+
1296
+ function debounce(func, wait, immediate) {
1297
+ var timeout = void 0;
1298
+ return function () {
1299
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
1300
+ args[_key] = arguments[_key];
1301
+ }
1302
+
1303
+ var context = this;
1304
+ var later = function later() {
1305
+ timeout = null;
1306
+ if (!immediate) func.apply(context, args);
1307
+ };
1308
+
1309
+ clearTimeout(timeout);
1310
+ timeout = setTimeout(later, wait);
1311
+ if (immediate && !timeout) func.apply(context, args);
1312
+ };
1313
+ }
1314
+
1315
+ function compareDates(date1, date2) {
1316
+ if (!(date1 instanceof Date) || !(date2 instanceof Date)) return false;
1317
+
1318
+ return new Date(date1.getTime()).setHours(0, 0, 0, 0) - new Date(date2.getTime()).setHours(0, 0, 0, 0);
1319
+ }
1320
+
1321
+ function timeWrapper(e) {
1322
+ e.preventDefault();
1323
+ if (e && ((e.target.value || e.target.textContent).length >= 2 || // typed two digits
1324
+ e.type !== "keydown" && e.type !== "input" // scroll event
1325
+ )) e.target.blur();
1326
+
1327
+ if (self.amPM && e.target === self.amPM) return e.target.textContent = ["AM", "PM"][e.target.textContent === "AM" | 0];
1328
+
1329
+ var min = Number(e.target.min),
1330
+ max = Number(e.target.max),
1331
+ step = Number(e.target.step),
1332
+ curValue = parseInt(e.target.value, 10),
1333
+ delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY));
1334
+
1335
+ var newValue = Number(curValue);
1336
+
1337
+ if (e.type === "wheel") newValue = curValue + step * delta;else if (e.type === "keydown") newValue = curValue + step * (e.which === 38 ? 1 : -1);
1338
+
1339
+ if (newValue < min) {
1340
+ newValue = max + newValue + (e.target !== self.hourElement) + (e.target === self.hourElement && !self.amPM);
1341
+ } else if (newValue > max) {
1342
+ newValue = e.target === self.hourElement ? newValue - max - !self.amPM : min;
1343
+ }
1344
+
1345
+ if (self.amPM && e.target === self.hourElement && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) self.amPM.textContent = self.amPM.innerHTML === "PM" ? "AM" : "PM";
1346
+
1347
+ e.target.value = self.pad(newValue);
1348
+ }
1349
+
1350
+ init();
1351
+ return self;
1352
+ }
1353
+
1354
+ Flatpickr.defaultConfig = {
1355
+
1356
+ mode: "single",
1357
+
1358
+ /* if true, dates will be parsed, formatted, and displayed in UTC.
1359
+ preloading date strings w/ timezones is recommended but not necessary */
1360
+ utc: false,
1361
+
1362
+ // wrap: see https://chmln.github.io/flatpickr/#strap
1363
+ wrap: false,
1364
+
1365
+ // enables week numbers
1366
+ weekNumbers: false,
1367
+
1368
+ // allow manual datetime input
1369
+ allowInput: false,
1370
+
1371
+ /*
1372
+ clicking on input opens the date(time)picker.
1373
+ disable if you wish to open the calendar manually with .open()
1374
+ */
1375
+ clickOpens: true,
1376
+
1377
+ // display time picker in 24 hour mode
1378
+ time_24hr: false,
1379
+
1380
+ // enables the time picker functionality
1381
+ enableTime: false,
1382
+
1383
+ // noCalendar: true will hide the calendar. use for a time picker along w/ enableTime
1384
+ noCalendar: false,
1385
+
1386
+ // more date format chars at https://chmln.github.io/flatpickr/#dateformat
1387
+ dateFormat: "Y-m-d",
1388
+
1389
+ // altInput - see https://chmln.github.io/flatpickr/#altinput
1390
+ altInput: false,
1391
+
1392
+ // the created altInput element will have this class.
1393
+ altInputClass: "form-control input",
1394
+
1395
+ // same as dateFormat, but for altInput
1396
+ altFormat: "F j, Y", // defaults to e.g. June 10, 2016
1397
+
1398
+ // defaultDate - either a datestring or a date object. used for datetimepicker"s initial value
1399
+ defaultDate: null,
1400
+
1401
+ // the minimum date that user can pick (inclusive)
1402
+ minDate: null,
1403
+
1404
+ // the maximum date that user can pick (inclusive)
1405
+ maxDate: null,
1406
+
1407
+ // dateparser that transforms a given string to a date object
1408
+ parseDate: null,
1409
+
1410
+ // dateformatter that transforms a given date object to a string, according to passed format
1411
+ formatDate: null,
1412
+
1413
+ getWeek: function getWeek(givenDate) {
1414
+ var date = new Date(givenDate.getTime());
1415
+ date.setHours(0, 0, 0, 0);
1416
+
1417
+ // Thursday in current week decides the year.
1418
+ date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
1419
+ // January 4 is always in week 1.
1420
+ var week1 = new Date(date.getFullYear(), 0, 4);
1421
+ // Adjust to Thursday in week 1 and count number of weeks from date to week1.
1422
+ return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
1423
+ },
1424
+
1425
+ // see https://chmln.github.io/flatpickr/#disable
1426
+ enable: [],
1427
+
1428
+ // see https://chmln.github.io/flatpickr/#disable
1429
+ disable: [],
1430
+
1431
+ // display the short version of month names - e.g. Sep instead of September
1432
+ shorthandCurrentMonth: false,
1433
+
1434
+ // displays calendar inline. see https://chmln.github.io/flatpickr/#inline-calendar
1435
+ inline: false,
1436
+
1437
+ // position calendar inside wrapper and next to the input element
1438
+ // leave at false unless you know what you"re doing
1439
+ static: false,
1440
+
1441
+ // DOM node to append the calendar to in *static* mode
1442
+ appendTo: null,
1443
+
1444
+ // code for previous/next icons. this is where you put your custom icon code e.g. fontawesome
1445
+ prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
1446
+ nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
1447
+
1448
+ // enables seconds in the time picker
1449
+ enableSeconds: false,
1450
+
1451
+ // step size used when scrolling/incrementing the hour element
1452
+ hourIncrement: 1,
1453
+
1454
+ // step size used when scrolling/incrementing the minute element
1455
+ minuteIncrement: 5,
1456
+
1457
+ // initial value in the hour element
1458
+ defaultHour: 12,
1459
+
1460
+ // initial value in the minute element
1461
+ defaultMinute: 0,
1462
+
1463
+ // disable native mobile datetime input support
1464
+ disableMobile: false,
1465
+
1466
+ // default locale
1467
+ locale: "default",
1468
+
1469
+ // onChange callback when user selects a date or time
1470
+ onChange: null, // function (dateObj, dateStr) {}
1471
+
1472
+ // called every time calendar is opened
1473
+ onOpen: null, // function (dateObj, dateStr) {}
1474
+
1475
+ // called every time calendar is closed
1476
+ onClose: null, // function (dateObj, dateStr) {}
1477
+
1478
+ // called after calendar is ready
1479
+ onReady: null, // function (dateObj, dateStr) {}
1480
+
1481
+ onValueUpdate: null,
1482
+
1483
+ onDayCreate: null
1484
+ };
1485
+
1486
+ Flatpickr.l10ns = {
1487
+ en: {
1488
+ weekdays: {
1489
+ shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
1490
+ longhand: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
1491
+ },
1492
+ months: {
1493
+ shorthand: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1494
+ longhand: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
1495
+ },
1496
+ daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
1497
+ firstDayOfWeek: 0,
1498
+ ordinal: function ordinal(nth) {
1499
+ var s = nth % 100;
1500
+ if (s > 3 && s < 21) return "th";
1501
+ switch (s % 10) {
1502
+ case 1:
1503
+ return "st";
1504
+ case 2:
1505
+ return "nd";
1506
+ case 3:
1507
+ return "rd";
1508
+ default:
1509
+ return "th";
1510
+ }
1511
+ },
1512
+ rangeSeparator: " to ",
1513
+ weekAbbreviation: "Wk",
1514
+ scrollTitle: "Scroll to increment",
1515
+ toggleTitle: "Click to toggle"
1516
+ }
1517
+ };
1518
+
1519
+ Flatpickr.l10ns.default = Flatpickr.l10ns.en;
1520
+
1521
+ Flatpickr.localize = function (l10n) {
1522
+ return _extends(Flatpickr.l10ns.default, l10n || {});
1523
+ };
1524
+
1525
+ Flatpickr.prototype = {
1526
+ pad: function pad(number) {
1527
+ return ("0" + number).slice(-2);
1528
+ }
1529
+ };
1530
+
1531
+ function _flatpickr(nodeList, config) {
1532
+ var instances = [];
1533
+ for (var i = 0; i < nodeList.length; i++) {
1534
+ try {
1535
+ nodeList[i]._flatpickr = new Flatpickr(nodeList[i], config || {});
1536
+ instances.push(nodeList[i]._flatpickr);
1537
+ } catch (e) {
1538
+ console.warn(e, e.stack);
1539
+ }
1540
+ }
1541
+
1542
+ return instances.length === 1 ? instances[0] : instances;
1543
+ }
1544
+ if (typeof HTMLElement !== "undefined") {
1545
+ // browser env
1546
+ HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
1547
+ return _flatpickr(this, config);
1548
+ };
1549
+
1550
+ HTMLElement.prototype.flatpickr = function (config) {
1551
+ return _flatpickr([this], config);
1552
+ };
1553
+ }
1554
+
1555
+ function flatpickr(selector, config) {
1556
+ return _flatpickr(document.querySelectorAll(selector), config);
1557
+ }
1558
+
1559
+ if (typeof jQuery !== "undefined") {
1560
+ jQuery.fn.flatpickr = function (config) {
1561
+ return _flatpickr(this, config);
1562
+ };
1563
+ }
1564
+
1565
+ Date.prototype.fp_incr = function (days) {
1566
+ return new Date(this.getFullYear(), this.getMonth(), this.getDate() + parseInt(days, 10));
1567
+ };
1568
+
1569
+ Date.prototype.fp_isUTC = false;
1570
+ Date.prototype.fp_toUTC = function () {
1571
+ var newDate = new Date(this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds());
1572
+
1573
+ newDate.fp_isUTC = true;
1574
+ return newDate;
1575
+ };
1576
+
1577
+ // IE9 classList polyfill
1578
+ if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== "undefined") {
1579
+ Object.defineProperty(HTMLElement.prototype, "classList", {
1580
+ get: function get() {
1581
+ var self = this;
1582
+ function update(fn) {
1583
+ return function (value) {
1584
+ var classes = self.className.split(/\s+/),
1585
+ index = classes.indexOf(value);
1586
+
1587
+ fn(classes, index, value);
1588
+ self.className = classes.join(" ");
1589
+ };
1590
+ }
1591
+
1592
+ var ret = {
1593
+ add: update(function (classes, index, value) {
1594
+ if (!~index) classes.push(value);
1595
+ }),
1596
+
1597
+ remove: update(function (classes, index) {
1598
+ if (~index) classes.splice(index, 1);
1599
+ }),
1600
+
1601
+ toggle: update(function (classes, index, value) {
1602
+ if (~index) classes.splice(index, 1);else classes.push(value);
1603
+ }),
1604
+
1605
+ contains: function contains(value) {
1606
+ return !!~self.className.split(/\s+/).indexOf(value);
1607
+ },
1608
+
1609
+ item: function item(i) {
1610
+ return self.className.split(/\s+/)[i] || null;
1611
+ }
1612
+ };
1613
+
1614
+ Object.defineProperty(ret, "length", {
1615
+ get: function get() {
1616
+ return self.className.split(/\s+/).length;
1617
+ }
1618
+ });
1619
+
1620
+ return ret;
1621
+ }
1622
+ });
1623
+ }
1624
+
1625
+ if (typeof module !== "undefined") module.exports = Flatpickr;
assets/js/wpforms.js CHANGED
@@ -55,10 +55,10 @@
55
  loadValidation: function() {
56
 
57
  // Only load if jQuery validation library exists
58
- if (typeof $.fn.validate !== 'undefined') {
59
 
60
  // Payments: Validate method for Credit Card Number
61
- if(typeof $.fn.payment !== 'undefined') {
62
  $.validator.addMethod( "creditcard", function(value, element) {
63
  //var type = $.payment.cardType(value);
64
  var valid = $.payment.validateCardNumber(value);
@@ -113,7 +113,7 @@
113
 
114
  // Validate 24-hour time
115
  $.validator.addMethod( "time24h", function( value, element ) {
116
- return this.optional(element) || /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(\ ?[AP]M)?$/i.test(value);
117
  }, "Please enter time in 24-hour format (eg 22:45)" );
118
 
119
  // Finally load jQuery Validation library for our forms
@@ -121,7 +121,7 @@
121
  var form = $(this),
122
  formID = form.data('formid');
123
 
124
- if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('validate')) {
125
  properties = window['wpforms_'+formID].validate;
126
  } else if ( typeof wpforms_validate != "undefined") {
127
  properties = wpforms_validate;
@@ -140,6 +140,14 @@
140
  error.insertAfter(element);
141
  }
142
  },
 
 
 
 
 
 
 
 
143
  submitHandler: function(form) {
144
 
145
  var $form = $(form),
@@ -167,13 +175,13 @@
167
  loadDatePicker: function() {
168
 
169
  // Only load if jQuery datepicker library exists
170
- if (typeof $.fn.flatpickr !== 'undefined') {
171
  $('.wpforms-datepicker').each(function() {
172
  var element = $(this),
173
  form = element.closest('.wpforms-form'),
174
  formID = form.data('formid');
175
 
176
- if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('datepicker') ) {
177
  properties = window['wpforms_'+formID].datepicker;
178
  } else if ( typeof wpforms_datepicker != "undefined") {
179
  properties = wpforms_datepicker;
@@ -193,13 +201,13 @@
193
  loadTimePicker: function() {
194
 
195
  // Only load if jQuery timepicker library exists
196
- if (typeof $.fn.timepicker !== 'undefined') {
197
  $('.wpforms-timepicker').each(function() {
198
  var element = $(this),
199
  form = element.closest('.wpforms-form'),
200
  formID = form.data('formid');
201
 
202
- if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('timepicker') ) {
203
  properties = window['wpforms_'+formID].timepicker;
204
  } else if ( typeof wpforms_timepicker != "undefined") {
205
  properties = wpforms_timepicker;
@@ -222,7 +230,7 @@
222
  loadInputMask: function() {
223
 
224
  // Only load if jQuery input mask library exists
225
- if (typeof $.fn.inputmask !== 'undefined') {
226
  $('.wpforms-masked-input').inputmask();
227
  };
228
  },
@@ -240,7 +248,7 @@
240
  })
241
 
242
  // Credit card valdation
243
- if(typeof $.fn.payment !== 'undefined') {
244
  $('.wpforms-field-credit-card-cardnumber').payment('formatCardNumber');
245
  $('.wpforms-field-credit-card-cardcvc').payment('formatCardCVC');
246
  };
@@ -273,7 +281,7 @@
273
  var $this = $(this),
274
  amount = $this.val();
275
  $this.val(amount.replace(/[^0-9.,]/g, ''));
276
- });
277
 
278
  // Payments: Sanitize/format user input amounts
279
  $(document).on('focusout', '.wpforms-payment-user-input', function(event) {
@@ -282,7 +290,7 @@
282
  sanitized = WPForms.amountSanitize(amount),
283
  formatted = WPForms.amountFormat(sanitized);
284
  $this.val(formatted);
285
- });
286
 
287
  // OptinMonster: initialize again after OM is finished.
288
  // This is to accomodate moving the form in the DOM.
@@ -308,13 +316,14 @@
308
  formID = $this.data('formid'),
309
  $form = $this.closest('.wpforms-form'),
310
  $page = $form.find('.wpforms-page-'+page),
311
- $submit = $form.find('.wpforms-submit-container');
312
- $indicator = $form.find('.wpforms-page-indicator');
 
313
 
314
  // Toggling between pages
315
  if ( action == 'next' ){
316
  // Validate
317
- if (typeof $.fn.validate !== 'undefined') {
318
  $page.find('input.wpforms-field-required, select.wpforms-field-required, textarea.wpforms-field-required, .wpforms-field-required input').each(function(index, el) {
319
  var field = $(el);
320
  if ( field.valid() ) {
@@ -339,6 +348,7 @@
339
  var $nextPage = $form.find('.wpforms-page-'+next);
340
  $nextPage.show();
341
  if ( $nextPage.hasClass('last') ) {
 
342
  $submit.show();
343
  }
344
  // Scroll to top of the form
@@ -351,6 +361,7 @@
351
  page2 = prev;
352
  $page.hide();
353
  $form.find('.wpforms-page-'+prev).show();
 
354
  $submit.hide();
355
  // Scroll to top of the form
356
  $('html, body').animate({
@@ -406,6 +417,7 @@
406
  currency = WPForms.getCurrency();
407
 
408
  $('.wpforms-payment-price').each(function(index, el) {
 
409
  var amount = 0,
410
  $this = $(this);
411
 
@@ -413,6 +425,8 @@
413
  amount = $this.val();
414
  } else if ($this.attr('type') === 'radio' && $this.is(':checked')) {
415
  amount = $this.data('amount');
 
 
416
  }
417
  if (!WPForms.empty(amount)) {
418
  amount = WPForms.amountSanitize(amount);
@@ -446,7 +460,7 @@
446
 
447
  var currency = WPForms.getCurrency();
448
 
449
- amount = amount.replace(/[^0-9.,]/g,'');
450
 
451
  if ( currency.decimal_sep == ',' && ( amount.indexOf(currency.decimal_sep) !== -1 ) ) {
452
  if ( currency.thousands_sep == '.' && amount.indexOf(currency.thousands_sep) !== -1 ) {;
@@ -459,7 +473,7 @@
459
  amount = amount.replace(currency.thousands_sep,'');
460
  }
461
 
462
- return WPForms.numberFormat( amount, 2, '.', '' );
463
  },
464
 
465
  /**
@@ -504,7 +518,7 @@
504
  thousands_sep: ',',
505
  decimal_sep: '.',
506
  symbol: '$',
507
- symbol_pos: 'left'
508
  }
509
 
510
  if ( 'undefined' !== wpforms_currency) {
@@ -523,7 +537,7 @@
523
  * @link http://locutus.io/php/number_format/
524
  * @since 1.2.6
525
  */
526
- numberFormat: function (number, decimals, decimalSep, thousandsSep) {
527
 
528
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
529
  var n = !isFinite(+number) ? 0 : +number
@@ -557,7 +571,7 @@
557
  * @since 1.2.6
558
  */
559
  empty: function(mixedVar) {
560
-
561
  var undef
562
  var key
563
  var i
55
  loadValidation: function() {
56
 
57
  // Only load if jQuery validation library exists
58
+ if (typeof $.fn.validate !== 'undefined') {
59
 
60
  // Payments: Validate method for Credit Card Number
61
+ if(typeof $.fn.payment !== 'undefined') {
62
  $.validator.addMethod( "creditcard", function(value, element) {
63
  //var type = $.payment.cardType(value);
64
  var valid = $.payment.validateCardNumber(value);
113
 
114
  // Validate 24-hour time
115
  $.validator.addMethod( "time24h", function( value, element ) {
116
+ return this.optional(element) || /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(\ ?[AP]M)?$/i.test(value);
117
  }, "Please enter time in 24-hour format (eg 22:45)" );
118
 
119
  // Finally load jQuery Validation library for our forms
121
  var form = $(this),
122
  formID = form.data('formid');
123
 
124
+ if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('validate')) {
125
  properties = window['wpforms_'+formID].validate;
126
  } else if ( typeof wpforms_validate != "undefined") {
127
  properties = wpforms_validate;
140
  error.insertAfter(element);
141
  }
142
  },
143
+ highlight: function(element, errorClass, validClass) {
144
+ $(element).addClass(errorClass).removeClass(validClass);
145
+ $(element).closest('.wpforms-field').addClass('wpforms-has-error');
146
+ },
147
+ unhighlight: function(element, errorClass, validClass) {
148
+ $(element).removeClass(errorClass).addClass(validClass);
149
+ $(element).closest('.wpforms-field').removeClass('wpforms-has-error');
150
+ },
151
  submitHandler: function(form) {
152
 
153
  var $form = $(form),
175
  loadDatePicker: function() {
176
 
177
  // Only load if jQuery datepicker library exists
178
+ if (typeof $.fn.flatpickr !== 'undefined') {
179
  $('.wpforms-datepicker').each(function() {
180
  var element = $(this),
181
  form = element.closest('.wpforms-form'),
182
  formID = form.data('formid');
183
 
184
+ if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('datepicker') ) {
185
  properties = window['wpforms_'+formID].datepicker;
186
  } else if ( typeof wpforms_datepicker != "undefined") {
187
  properties = wpforms_datepicker;
201
  loadTimePicker: function() {
202
 
203
  // Only load if jQuery timepicker library exists
204
+ if (typeof $.fn.timepicker !== 'undefined') {
205
  $('.wpforms-timepicker').each(function() {
206
  var element = $(this),
207
  form = element.closest('.wpforms-form'),
208
  formID = form.data('formid');
209
 
210
+ if (typeof window['wpforms_'+formID] != "undefined" && window['wpforms_'+formID].hasOwnProperty('timepicker') ) {
211
  properties = window['wpforms_'+formID].timepicker;
212
  } else if ( typeof wpforms_timepicker != "undefined") {
213
  properties = wpforms_timepicker;
230
  loadInputMask: function() {
231
 
232
  // Only load if jQuery input mask library exists
233
+ if (typeof $.fn.inputmask !== 'undefined') {
234
  $('.wpforms-masked-input').inputmask();
235
  };
236
  },
248
  })
249
 
250
  // Credit card valdation
251
+ if(typeof $.fn.payment !== 'undefined') {
252
  $('.wpforms-field-credit-card-cardnumber').payment('formatCardNumber');
253
  $('.wpforms-field-credit-card-cardcvc').payment('formatCardCVC');
254
  };
281
  var $this = $(this),
282
  amount = $this.val();
283
  $this.val(amount.replace(/[^0-9.,]/g, ''));
284
+ });
285
 
286
  // Payments: Sanitize/format user input amounts
287
  $(document).on('focusout', '.wpforms-payment-user-input', function(event) {
290
  sanitized = WPForms.amountSanitize(amount),
291
  formatted = WPForms.amountFormat(sanitized);
292
  $this.val(formatted);
293
+ });
294
 
295
  // OptinMonster: initialize again after OM is finished.
296
  // This is to accomodate moving the form in the DOM.
316
  formID = $this.data('formid'),
317
  $form = $this.closest('.wpforms-form'),
318
  $page = $form.find('.wpforms-page-'+page),
319
+ $submit = $form.find('.wpforms-submit-container'),
320
+ $indicator = $form.find('.wpforms-page-indicator'),
321
+ $reCAPTCHA = $form.find('.wpforms-recaptcha-container');
322
 
323
  // Toggling between pages
324
  if ( action == 'next' ){
325
  // Validate
326
+ if (typeof $.fn.validate !== 'undefined') {
327
  $page.find('input.wpforms-field-required, select.wpforms-field-required, textarea.wpforms-field-required, .wpforms-field-required input').each(function(index, el) {
328
  var field = $(el);
329
  if ( field.valid() ) {
348
  var $nextPage = $form.find('.wpforms-page-'+next);
349
  $nextPage.show();
350
  if ( $nextPage.hasClass('last') ) {
351
+ $reCAPTCHA.show();
352
  $submit.show();
353
  }
354
  // Scroll to top of the form
361
  page2 = prev;
362
  $page.hide();
363
  $form.find('.wpforms-page-'+prev).show();
364
+ $reCAPTCHA.hide();
365
  $submit.hide();
366
  // Scroll to top of the form
367
  $('html, body').animate({
417
  currency = WPForms.getCurrency();
418
 
419
  $('.wpforms-payment-price').each(function(index, el) {
420
+
421
  var amount = 0,
422
  $this = $(this);
423
 
425
  amount = $this.val();
426
  } else if ($this.attr('type') === 'radio' && $this.is(':checked')) {
427
  amount = $this.data('amount');
428
+ } else if ($this.is('select') && $this.find('option:selected').length > 0) {
429
+ amount = $this.find('option:selected').data('amount');
430
  }
431
  if (!WPForms.empty(amount)) {
432
  amount = WPForms.amountSanitize(amount);
460
 
461
  var currency = WPForms.getCurrency();
462
 
463
+ amount = amount.toString().replace(/[^0-9.,]/g,'');
464
 
465
  if ( currency.decimal_sep == ',' && ( amount.indexOf(currency.decimal_sep) !== -1 ) ) {
466
  if ( currency.thousands_sep == '.' && amount.indexOf(currency.thousands_sep) !== -1 ) {;
473
  amount = amount.replace(currency.thousands_sep,'');
474
  }
475
 
476
+ return WPForms.numberFormat( amount, 2, '.', '' );
477
  },
478
 
479
  /**
518
  thousands_sep: ',',
519
  decimal_sep: '.',
520
  symbol: '$',
521
+ symbol_pos: 'left'
522
  }
523
 
524
  if ( 'undefined' !== wpforms_currency) {
537
  * @link http://locutus.io/php/number_format/
538
  * @since 1.2.6
539
  */
540
+ numberFormat: function (number, decimals, decimalSep, thousandsSep) {
541
 
542
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
543
  var n = !isFinite(+number) ? 0 : +number
571
  * @since 1.2.6
572
  */
573
  empty: function(mixedVar) {
574
+
575
  var undef
576
  var key
577
  var i
includes/admin/builder/panels/class-settings.php CHANGED
@@ -165,93 +165,6 @@ class WPForms_Builder_Panel_Settings extends WPForms_Builder_Panel {
165
  // Notifications
166
  //--------------------------------------------------------------------//
167
  echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-notifications">';
168
- // echo '<div class="wpforms-panel-content-section-title">';
169
- // _e( 'Notifications', 'wpforms' );
170
- // echo '</div>';
171
- // wpforms_panel_field(
172
- // 'select',
173
- // 'settings',
174
- // 'notification_enable',
175
- // $this->form_data,
176
- // __( 'Notifications', 'wpforms' ),
177
- // array(
178
- // 'default' => '1',
179
- // 'options' => array(
180
- // '1' => __( 'On', 'wpforms' ),
181
- // '0' => __( 'Off', 'wpforms' ),
182
- // ),
183
- // )
184
- // );
185
- // wpforms_panel_field(
186
- // 'text',
187
- // 'settings',
188
- // 'notification_email',
189
- // $this->form_data,
190
- // __( 'Send To Email Address', 'wpforms' ),
191
- // array(
192
- // 'default' => '{admin_email}',
193
- // 'tooltip' => __( 'Enter the email address to receive form entry notifications. For multiple notifications, separate email addresses with a comma.', 'wpforms' ),
194
- // 'smarttags' => array(
195
- // 'type' => 'fields',
196
- // 'fields' => 'name,email,text',
197
- // ),
198
- // )
199
- // );
200
- // wpforms_panel_field(
201
- // 'text',
202
- // 'settings',
203
- // 'notification_subject',
204
- // $this->form_data,
205
- // __( 'Email Subject', 'wpforms' ),
206
- // array(
207
- // 'default' => __( 'New Entry: ' , 'wpforms' ) . $this->form->post_title,
208
- // 'smarttags' => array(
209
- // 'type' => 'fields',
210
- // 'fields' => 'name,email,text',
211
- // ),
212
- // )
213
- // );
214
- // wpforms_panel_field(
215
- // 'text',
216
- // 'settings',
217
- // 'notification_fromname',
218
- // $this->form_data,
219
- // __( 'From Name', 'wpforms' ),
220
- // array(
221
- // 'default' => sanitize_text_field( get_option( 'blogname' ) ),
222
- // 'smarttags' => array(
223
- // 'type' => 'fields',
224
- // 'fields' => 'name,email,text',
225
- // ),
226
- // )
227
- // );
228
- // wpforms_panel_field(
229
- // 'text',
230
- // 'settings',
231
- // 'notification_fromaddress',
232
- // $this->form_data,
233
- // __( 'From Email', 'wpforms' ),
234
- // array(
235
- // 'default' => '{admin_email}',
236
- // 'smarttags' => array(
237
- // 'type' => 'fields',
238
- // 'fields' => 'name,email,text',
239
- // ),
240
- // )
241
- // );
242
- // wpforms_panel_field(
243
- // 'text',
244
- // 'settings',
245
- // 'notification_replyto',
246
- // $this->form_data,
247
- // __( 'Reply-To', 'wpforms' ),
248
- // array(
249
- // 'smarttags' => array(
250
- // 'type' => 'fields',
251
- // 'fields' => 'name,email,text',
252
- // ),
253
- // )
254
- // );
255
  do_action( 'wpforms_form_settings_notifications', $this );
256
  echo '</div>';
257
 
@@ -283,7 +196,7 @@ class WPForms_Builder_Panel_Settings extends WPForms_Builder_Panel {
283
  'confirmation_message',
284
  $this->form_data,
285
  __( 'Confirmation Message', 'wpforms' ),
286
- array(
287
  'default' => __( 'Thanks for contacting us! We will be in touch with you shortly.', 'wpforms' ),
288
  'tinymce' => array(
289
  'editor_height' => '200'
165
  // Notifications
166
  //--------------------------------------------------------------------//
167
  echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-notifications">';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  do_action( 'wpforms_form_settings_notifications', $this );
169
  echo '</div>';
170
 
196
  'confirmation_message',
197
  $this->form_data,
198
  __( 'Confirmation Message', 'wpforms' ),
199
+ array(
200
  'default' => __( 'Thanks for contacting us! We will be in touch with you shortly.', 'wpforms' ),
201
  'tinymce' => array(
202
  'editor_height' => '200'
includes/admin/class-menu.php CHANGED
@@ -36,7 +36,7 @@ class WPForms_Admin_Menu {
36
 
37
  // Default Forms top level menu item
38
  add_menu_page(
39
- __( 'WPForms', 'wpforms' ),
40
  __( 'WPForms', 'wpforms' ),
41
  $menu_cap,
42
  'wpforms-overview',
@@ -110,9 +110,9 @@ class WPForms_Admin_Menu {
110
  */
111
  public function menu_icon() {
112
 
113
- wp_enqueue_style(
114
  'wpforms-menu',
115
- WPFORMS_PLUGIN_URL . 'assets/css/admin-menu.css',
116
  null,
117
  WPFORMS_VERSION
118
  );
@@ -131,7 +131,7 @@ class WPForms_Admin_Menu {
131
  global $current_screen;
132
  if ( !empty( $current_screen->id ) && strpos( $current_screen->id, 'wpforms' ) !== false ) {
133
  $url = 'http://wordpress.org/support/view/plugin-reviews/wpforms-lite?filter=5';
134
- $text = sprintf( __( 'Please rate <strong>WPForms</strong> <a href="%s" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from the WPForms team!', 'wpforms' ), $url, $url );
135
  }
136
  return $text;
137
  }
36
 
37
  // Default Forms top level menu item
38
  add_menu_page(
39
+ __( 'WPForms', 'wpforms' ),
40
  __( 'WPForms', 'wpforms' ),
41
  $menu_cap,
42
  'wpforms-overview',
110
  */
111
  public function menu_icon() {
112
 
113
+ wp_enqueue_style(
114
  'wpforms-menu',
115
+ WPFORMS_PLUGIN_URL . 'assets/css/admin-menu.css',
116
  null,
117
  WPFORMS_VERSION
118
  );
131
  global $current_screen;
132
  if ( !empty( $current_screen->id ) && strpos( $current_screen->id, 'wpforms' ) !== false ) {
133
  $url = 'http://wordpress.org/support/view/plugin-reviews/wpforms-lite?filter=5';
134
+ $text = sprintf( __( 'Please rate <strong>WPForms</strong> <a href="%s" target="_blank" rel="noopener">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from the WPForms team!', 'wpforms' ), $url, $url );
135
  }
136
  return $text;
137
  }
includes/admin/class-welcome.php CHANGED
@@ -77,7 +77,7 @@ class WPForms_Welcome {
77
  * @since 1.0.0
78
  */
79
  public function welcome_head() {
80
-
81
  $selected = isset( $_GET['page'] ) ? $_GET['page'] : 'wpforms-getting-started';
82
  ?>
83
  <h1><?php _e( 'Welcome to WPForms', 'wpforms' ); ?></h1>
@@ -108,17 +108,17 @@ class WPForms_Welcome {
108
 
109
  ?>
110
  <div class="wrap about-wrap">
111
-
112
  <?php $this->welcome_head(); ?>
113
-
114
  <p class="about-description">
115
  <?php _e( 'Use the tips below to get started using WPForms. You will be up and running in no time.', 'wpforms' ); ?>
116
  </p>
117
 
118
- <div class="feature-section two-col">
119
  <div class="col">
120
  <h3><?php _e( 'Creating Your First Form' , 'wpforms' ); ?></h3>
121
- <p><?php printf( __( 'WPForms make it easy to create forms in WordPress. You can follow the video tutorial on the right or read our how to <a href="%s" target="_blank">create your first form guide</a>.', 'wpforms' ), ' https://wpforms.com/docs/creating-first-form/ ' ); ?>
122
  <p><?php printf( __( 'But in reality, the process is so intuitive that you can just start by going to <a href="%s">WPForms - > Add New</a>.', 'wpforms' ), admin_url( 'admin.php?page=wpforms-builder' ) ); ?>
123
  </div>
124
  <div class="col">
@@ -128,17 +128,17 @@ class WPForms_Welcome {
128
  </div>
129
  </div>
130
 
131
- <div class="feature-section two-col">
132
  <div class="col">
133
  <h3><?php _e( 'See all WPForms Features', 'wpforms' ); ?></h3>
134
  <p><?php _e( 'WPForms is both easy to use and extremely powerful. We have tons of helpful features that allows us to give you everything you need from a form builder.', 'wpforms' ); ?></p>
135
- <p><a href="https://wpforms.com/features/" target="_blank" class="wpforms-features-button button button-primary"><?php _e( 'See all Features', 'wpforms' ); ?></a></p>
136
  </div>
137
  <div class="col">
138
  <img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-features.png">
139
  </div>
140
  </div>
141
-
142
  </div>
143
  <script type="text/javascript">
144
  jQuery(function($){
@@ -205,17 +205,17 @@ class WPForms_Welcome {
205
  if ( !isset( $_GET['page'] ) || 'wpforms-getting-started' != $_GET['page'] )
206
  return;
207
 
208
- wp_enqueue_style(
209
- 'wpforms-welcome',
210
- WPFORMS_PLUGIN_URL . 'assets/css/admin-welcome.css',
211
- null,
212
  WPFORMS_VERSION
213
  );
214
 
215
- wp_enqueue_script(
216
- 'fitvids',
217
- WPFORMS_PLUGIN_URL . 'assets/js/jquery.fitvids.js',
218
- array( 'jquery' ),
219
  '1.1.0',
220
  false
221
  );
77
  * @since 1.0.0
78
  */
79
  public function welcome_head() {
80
+
81
  $selected = isset( $_GET['page'] ) ? $_GET['page'] : 'wpforms-getting-started';
82
  ?>
83
  <h1><?php _e( 'Welcome to WPForms', 'wpforms' ); ?></h1>
108
 
109
  ?>
110
  <div class="wrap about-wrap">
111
+
112
  <?php $this->welcome_head(); ?>
113
+
114
  <p class="about-description">
115
  <?php _e( 'Use the tips below to get started using WPForms. You will be up and running in no time.', 'wpforms' ); ?>
116
  </p>
117
 
118
+ <div class="feature-section two-col">
119
  <div class="col">
120
  <h3><?php _e( 'Creating Your First Form' , 'wpforms' ); ?></h3>
121
+ <p><?php printf( __( 'WPForms make it easy to create forms in WordPress. You can follow the video tutorial on the right or read our how to <a href="%s" target="_blank" rel="noopener">create your first form guide</a>.', 'wpforms' ), ' https://wpforms.com/docs/creating-first-form/ ' ); ?>
122
  <p><?php printf( __( 'But in reality, the process is so intuitive that you can just start by going to <a href="%s">WPForms - > Add New</a>.', 'wpforms' ), admin_url( 'admin.php?page=wpforms-builder' ) ); ?>
123
  </div>
124
  <div class="col">
128
  </div>
129
  </div>
130
 
131
+ <div class="feature-section two-col">
132
  <div class="col">
133
  <h3><?php _e( 'See all WPForms Features', 'wpforms' ); ?></h3>
134
  <p><?php _e( 'WPForms is both easy to use and extremely powerful. We have tons of helpful features that allows us to give you everything you need from a form builder.', 'wpforms' ); ?></p>
135
+ <p><a href="https://wpforms.com/features/" target="_blank" rel="noopener" class="wpforms-features-button button button-primary"><?php _e( 'See all Features', 'wpforms' ); ?></a></p>
136
  </div>
137
  <div class="col">
138
  <img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-features.png">
139
  </div>
140
  </div>
141
+
142
  </div>
143
  <script type="text/javascript">
144
  jQuery(function($){
205
  if ( !isset( $_GET['page'] ) || 'wpforms-getting-started' != $_GET['page'] )
206
  return;
207
 
208
+ wp_enqueue_style(
209
+ 'wpforms-welcome',
210
+ WPFORMS_PLUGIN_URL . 'assets/css/admin-welcome.css',
211
+ null,
212
  WPFORMS_VERSION
213
  );
214
 
215
+ wp_enqueue_script(
216
+ 'fitvids',
217
+ WPFORMS_PLUGIN_URL . 'assets/js/jquery.fitvids.js',
218
+ array( 'jquery' ),
219
  '1.1.0',
220
  false
221
  );
includes/admin/overview/class-overview-table.php CHANGED
@@ -78,39 +78,39 @@ class WPForms_Overview_Table extends WP_List_Table {
78
  * Renders the columns.
79
  *
80
  * @since 1.0.0
81
- * @param array $form
82
  * @param string $column_name
83
  * @return string
84
  */
85
  public function column_default( $form, $column_name ) {
86
 
87
- switch( $column_name ) {
88
 
89
  case 'id':
90
  $value = $form->ID;
91
  break;
92
-
93
  case 'shortcode':
94
  $value = '[wpforms id="' . $form->ID . '"]';
95
  break;
96
-
97
  case 'created':
98
  $value = get_the_date( get_option( 'date_format' ), $form );
99
  break;
100
-
101
  case 'modified':
102
  $value = get_post_modified_time( get_option( 'date_format' ), false, $form );
103
  break;
104
-
105
  case 'author':
106
  $author = get_userdata( $form->post_author );
107
  $value = $author->display_name;
108
  break;
109
-
110
  case 'php':
111
  $value = '<code style="display:block;font-size:11px;">if( function_exists( \'wpforms_get\' ) ){ wpforms_get( ' . $form->ID . ' ); }</code>';
112
  break;
113
-
114
  default:
115
  $value = '';
116
  }
@@ -131,10 +131,10 @@ class WPForms_Overview_Table extends WP_List_Table {
131
  $name = ! empty( $form->post_title ) ? $form->post_title : $form->post_name;
132
  $name = sprintf( '<a class="row-title" href="%s" title="%s"><strong>%s</strong></a>',
133
  add_query_arg( array( 'view' => 'fields', 'form_id' => $form->ID ), admin_url( 'admin.php?page=wpforms-builder' ) ),
134
- __( 'Edit this form', 'wpforms' ),
135
  $name
136
  );
137
-
138
  // Build all of the row action links.
139
  $row_actions = array();
140
 
@@ -142,7 +142,7 @@ class WPForms_Overview_Table extends WP_List_Table {
142
  $row_actions['edit'] = sprintf( '<a href="%s" title="%s">%s</a>',
143
  add_query_arg( array( 'view' => 'fields', 'form_id' => $form->ID ), admin_url( 'admin.php?page=wpforms-builder' ) ),
144
  __( 'Edit this form', 'wpforms' ),
145
- __( 'Edit', 'wpforms' )
146
  );
147
 
148
  // Entries
@@ -153,7 +153,7 @@ class WPForms_Overview_Table extends WP_List_Table {
153
  );
154
 
155
  // Preview
156
- $row_actions['preview_'] = sprintf( '<a href="%s" title="%s" target="_blank">%s</a>',
157
  esc_url( wpforms()->preview->form_preview_url( $form->ID ) ),
158
  __( 'View preview', 'wpforms' ),
159
  __( 'Preview', 'wpforms' )
@@ -175,13 +175,13 @@ class WPForms_Overview_Table extends WP_List_Table {
175
 
176
  // Build the row action links and return the value.
177
  $value = $name . $this->row_actions( $row_actions );
178
-
179
  return apply_filters( 'wpforms_overview_row_actions', $value, $form );
180
  }
181
 
182
  /**
183
  * Define bulk actions available for our table listing
184
- *
185
  * @since 1.0.0
186
  * @return array
187
  */
@@ -213,7 +213,7 @@ class WPForms_Overview_Table extends WP_List_Table {
213
  return;
214
  }
215
 
216
- // Delete one or multiple forms - both delete links and bulk actions
217
  if ( 'delete' === $this->current_action() ) {
218
 
219
  if ( wp_verify_nonce( $_GET['_wpnonce'], 'bulk-forms' ) || wp_verify_nonce( $_GET['_wpnonce'], 'wpforms_delete_form_nonce' ) ) {
@@ -267,9 +267,9 @@ class WPForms_Overview_Table extends WP_List_Table {
267
  $hidden = array();
268
 
269
  // Define which columns can be sorted - form name, date
270
- $sortable = array(
271
- 'form_name' => array( 'title', false ),
272
- 'created' => array( 'date', false )
273
  );
274
 
275
  // Set column headers
@@ -281,8 +281,8 @@ class WPForms_Overview_Table extends WP_List_Table {
281
  $order = isset( $_GET['order'] ) ? $_GET['order'] : 'DESC';
282
  $orderby = isset( $_GET['orderby'] ) ? $_GET['orderby'] : 'ID';
283
  $per_page = $this->get_items_per_page( 'wpforms_forms_per_page', $this->per_page );
284
- $data = wpforms()->form->get( '', array(
285
- 'orderby' => $orderby,
286
  'order' => $order,
287
  'nopaging' => false,
288
  'posts_per_page' => $per_page,
@@ -294,7 +294,7 @@ class WPForms_Overview_Table extends WP_List_Table {
294
  $this->items = $data;
295
 
296
  // Finalize pagination
297
- $this->set_pagination_args(
298
  array(
299
  'total_items' => $total,
300
  'per_page' => $per_page,
78
  * Renders the columns.
79
  *
80
  * @since 1.0.0
81
+ * @param array $form
82
  * @param string $column_name
83
  * @return string
84
  */
85
  public function column_default( $form, $column_name ) {
86
 
87
+ switch( $column_name ) {
88
 
89
  case 'id':
90
  $value = $form->ID;
91
  break;
92
+
93
  case 'shortcode':
94
  $value = '[wpforms id="' . $form->ID . '"]';
95
  break;
96
+
97
  case 'created':
98
  $value = get_the_date( get_option( 'date_format' ), $form );
99
  break;
100
+
101
  case 'modified':
102
  $value = get_post_modified_time( get_option( 'date_format' ), false, $form );
103
  break;
104
+
105
  case 'author':
106
  $author = get_userdata( $form->post_author );
107
  $value = $author->display_name;
108
  break;
109
+
110
  case 'php':
111
  $value = '<code style="display:block;font-size:11px;">if( function_exists( \'wpforms_get\' ) ){ wpforms_get( ' . $form->ID . ' ); }</code>';
112
  break;
113
+
114
  default:
115
  $value = '';
116
  }
131
  $name = ! empty( $form->post_title ) ? $form->post_title : $form->post_name;
132
  $name = sprintf( '<a class="row-title" href="%s" title="%s"><strong>%s</strong></a>',
133
  add_query_arg( array( 'view' => 'fields', 'form_id' => $form->ID ), admin_url( 'admin.php?page=wpforms-builder' ) ),
134
+ __( 'Edit this form', 'wpforms' ),
135
  $name
136
  );
137
+
138
  // Build all of the row action links.
139
  $row_actions = array();
140
 
142
  $row_actions['edit'] = sprintf( '<a href="%s" title="%s">%s</a>',
143
  add_query_arg( array( 'view' => 'fields', 'form_id' => $form->ID ), admin_url( 'admin.php?page=wpforms-builder' ) ),
144
  __( 'Edit this form', 'wpforms' ),
145
+ __( 'Edit', 'wpforms' )
146
  );
147
 
148
  // Entries
153
  );
154
 
155
  // Preview
156
+ $row_actions['preview_'] = sprintf( '<a href="%s" title="%s" target="_blank" rel="noopener">%s</a>',
157
  esc_url( wpforms()->preview->form_preview_url( $form->ID ) ),
158
  __( 'View preview', 'wpforms' ),
159
  __( 'Preview', 'wpforms' )
175
 
176
  // Build the row action links and return the value.
177
  $value = $name . $this->row_actions( $row_actions );
178
+
179
  return apply_filters( 'wpforms_overview_row_actions', $value, $form );
180
  }
181
 
182
  /**
183
  * Define bulk actions available for our table listing
184
+ *
185
  * @since 1.0.0
186
  * @return array
187
  */
213
  return;
214
  }
215
 
216
+ // Delete one or multiple forms - both delete links and bulk actions
217
  if ( 'delete' === $this->current_action() ) {
218
 
219
  if ( wp_verify_nonce( $_GET['_wpnonce'], 'bulk-forms' ) || wp_verify_nonce( $_GET['_wpnonce'], 'wpforms_delete_form_nonce' ) ) {
267
  $hidden = array();
268
 
269
  // Define which columns can be sorted - form name, date
270
+ $sortable = array(
271
+ 'form_name' => array( 'title', false ),
272
+ 'created' => array( 'date', false )
273
  );
274
 
275
  // Set column headers
281
  $order = isset( $_GET['order'] ) ? $_GET['order'] : 'DESC';
282
  $orderby = isset( $_GET['orderby'] ) ? $_GET['orderby'] : 'ID';
283
  $per_page = $this->get_items_per_page( 'wpforms_forms_per_page', $this->per_page );
284
+ $data = wpforms()->form->get( '', array(
285
+ 'orderby' => $orderby,
286
  'order' => $order,
287
  'nopaging' => false,
288
  'posts_per_page' => $per_page,
294
  $this->items = $data;
295
 
296
  // Finalize pagination
297
+ $this->set_pagination_args(
298
  array(
299
  'total_items' => $total,
300
  'per_page' => $per_page,
includes/class-fields.php CHANGED
@@ -62,6 +62,7 @@ class WPForms_Fields {
62
  'file-upload',
63
  'payment-single',
64
  'payment-multiple',
 
65
  'payment-credit-card',
66
  'payment-total',
67
  ) );
62
  'file-upload',
63
  'payment-single',
64
  'payment-multiple',
65
+ 'payment-dropdown',
66
  'payment-credit-card',
67
  'payment-total',
68
  ) );
includes/class-frontend.php CHANGED
@@ -70,8 +70,8 @@ class WPForms_Frontend {
70
  $class[] = wpforms_setting( 'disable-css', '1' ) == '1' ? 'wpforms-container-full' : '';
71
  $errors = empty( wpforms()->process->errors[$form->ID] ) ? array() : wpforms()->process->errors[$form->ID];
72
  $success = false;
73
- $title = $title == 'false' ? false : $title;
74
- $description = $description == 'false' ? false : $description;
75
 
76
  // If the form does not contain any fields do not proceed
77
  if ( empty( $form_data['fields'] ) ) {
@@ -109,12 +109,12 @@ class WPForms_Frontend {
109
  // Prep the form action URL, allow filter
110
  if ( !empty( $settings['confirmation_type'] ) && 'message' == $settings['confirmation_type'] && !empty( $settings['confirmation_message_scroll'] ) ) {
111
  $action .= '#wpforms-' . $form_id;
112
- }
113
  $action = apply_filters( 'wpforms_frontend_form_action', $action, $form_data, $form );
114
 
115
  // Allow form container classes to be filtered
116
  $class = array_map( 'sanitize_html_class', apply_filters( 'wpforms_frontend_container_class', $class, $form_data ) );
117
-
118
  if ( !empty( $form_data['settings']['form_class'] ) ) {
119
  $class = array_merge( $class, array_map('sanitize_html_class', explode( ' ', $form_data['settings']['form_class'] ) ) );
120
  }
@@ -200,7 +200,7 @@ class WPForms_Frontend {
200
  if ( !empty( $errors['header'] ) ) {
201
 
202
  echo '<div class="wpforms-error-container">';
203
-
204
  $allow = array(
205
  'a' => array(
206
  'href' => array(),
@@ -250,7 +250,7 @@ class WPForms_Frontend {
250
  $pagebreak['indicator'],
251
  $pagebreak['color']
252
  );
253
-
254
  if ( 'circles' == $pagebreak['indicator'] ) {
255
 
256
  // Circles theme
@@ -293,7 +293,7 @@ class WPForms_Frontend {
293
  $names = '';
294
  $step = __( 'Step', 'wpforms' );
295
  $of = __( 'of', 'wpforms' );
296
-
297
  foreach ( $pagebreak['pages'] as $page ) {
298
  if ( !empty( $page['title'] ) ) {
299
  $names .= sprintf( 'data-page-%d-title="%s" ', $p, esc_attr( $page['title'] ) );
@@ -301,13 +301,13 @@ class WPForms_Frontend {
301
  $p++;
302
  }
303
  printf( '<span class="wpforms-page-indicator-page-title" %s>%s</span>', $names, $p1 );
304
- printf( '<span class="wpforms-page-indicator-page-title-sep" %s> - </span>', $sep );
305
  printf( '<span class="wpforms-page-indicator-steps">%s <span class="wpforms-page-indicator-steps-current">1</span> %s %d</span>', $step, $of, count( $pagebreak['pages'] ) );
306
  printf( '<div class="wpforms-page-indicator-page-progress-wrap"><div class="wpforms-page-indicator-page-progress" %s></div></div>', $prog );
307
  }
308
 
309
  do_action( 'wpforms_frontend_indicator', $pagebreak, $form_data );
310
-
311
  echo '</div>';
312
  }
313
 
@@ -552,10 +552,16 @@ class WPForms_Frontend {
552
  if ( !isset( $form_data['settings']['recaptcha'] ) || '1' != $form_data['settings']['recaptcha'] )
553
  return;
554
 
555
- $d = '';
 
556
  $datas = apply_filters( 'wpforms_frontend_recaptcha', array( 'sitekey' => $site_key ), $form_data );
557
 
558
- echo '<div class="wpforms-recaptcha-container">';
 
 
 
 
 
559
 
560
  foreach( $datas as $key => $data ) {
561
  $d .= 'data-' . $key . '="' . esc_attr( $data ) . '" ';
@@ -625,7 +631,7 @@ class WPForms_Frontend {
625
 
626
  echo '<input type="hidden" name="wpforms[id]" value="' . $form->ID . '">';
627
 
628
- printf(
629
  '<button type="submit" name="wpforms[submit]" class="wpforms-submit %s" id="wpforms-submit-%d" value="wpforms-submit" %s>%s</button>',
630
  implode( ' ', $submit_classes ),
631
  $form->ID,
@@ -704,7 +710,7 @@ class WPForms_Frontend {
704
  array(),
705
  WPFORMS_VERSION
706
  );
707
- }
708
  if ( wpforms_setting( 'disable-css', '1' ) == '2' ) {
709
  wp_enqueue_style(
710
  'wpforms-base',
@@ -783,12 +789,12 @@ class WPForms_Frontend {
783
  );
784
 
785
  // If we have payment fields then include currency details
786
- $payment_fields = array( 'credit-card', 'payment-single', 'payment-multiple', 'payment-total' );
787
  if ( ( $this->assets_global() || true == wpforms_has_field_type( $payment_fields , $this->forms, true ) ) && function_exists( 'wpforms_get_currencies' ) ) :
788
  $currency = wpforms_setting( 'currency', 'USD' );
789
  $currencies = wpforms_get_currencies();
790
- wp_localize_script(
791
- 'wpforms',
792
  'wpforms_currency',
793
  array(
794
  'code' => $currency,
@@ -796,7 +802,7 @@ class WPForms_Frontend {
796
  'decimal' => $currencies[$currency]['decimal_separator'],
797
  'symbol' => $currencies[$currency]['symbol'],
798
  'symbol_pos' => $currencies[$currency]['symbol_pos']
799
- )
800
  );
801
  endif;
802
 
70
  $class[] = wpforms_setting( 'disable-css', '1' ) == '1' ? 'wpforms-container-full' : '';
71
  $errors = empty( wpforms()->process->errors[$form->ID] ) ? array() : wpforms()->process->errors[$form->ID];
72
  $success = false;
73
+ $title = filter_var( $title, FILTER_VALIDATE_BOOLEAN );
74
+ $description = filter_var( $description, FILTER_VALIDATE_BOOLEAN );
75
 
76
  // If the form does not contain any fields do not proceed
77
  if ( empty( $form_data['fields'] ) ) {
109
  // Prep the form action URL, allow filter
110
  if ( !empty( $settings['confirmation_type'] ) && 'message' == $settings['confirmation_type'] && !empty( $settings['confirmation_message_scroll'] ) ) {
111
  $action .= '#wpforms-' . $form_id;
112
+ }
113
  $action = apply_filters( 'wpforms_frontend_form_action', $action, $form_data, $form );
114
 
115
  // Allow form container classes to be filtered
116
  $class = array_map( 'sanitize_html_class', apply_filters( 'wpforms_frontend_container_class', $class, $form_data ) );
117
+
118
  if ( !empty( $form_data['settings']['form_class'] ) ) {
119
  $class = array_merge( $class, array_map('sanitize_html_class', explode( ' ', $form_data['settings']['form_class'] ) ) );
120
  }
200
  if ( !empty( $errors['header'] ) ) {
201
 
202
  echo '<div class="wpforms-error-container">';
203
+
204
  $allow = array(
205
  'a' => array(
206
  'href' => array(),
250
  $pagebreak['indicator'],
251
  $pagebreak['color']
252
  );
253
+
254
  if ( 'circles' == $pagebreak['indicator'] ) {
255
 
256
  // Circles theme
293
  $names = '';
294
  $step = __( 'Step', 'wpforms' );
295
  $of = __( 'of', 'wpforms' );
296
+
297
  foreach ( $pagebreak['pages'] as $page ) {
298
  if ( !empty( $page['title'] ) ) {
299
  $names .= sprintf( 'data-page-%d-title="%s" ', $p, esc_attr( $page['title'] ) );
301
  $p++;
302
  }
303
  printf( '<span class="wpforms-page-indicator-page-title" %s>%s</span>', $names, $p1 );
304
+ printf( '<span class="wpforms-page-indicator-page-title-sep" %s> - </span>', $sep );
305
  printf( '<span class="wpforms-page-indicator-steps">%s <span class="wpforms-page-indicator-steps-current">1</span> %s %d</span>', $step, $of, count( $pagebreak['pages'] ) );
306
  printf( '<div class="wpforms-page-indicator-page-progress-wrap"><div class="wpforms-page-indicator-page-progress" %s></div></div>', $prog );
307
  }
308
 
309
  do_action( 'wpforms_frontend_indicator', $pagebreak, $form_data );
310
+
311
  echo '</div>';
312
  }
313
 
552
  if ( !isset( $form_data['settings']['recaptcha'] ) || '1' != $form_data['settings']['recaptcha'] )
553
  return;
554
 
555
+ $pages = wpforms_has_pagebreak( $form_data );
556
+ $d = '';
557
  $datas = apply_filters( 'wpforms_frontend_recaptcha', array( 'sitekey' => $site_key ), $form_data );
558
 
559
+
560
+ if ( $pages ) {
561
+ echo '<div class="wpforms-recaptcha-container" style="display:none;">';
562
+ } else {
563
+ echo '<div class="wpforms-recaptcha-container">';
564
+ }
565
 
566
  foreach( $datas as $key => $data ) {
567
  $d .= 'data-' . $key . '="' . esc_attr( $data ) . '" ';
631
 
632
  echo '<input type="hidden" name="wpforms[id]" value="' . $form->ID . '">';
633
 
634
+ printf(
635
  '<button type="submit" name="wpforms[submit]" class="wpforms-submit %s" id="wpforms-submit-%d" value="wpforms-submit" %s>%s</button>',
636
  implode( ' ', $submit_classes ),
637
  $form->ID,
710
  array(),
711
  WPFORMS_VERSION
712
  );
713
+ }
714
  if ( wpforms_setting( 'disable-css', '1' ) == '2' ) {
715
  wp_enqueue_style(
716
  'wpforms-base',
789
  );
790
 
791
  // If we have payment fields then include currency details
792
+ $payment_fields = array( 'credit-card', 'payment-single', 'payment-multiple', 'payment-select', 'payment-total' );
793
  if ( ( $this->assets_global() || true == wpforms_has_field_type( $payment_fields , $this->forms, true ) ) && function_exists( 'wpforms_get_currencies' ) ) :
794
  $currency = wpforms_setting( 'currency', 'USD' );
795
  $currencies = wpforms_get_currencies();
796
+ wp_localize_script(
797
+ 'wpforms',
798
  'wpforms_currency',
799
  array(
800
  'code' => $currency,
802
  'decimal' => $currencies[$currency]['decimal_separator'],
803
  'symbol' => $currencies[$currency]['symbol'],
804
  'symbol_pos' => $currencies[$currency]['symbol_pos']
805
+ )
806
  );
807
  endif;
808
 
includes/class-preview.php CHANGED
@@ -69,7 +69,7 @@ class WPForms_Preview {
69
 
70
  // Get form details
71
  $form_data = wpforms()->form->get( $entry->form_id, array( 'content_only' => true ) );
72
-
73
  // Double check that we found a valid entry
74
  if ( ! $form_data || empty( $form_data ) ) {
75
  return;
@@ -113,9 +113,9 @@ class WPForms_Preview {
113
  // Display the fields and their values
114
  foreach ( $fields as $key => $field ) {
115
 
116
- $field_value = apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data );
117
  $field_class = sanitize_html_class( 'wpforms-field-' . $field['type'] );
118
- $field_class .= empty( $field_value ) ? ' empty' : '';
119
 
120
  echo '<div class="wpforms-entry-field ' . $field_class . '">';
121
 
@@ -151,7 +151,7 @@ class WPForms_Preview {
151
 
152
  if ( !is_admin() )
153
  return;
154
-
155
  // Verify page exits
156
  $preview = get_option( 'wpforms_preview_page' );
157
 
@@ -268,7 +268,7 @@ class WPForms_Preview {
268
 
269
  return $posts;
270
  }
271
-
272
  /**
273
  * Hide the preview page from admin
274
  *
@@ -276,7 +276,7 @@ class WPForms_Preview {
276
  * @param object $query
277
  */
278
  function form_preview_hide( $query ) {
279
-
280
  if( $query->is_main_query() && is_admin() && isset( $query->query_vars['post_type'] ) && 'page' == $query->query_vars['post_type'] ) {
281
  $wpforms_preview = intval( get_option( 'wpforms_preview_page' ) );
282
  if( $wpforms_preview ) {
@@ -285,5 +285,5 @@ class WPForms_Preview {
285
  $query->set( 'post__not_in', $exclude );
286
  }
287
  }
288
- }
289
  }
69
 
70
  // Get form details
71
  $form_data = wpforms()->form->get( $entry->form_id, array( 'content_only' => true ) );
72
+
73
  // Double check that we found a valid entry
74
  if ( ! $form_data || empty( $form_data ) ) {
75
  return;
113
  // Display the fields and their values
114
  foreach ( $fields as $key => $field ) {
115
 
116
+ $field_value = apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data, 'entry-single' );
117
  $field_class = sanitize_html_class( 'wpforms-field-' . $field['type'] );
118
+ $field_class .= empty( $field_value ) ? ' empty' : '';
119
 
120
  echo '<div class="wpforms-entry-field ' . $field_class . '">';
121
 
151
 
152
  if ( !is_admin() )
153
  return;
154
+
155
  // Verify page exits
156
  $preview = get_option( 'wpforms_preview_page' );
157
 
268
 
269
  return $posts;
270
  }
271
+
272
  /**
273
  * Hide the preview page from admin
274
  *
276
  * @param object $query
277
  */
278
  function form_preview_hide( $query ) {
279
+
280
  if( $query->is_main_query() && is_admin() && isset( $query->query_vars['post_type'] ) && 'page' == $query->query_vars['post_type'] ) {
281
  $wpforms_preview = intval( get_option( 'wpforms_preview_page' ) );
282
  if( $wpforms_preview ) {
285
  $query->set( 'post__not_in', $exclude );
286
  }
287
  }
288
+ }
289
  }
includes/class-process.php CHANGED
@@ -103,16 +103,15 @@ class WPForms_Process {
103
  // reCAPTCHA check
104
  $site_key = wpforms_setting( 'recaptcha-site-key', '' );
105
  $secret_key = wpforms_setting( 'recaptcha-secret-key', '' );
106
- if ( !empty( $site_key ) || !empty( $secret_key ) ) {
107
- if ( isset( $form_data['settings']['recaptcha'] ) && '1' == $form_data['settings']['recaptcha'] ) {
108
- // We should have a reCAPTCHA so let's process
109
- $response = $_POST['g-recaptcha-response'];
110
- $secret = wpforms_setting( 'recaptcha-secret-key' );
111
- $data = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret . '&response=' . $response );
112
- $data = json_decode( wp_remote_retrieve_body( $data ) );
113
  if ( empty( $data->success ) ) {
114
  $this->errors[$form_id]['recaptcha'] = __( 'Incorrect reCAPTCHA, please try again.', 'wpforms' );
115
  }
 
 
116
  }
117
  }
118
 
@@ -179,12 +178,12 @@ class WPForms_Process {
179
  $_POST['wpforms']['entry_id'] = $entry_id;
180
 
181
  // Logs entry depending on log levels set
182
- wpforms_log(
183
- 'Entry',
184
- $this->fields,
185
- array(
186
- 'type' => array( 'entry' ),
187
- 'parent' => $entry_id,
188
  'form_id' => $form_data['id'],
189
  )
190
  );
@@ -192,15 +191,15 @@ class WPForms_Process {
192
  // Post-process hooks
193
  do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
194
  do_action( "wpforms_process_complete_{$form_id}", $this->fields, $entry, $form_data, $entry_id );
195
-
196
  } else {
197
 
198
  // Logs spam entry depending on log levels set
199
- wpforms_log(
200
- 'Spam Entry',
201
- array( $honeypot, $entry ),
202
- array(
203
- 'type' => array( 'spam' ),
204
  'form_id' => $form_data['id'],
205
  )
206
  );
@@ -326,7 +325,7 @@ class WPForms_Process {
326
  continue;
327
  }
328
 
329
- $process_email = apply_filters( 'wpforms_entry_email_process', true, $fields, $form_data, $notification_id );
330
 
331
  if ( ! $process_email ) {
332
  continue;
@@ -353,11 +352,16 @@ class WPForms_Process {
353
  $emails->__set( 'from_address', $email['sender_address'] );
354
  $emails->__set( 'reply_to', $email['replyto'] );
355
 
 
 
 
 
 
356
  // Go
357
  foreach( $email['address'] as $address ) {
358
  $emails->send( trim( $address ), $email['subject'], $email['message'] );
359
- }
360
- }
361
  }
362
 
363
  /**
@@ -374,4 +378,4 @@ class WPForms_Process {
374
 
375
  return $this->entry_id;
376
  }
377
- }
103
  // reCAPTCHA check
104
  $site_key = wpforms_setting( 'recaptcha-site-key', '' );
105
  $secret_key = wpforms_setting( 'recaptcha-secret-key', '' );
106
+ if ( !empty( $site_key ) && !empty( $secret_key ) && isset( $form_data['settings']['recaptcha'] ) && '1' == $form_data['settings']['recaptcha'] ) {
107
+ if ( !empty( $_POST['g-recaptcha-response'] ) ) {
108
+ $data = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $_POST['g-recaptcha-response'] );
109
+ $data = json_decode( wp_remote_retrieve_body( $data ) );
 
 
 
110
  if ( empty( $data->success ) ) {
111
  $this->errors[$form_id]['recaptcha'] = __( 'Incorrect reCAPTCHA, please try again.', 'wpforms' );
112
  }
113
+ } else {
114
+ $this->errors[$form_id]['recaptcha'] = __( 'reCAPTCHA is required.', 'wpforms' );
115
  }
116
  }
117
 
178
  $_POST['wpforms']['entry_id'] = $entry_id;
179
 
180
  // Logs entry depending on log levels set
181
+ wpforms_log(
182
+ 'Entry',
183
+ $this->fields,
184
+ array(
185
+ 'type' => array( 'entry' ),
186
+ 'parent' => $entry_id,
187
  'form_id' => $form_data['id'],
188
  )
189
  );
191
  // Post-process hooks
192
  do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
193
  do_action( "wpforms_process_complete_{$form_id}", $this->fields, $entry, $form_data, $entry_id );
194
+
195
  } else {
196
 
197
  // Logs spam entry depending on log levels set
198
+ wpforms_log(
199
+ 'Spam Entry',
200
+ array( $honeypot, $entry ),
201
+ array(
202
+ 'type' => array( 'spam' ),
203
  'form_id' => $form_data['id'],
204
  )
205
  );
325
  continue;
326
  }
327
 
328
+ $process_email = apply_filters( 'wpforms_entry_email_process', true, $fields, $form_data, $notification_id );
329
 
330
  if ( ! $process_email ) {
331
  continue;
352
  $emails->__set( 'from_address', $email['sender_address'] );
353
  $emails->__set( 'reply_to', $email['replyto'] );
354
 
355
+ // Maybe include CC
356
+ if ( !empty( $notification['carboncopy'] ) && wpforms_setting( 'email-carbon-copy', false ) ) {
357
+ $emails->__set( 'cc', $notification['carboncopy'] );
358
+ }
359
+
360
  // Go
361
  foreach( $email['address'] as $address ) {
362
  $emails->send( trim( $address ), $email['subject'], $email['message'] );
363
+ }
364
+ }
365
  }
366
 
367
  /**
378
 
379
  return $this->entry_id;
380
  }
381
+ }
includes/class-smart-tags.php CHANGED
@@ -43,6 +43,9 @@ class WPForms_Smart_Tags {
43
  'user_id' => __( 'User ID', 'wpforms' ),
44
  'user_display' => __( 'User Name', 'wpforms' ),
45
  'user_email' => __( 'User Email', 'wpforms' ),
 
 
 
46
  'url_referer' => __( 'Referer URL', 'wpforms' ),
47
  'url_login' => __( 'Login URL', 'wpforms' ),
48
  'url_logout' => __( 'Logout URL', 'wpforms' ),
@@ -67,7 +70,7 @@ class WPForms_Smart_Tags {
67
 
68
  // Return raw array
69
  return $tags;
70
- }
71
  }
72
 
73
  /**
@@ -88,7 +91,7 @@ class WPForms_Smart_Tags {
88
  if ( !empty( $tags[1] ) ) {
89
 
90
  foreach( $tags[1] as $key => $tag ) {
91
-
92
  switch ( $tag ) {
93
 
94
  case 'admin_email':
@@ -157,6 +160,22 @@ class WPForms_Smart_Tags {
157
  $content = str_replace( '{'.$tag.'}', $email, $content );
158
  break;
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  case 'url_referer':
161
  $referer = !empty( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '';
162
  $content = str_replace( '{'.$tag.'}', sanitize_text_field( $referer ), $content );
@@ -179,6 +198,7 @@ class WPForms_Smart_Tags {
179
  break;
180
 
181
  default:
 
182
  break;
183
  }
184
  }
@@ -231,7 +251,7 @@ class WPForms_Smart_Tags {
231
  } else {
232
  $value = !empty( $fields[$field_id]['value'] ) ? sanitize_text_field( $fields[$field_id]['value'] ) : '';
233
  }
234
-
235
  $content = str_replace( '{field_value_id="' . $field_id . '"}', $value , $content );
236
  }
237
  }
43
  'user_id' => __( 'User ID', 'wpforms' ),
44
  'user_display' => __( 'User Name', 'wpforms' ),
45
  'user_email' => __( 'User Email', 'wpforms' ),
46
+ 'author_id' => __( 'Author ID', 'wpforms' ),
47
+ 'author_display' => __( 'Author Name', 'wpforms' ),
48
+ 'author_email' => __( 'Author Email', 'wpforms' ),
49
  'url_referer' => __( 'Referer URL', 'wpforms' ),
50
  'url_login' => __( 'Login URL', 'wpforms' ),
51
  'url_logout' => __( 'Logout URL', 'wpforms' ),
70
 
71
  // Return raw array
72
  return $tags;
73
+ }
74
  }
75
 
76
  /**
91
  if ( !empty( $tags[1] ) ) {
92
 
93
  foreach( $tags[1] as $key => $tag ) {
94
+
95
  switch ( $tag ) {
96
 
97
  case 'admin_email':
160
  $content = str_replace( '{'.$tag.'}', $email, $content );
161
  break;
162
 
163
+ case 'author_id':
164
+ $id = get_the_author_meta( 'ID' );
165
+ $content = str_replace( '{'.$tag.'}', $id, $content );
166
+ break;
167
+
168
+ case 'author_display':
169
+ $name = get_the_author();
170
+ $name = !empty( $name ) ? sanitize_text_field( $name ) : '';
171
+ $content = str_replace( '{'.$tag.'}', $name, $content );
172
+ break;
173
+
174
+ case 'author_email':
175
+ $email = sanitize_email( get_the_author_meta( 'user_email' ) );
176
+ $content = str_replace( '{'.$tag.'}', $email, $content );
177
+ break;
178
+
179
  case 'url_referer':
180
  $referer = !empty( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '';
181
  $content = str_replace( '{'.$tag.'}', sanitize_text_field( $referer ), $content );
198
  break;
199
 
200
  default:
201
+ $content = apply_filters( 'wpforms_smart_tag_process', $content, $tag );
202
  break;
203
  }
204
  }
251
  } else {
252
  $value = !empty( $fields[$field_id]['value'] ) ? sanitize_text_field( $fields[$field_id]['value'] ) : '';
253
  }
254
+
255
  $content = str_replace( '{field_value_id="' . $field_id . '"}', $value , $content );
256
  }
257
  }
includes/emails/class-emails.php CHANGED
@@ -36,6 +36,13 @@ class WPForms_WP_Emails {
36
  */
37
  private $reply_to = false;
38
 
 
 
 
 
 
 
 
39
  /**
40
  * Holds the email content type.
41
  *
@@ -69,14 +76,14 @@ class WPForms_WP_Emails {
69
  *
70
  * @since 1.1.3
71
  */
72
- private $form_data = '';
73
 
74
  /**
75
  * Fields, formatted, and sanitized.
76
  *
77
  * @since 1.1.3
78
  */
79
- private $fields = '';
80
 
81
  /**
82
  * Entry ID.
@@ -120,7 +127,7 @@ class WPForms_WP_Emails {
120
  */
121
  public function get_from_name() {
122
 
123
- if ( !empty( $this->from_name ) ) {
124
  $this->from_name = $this->process_tag( $this->from_name );
125
  } else {
126
  $this->from_name = get_bloginfo( 'name' );
@@ -155,12 +162,43 @@ class WPForms_WP_Emails {
155
  public function get_reply_to() {
156
 
157
  if ( !empty( $this->reply_to ) ) {
 
158
  $this->reply_to = $this->process_tag( $this->reply_to );
 
 
 
 
159
  }
160
 
161
  return apply_filters( 'wpforms_email_reply_to', $this->reply_to, $this );
162
  }
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Get the email content type.
166
  *
@@ -191,6 +229,9 @@ class WPForms_WP_Emails {
191
  if ( $this->get_reply_to() ) {
192
  $this->headers .= "Reply-To: {$this->get_reply_to()}\r\n";
193
  }
 
 
 
194
  $this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8\r\n";
195
  }
196
 
@@ -207,8 +248,8 @@ class WPForms_WP_Emails {
207
  public function build_email( $message ) {
208
 
209
  if ( false === $this->html ) {
210
- $message = $this->process_tag( $message );
211
- $message = str_replace( '{all_fields}', $this->process_all_fields( false ), $message );
212
  return apply_filters( 'wpforms_email_message', wp_strip_all_tags( $message ), $this );
213
  }
214
 
@@ -234,7 +275,8 @@ class WPForms_WP_Emails {
234
 
235
  $body = ob_get_clean();
236
  $message = str_replace( '{email}', $message, $body );
237
- $message = str_replace( '{all_fields}', $this->process_all_fields( true ), $message );
 
238
 
239
  return apply_filters( 'wpforms_email_message', $message, $this );
240
  }
@@ -283,7 +325,7 @@ class WPForms_WP_Emails {
283
 
284
  /**
285
  * Add filters/actions before the email is sent.
286
- *
287
  * @since 1.1.3
288
  */
289
  public function send_before() {
@@ -306,7 +348,7 @@ class WPForms_WP_Emails {
306
  }
307
 
308
  /**
309
- * Converts text formatted HTML. This is primarily for turning line breaks
310
  * into <p> and <br/> tags.
311
  *
312
  * @since 1.1.3
@@ -330,14 +372,18 @@ class WPForms_WP_Emails {
330
  * @param bool $sanitize
331
  * @return string
332
  */
333
- function process_tag( $string = '', $santiize = true ) {
334
 
335
  $tag = apply_filters( 'wpforms_process_smart_tags', $string, $this->form_data, $this->fields, $this->entry_id );
336
 
337
  $tag = stripslashes( wp_specialchars_decode( $tag ) );
338
 
339
- if ( $santiize ) {
340
- $tag = sanitize_text_field( $tag );
 
 
 
 
341
  }
342
 
343
  return $tag;
@@ -348,7 +394,7 @@ class WPForms_WP_Emails {
348
  *
349
  * @since 1.1.3
350
  */
351
- function process_all_fields( $html = true ) {
352
 
353
  if ( empty( $this->fields ) )
354
  return;
@@ -373,20 +419,20 @@ class WPForms_WP_Emails {
373
  if ( !empty( $field['value'] ) && false !== $field['value'] ) {
374
 
375
  $field_name = !empty( $field['name'] ) ? $field['name'] : __( 'Field ID #', 'wpforms' ) . absint( $field['id'] );
376
-
377
  $field_item = $field_template;
378
  if ( $x === 1 ) {
379
  $field_item = str_replace( 'border-top:1px solid #dddddd;', '', $field_item );
380
  }
381
  $field_item = str_replace( '{field_name}', $field_name, $field_item );
382
- $field_value = apply_filters( 'wpforms_html_field_value', stripslashes( wp_specialchars_decode( $field['value'] ) ), $field, $this->form_data );
383
  $field_item = str_replace( '{field_value}', $field_value, $field_item );
384
-
385
  $message .= wpautop( $field_item );
386
  $x++;
387
  }
388
  }
389
-
390
  } else {
391
 
392
  // Plain Text emails ---------------------------------------------//
@@ -397,7 +443,8 @@ class WPForms_WP_Emails {
397
  $field_name = !empty( $field['name'] ) ? $field['name'] : __( 'Field ID #', 'wpforms' ) . absint( $field['id'] );
398
 
399
  $message .= "--- " . wp_specialchars_decode( $field_name ) . " ---\r\n";
400
- $message .= stripslashes( wp_specialchars_decode( $field['value'] ) ) . "\r\n\r\n";
 
401
  }
402
  }
403
  }
@@ -523,4 +570,4 @@ class WPForms_WP_Emails {
523
 
524
  return array_map( 'trailingslashit', $file_paths );
525
  }
526
- }
36
  */
37
  private $reply_to = false;
38
 
39
+ /**
40
+ * Holds the carbon copy addresses.
41
+ *
42
+ * @since 1.3,1
43
+ */
44
+ private $cc = false;
45
+
46
  /**
47
  * Holds the email content type.
48
  *
76
  *
77
  * @since 1.1.3
78
  */
79
+ public $form_data = '';
80
 
81
  /**
82
  * Fields, formatted, and sanitized.
83
  *
84
  * @since 1.1.3
85
  */
86
+ public $fields = '';
87
 
88
  /**
89
  * Entry ID.
127
  */
128
  public function get_from_name() {
129
 
130
+ if ( !empty( $this->from_name ) ) {
131
  $this->from_name = $this->process_tag( $this->from_name );
132
  } else {
133
  $this->from_name = get_bloginfo( 'name' );
162
  public function get_reply_to() {
163
 
164
  if ( !empty( $this->reply_to ) ) {
165
+
166
  $this->reply_to = $this->process_tag( $this->reply_to );
167
+
168
+ if ( !is_email( $this->reply_to ) ) {
169
+ $this->reply_to = false;
170
+ }
171
  }
172
 
173
  return apply_filters( 'wpforms_email_reply_to', $this->reply_to, $this );
174
  }
175
 
176
+ /**
177
+ * Get the email carbon copy addresses.
178
+ *
179
+ * @since 1.3.1
180
+ * @return string The email reply-to address
181
+ */
182
+ public function get_cc() {
183
+
184
+ if ( !empty( $this->cc ) ) {
185
+
186
+ $this->cc = $this->process_tag( $this->cc );
187
+
188
+ $addresses = array_map( 'trim', explode(',', $this->cc ) );
189
+
190
+ foreach ( $addresses as $key => $address ) {
191
+ if ( !is_email( $address ) ) {
192
+ unset( $addresses[$key] );
193
+ }
194
+ }
195
+
196
+ $this->cc = implode( ',', $addresses );
197
+ }
198
+
199
+ return apply_filters( 'wpforms_email_cc', $this->cc, $this );
200
+ }
201
+
202
  /**
203
  * Get the email content type.
204
  *
229
  if ( $this->get_reply_to() ) {
230
  $this->headers .= "Reply-To: {$this->get_reply_to()}\r\n";
231
  }
232
+ if ( $this->get_cc() ) {
233
+ $this->headers .= "Cc: {$this->get_cc()}\r\n";
234
+ }
235
  $this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8\r\n";
236
  }
237
 
248
  public function build_email( $message ) {
249
 
250
  if ( false === $this->html ) {
251
+ $message = $this->process_tag( $message, true, true );
252
+ $message = str_replace( '{all_fields}', $this->wpforms_html_field_value( false ), $message );
253
  return apply_filters( 'wpforms_email_message', wp_strip_all_tags( $message ), $this );
254
  }
255
 
275
 
276
  $body = ob_get_clean();
277
  $message = str_replace( '{email}', $message, $body );
278
+ $message = str_replace( '{all_fields}', $this->wpforms_html_field_value( true ), $message );
279
+ $message = make_clickable( $message );
280
 
281
  return apply_filters( 'wpforms_email_message', $message, $this );
282
  }
325
 
326
  /**
327
  * Add filters/actions before the email is sent.
328
+ *
329
  * @since 1.1.3
330
  */
331
  public function send_before() {
348
  }
349
 
350
  /**
351
+ * Converts text formatted HTML. This is primarily for turning line breaks
352
  * into <p> and <br/> tags.
353
  *
354
  * @since 1.1.3
372
  * @param bool $sanitize
373
  * @return string
374
  */
375
+ function process_tag( $string = '', $sanitize = true, $linebreaks = false ) {
376
 
377
  $tag = apply_filters( 'wpforms_process_smart_tags', $string, $this->form_data, $this->fields, $this->entry_id );
378
 
379
  $tag = stripslashes( wp_specialchars_decode( $tag ) );
380
 
381
+ if ( $sanitize ) {
382
+ if ( function_exists( 'sanitize_textarea_field' ) && $linebreaks ) {
383
+ $tag = sanitize_textarea_field( $tag );
384
+ } else {
385
+ $tag = sanitize_text_field( $tag );
386
+ }
387
  }
388
 
389
  return $tag;
394
  *
395
  * @since 1.1.3
396
  */
397
+ function wpforms_html_field_value( $html = true ) {
398
 
399
  if ( empty( $this->fields ) )
400
  return;
419
  if ( !empty( $field['value'] ) && false !== $field['value'] ) {
420
 
421
  $field_name = !empty( $field['name'] ) ? $field['name'] : __( 'Field ID #', 'wpforms' ) . absint( $field['id'] );
422
+
423
  $field_item = $field_template;
424
  if ( $x === 1 ) {
425
  $field_item = str_replace( 'border-top:1px solid #dddddd;', '', $field_item );
426
  }
427
  $field_item = str_replace( '{field_name}', $field_name, $field_item );
428
+ $field_value = apply_filters( 'wpforms_html_field_value', stripslashes( wp_specialchars_decode( $field['value'] ) ), $field, $this->form_data, 'email-html' );
429
  $field_item = str_replace( '{field_value}', $field_value, $field_item );
430
+
431
  $message .= wpautop( $field_item );
432
  $x++;
433
  }
434
  }
435
+
436
  } else {
437
 
438
  // Plain Text emails ---------------------------------------------//
443
  $field_name = !empty( $field['name'] ) ? $field['name'] : __( 'Field ID #', 'wpforms' ) . absint( $field['id'] );
444
 
445
  $message .= "--- " . wp_specialchars_decode( $field_name ) . " ---\r\n";
446
+ $field_value = stripslashes( wp_specialchars_decode( $field['value'] ) ) . "\r\n\r\n";
447
+ $message .= apply_filters( 'wpforms_plaintext_field_value', $field_value, $field, $this->form_data );
448
  }
449
  }
450
  }
570
 
571
  return array_map( 'trailingslashit', $file_paths );
572
  }
573
+ }
includes/fields/class-base.php CHANGED
@@ -244,7 +244,7 @@ abstract class WPForms_Field {
244
  // Select
245
  case 'select':
246
  $options = $args['options'];
247
- $value = isset( $args['value'] ) ? $args['value'] : '';
248
  $output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
249
  foreach ( $options as $key => $option ) {
250
  $output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( $key, $value, false ), $option );
@@ -349,19 +349,19 @@ abstract class WPForms_Field {
349
  $values = !empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
350
  $class = !empty( $field['show_values'] ) && $field['show_values'] == '1' ? 'show-values' : '';
351
  $class .= !empty( $dynamic ) ? ' wpforms-hidden' : '';
352
-
353
  // Field option label
354
- $option_label = $this->field_element(
355
- 'label',
356
- $field,
357
- array(
358
- 'slug' => 'choices',
359
- 'value' => __( 'Choices', 'wpforms' ),
360
- 'tooltip' => $tooltip
361
- ),
362
  false
363
  );
364
-
365
  // Field option choices inputs
366
  $option_choices = sprintf( '<ul data-next-id="%s" class="%s" data-field-id="%d" data-field-type="%s">', max( array_keys( $values ) ) +1, $class, $field['id'], $this->type );
367
  foreach ( $values as $key => $value ) {
@@ -383,7 +383,7 @@ abstract class WPForms_Field {
383
  $status_visibility = !empty( $dynamic ) && !empty( $field['dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden';
384
 
385
  if ( 'post_type' == $dynamic && !empty( $field['dynamic_' . $dynamic ] ) ) {
386
-
387
  $type_name = __( 'post type', 'wpforms' );
388
  $source = $field['dynamic_' . $dynamic ];
389
  $pt = get_post_type_object( $source );
@@ -396,20 +396,67 @@ abstract class WPForms_Field {
396
  $tax = get_taxonomy( $source );
397
  $source_name = $tax->labels->name;
398
  }
399
-
400
  $option_status = sprintf( '<div class="wpforms-alert-warning wpforms-alert %s">', $status_visibility );
401
  $option_status .= sprintf( __( 'Choices are dynamically populated from the <span class="dynamic-name">%s</span> <span class="dynamic-type">%s</span>', 'wpforms' ), $source_name, $type_name );
402
  $option_status .= '</div>';
403
-
404
  // Field option row (markup) including label and input.
405
- $output = $this->field_element(
406
- 'row',
407
- $field,
408
- array(
409
- 'slug' => 'choices',
410
  'content' => $option_label . $option_choices . $option_status,
411
  )
412
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  break;
414
 
415
  //----------------------------------------------------------------//
@@ -528,24 +575,24 @@ abstract class WPForms_Field {
528
  $output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
529
  $output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
530
  break;
531
-
532
  // Dynamic Choices Source ----------------------------------------//
533
 
534
  case 'dynamic_choices_source':
535
-
536
  $output = '';
537
  $type = !empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
538
 
539
  if ( !empty( $type ) ) {
540
-
541
  if ( 'post_type' == $type ) {
542
-
543
  $type_name = __( 'Post Type', 'wpforms' );
544
  $items = get_post_types( array( 'public' => true ), 'objects' );
545
  unset( $items['attachment'] );
546
-
547
  } elseif ( 'taxonomy' == $type ) {
548
-
549
  $type_name = __( 'Taxonomy', 'wpforms' );
550
  $items = get_taxonomies( array( 'public' => true ), 'objects' );
551
  unset( $items['post_format'] );
@@ -561,39 +608,39 @@ abstract class WPForms_Field {
561
  }
562
 
563
  // Field option label
564
- $option_label = $this->field_element(
565
- 'label',
566
- $field,
567
- array(
568
  'slug' => 'dynamic_' . $type,
569
- 'value' => $label,
570
  'tooltip' => $tooltip,
571
  ),
572
  false
573
  );
574
 
575
  // Field option select input
576
- $option_input = $this->field_element(
577
- 'select',
578
- $field,
579
- array(
580
- 'slug' => 'dynamic_' . $type,
581
  'options' => $options,
582
  'value' => $source,
583
- ),
584
- false
585
  );
586
-
587
  // Field option row (markup) including label and input.
588
- $output = $this->field_element(
589
- 'row',
590
- $field,
591
- array(
592
- 'slug' => 'dynamic_' . $type,
593
  'content' => $option_label . $option_input
594
- ),
595
  false
596
- );
597
  }
598
  break;
599
  }
@@ -708,8 +755,8 @@ abstract class WPForms_Field {
708
 
709
  // Build Options
710
  $options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
711
- $options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d">', $field['id'], $field['id'] );
712
- $options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s">', $field['id'], esc_attr( $field['type'] ) );
713
  ob_start();
714
  $this->field_options( $field );
715
  $options .= ob_get_clean();
244
  // Select
245
  case 'select':
246
  $options = $args['options'];
247
+ $value = isset( $args['value'] ) ? $args['value'] : '';
248
  $output = sprintf( '<select class="%s" id="wpforms-field-option-%d-%s" name="fields[%d][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
249
  foreach ( $options as $key => $option ) {
250
  $output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( $key, $value, false ), $option );
349
  $values = !empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
350
  $class = !empty( $field['show_values'] ) && $field['show_values'] == '1' ? 'show-values' : '';
351
  $class .= !empty( $dynamic ) ? ' wpforms-hidden' : '';
352
+
353
  // Field option label
354
+ $option_label = $this->field_element(
355
+ 'label',
356
+ $field,
357
+ array(
358
+ 'slug' => 'choices',
359
+ 'value' => __( 'Choices', 'wpforms' ),
360
+ 'tooltip' => $tooltip
361
+ ),
362
  false
363
  );
364
+
365
  // Field option choices inputs
366
  $option_choices = sprintf( '<ul data-next-id="%s" class="%s" data-field-id="%d" data-field-type="%s">', max( array_keys( $values ) ) +1, $class, $field['id'], $this->type );
367
  foreach ( $values as $key => $value ) {
383
  $status_visibility = !empty( $dynamic ) && !empty( $field['dynamic_' . $dynamic ] ) ? '' : 'wpforms-hidden';
384
 
385
  if ( 'post_type' == $dynamic && !empty( $field['dynamic_' . $dynamic ] ) ) {
386
+
387
  $type_name = __( 'post type', 'wpforms' );
388
  $source = $field['dynamic_' . $dynamic ];
389
  $pt = get_post_type_object( $source );
396
  $tax = get_taxonomy( $source );
397
  $source_name = $tax->labels->name;
398
  }
399
+
400
  $option_status = sprintf( '<div class="wpforms-alert-warning wpforms-alert %s">', $status_visibility );
401
  $option_status .= sprintf( __( 'Choices are dynamically populated from the <span class="dynamic-name">%s</span> <span class="dynamic-type">%s</span>', 'wpforms' ), $source_name, $type_name );
402
  $option_status .= '</div>';
403
+
404
  // Field option row (markup) including label and input.
405
+ $output = $this->field_element(
406
+ 'row',
407
+ $field,
408
+ array(
409
+ 'slug' => 'choices',
410
  'content' => $option_label . $option_choices . $option_status,
411
  )
412
+ );
413
+ break;
414
+
415
+ // Choices for payments ------------------------------------------//
416
+
417
+ case 'choices_payments':
418
+
419
+ $tooltip = __( 'Add choices for the form field.', 'wpforms' );
420
+ $values = !empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
421
+
422
+ // Field option label
423
+ $option_label = $this->field_element(
424
+ 'label',
425
+ $field,
426
+ array(
427
+ 'slug' => 'choices',
428
+ 'value' => __( 'Items', 'wpforms' ),
429
+ 'tooltip' => $tooltip
430
+ ),
431
+ false
432
+ );
433
+
434
+ // Field option choices inputs
435
+ $option_choices = sprintf( '<ul data-next-id="%s" data-field-id="%d" data-field-type="%s">', max( array_keys( $values ) ) +1, $field['id'], $this->type );
436
+ foreach ( $values as $key => $value ) {
437
+ $default = !empty( $value['default'] ) ? $value['default'] : '';
438
+ $placeholder = wpforms_format_amount( 0 );
439
+ $amount = !empty( $value['value'] ) ? wpforms_format_amount( wpforms_sanitize_amount( $value['value'] ) ) : $placeholder;
440
+ $option_choices .= sprintf( '<li data-key="%d">', $key );
441
+ $option_choices .= sprintf( '<input type="radio" name="fields[%s][choices][%s][default]" class="default" value="1" %s>', $field['id'], $key, checked( '1', $default, false ) );
442
+ $option_choices .= '<span class="move"><i class="fa fa-bars"></i></span>';
443
+ $option_choices .= sprintf( '<input type="text" name="fields[%s][choices][%s][label]" value="%s" class="label">', $field['id'], $key, esc_attr( $value['label'] ) );
444
+ $option_choices .= sprintf( '<input type="text" name="fields[%s][choices][%s][value]" value="%s" class="value wpforms-money-input" placeholder="%s">', $field['id'], $key, $amount, $placeholder );
445
+ $option_choices .= '<a class="add" href="#"><i class="fa fa-plus-circle"></i></a>';
446
+ $option_choices .= '<a class="remove" href="#"><i class="fa fa-minus-circle"></i></a>';
447
+ $option_choices .= '</li>';
448
+ }
449
+ $option_choices .= '</ul>';
450
+
451
+ // Field option row (markup) including label and input.
452
+ $output = $this->field_element(
453
+ 'row',
454
+ $field,
455
+ array(
456
+ 'slug' => 'choices',
457
+ 'content' => $option_label . $option_choices,
458
+ )
459
+ );
460
  break;
461
 
462
  //----------------------------------------------------------------//
575
  $output .= $this->field_element( 'select', $field, array( 'slug' => 'dynamic_choices', 'value' => $value, 'options' => $options ), false );
576
  $output = $this->field_element( 'row', $field, array( 'slug' => 'dynamic_choices', 'content' => $output ), false );
577
  break;
578
+
579
  // Dynamic Choices Source ----------------------------------------//
580
 
581
  case 'dynamic_choices_source':
582
+
583
  $output = '';
584
  $type = !empty( $field['dynamic_choices'] ) ? esc_attr( $field['dynamic_choices'] ) : '';
585
 
586
  if ( !empty( $type ) ) {
587
+
588
  if ( 'post_type' == $type ) {
589
+
590
  $type_name = __( 'Post Type', 'wpforms' );
591
  $items = get_post_types( array( 'public' => true ), 'objects' );
592
  unset( $items['attachment'] );
593
+
594
  } elseif ( 'taxonomy' == $type ) {
595
+
596
  $type_name = __( 'Taxonomy', 'wpforms' );
597
  $items = get_taxonomies( array( 'public' => true ), 'objects' );
598
  unset( $items['post_format'] );
608
  }
609
 
610
  // Field option label
611
+ $option_label = $this->field_element(
612
+ 'label',
613
+ $field,
614
+ array(
615
  'slug' => 'dynamic_' . $type,
616
+ 'value' => $label,
617
  'tooltip' => $tooltip,
618
  ),
619
  false
620
  );
621
 
622
  // Field option select input
623
+ $option_input = $this->field_element(
624
+ 'select',
625
+ $field,
626
+ array(
627
+ 'slug' => 'dynamic_' . $type,
628
  'options' => $options,
629
  'value' => $source,
630
+ ),
631
+ false
632
  );
633
+
634
  // Field option row (markup) including label and input.
635
+ $output = $this->field_element(
636
+ 'row',
637
+ $field,
638
+ array(
639
+ 'slug' => 'dynamic_' . $type,
640
  'content' => $option_label . $option_input
641
+ ),
642
  false
643
+ );
644
  }
645
  break;
646
  }
755
 
756
  // Build Options
757
  $options = sprintf( '<div class="wpforms-field-option wpforms-field-option-%s" id="wpforms-field-option-%d" data-field-id="%d">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
758
+ $options .= sprintf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', $field['id'], $field['id'] );
759
+ $options .= sprintf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
760
  ob_start();
761
  $this->field_options( $field );
762
  $options .= ob_get_clean();
includes/fields/class-number.php CHANGED
@@ -35,18 +35,18 @@ class WPForms_Field_Number extends WPForms_Field {
35
  //--------------------------------------------------------------------//
36
  // Basic field options
37
  //--------------------------------------------------------------------//
38
-
39
  //$this->field_option( 'meta', $field );
40
  $this->field_option( 'basic-options', $field, array( 'markup' => 'open' ) );
41
  $this->field_option( 'label', $field );
42
  $this->field_option( 'description', $field );
43
  $this->field_option( 'required', $field );
44
  $this->field_option( 'basic-options', $field, array( 'markup' => 'close' ) );
45
-
46
  //--------------------------------------------------------------------//
47
  // Advanced field options
48
  //--------------------------------------------------------------------//
49
-
50
  $this->field_option( 'advanced-options', $field, array( 'markup' => 'open' ) );
51
  $this->field_option( 'size', $field );
52
  $this->field_option( 'placeholder', $field );
@@ -98,7 +98,7 @@ class WPForms_Field_Number extends WPForms_Field {
98
  }
99
 
100
  // Primary text field
101
- printf(
102
  '<input type="number" name="wpforms[fields][%d]" id="%s" class="%s" value="%s" placeholder="%s" %s %s>',
103
  $field['id'],
104
  $field_id,
@@ -123,10 +123,10 @@ class WPForms_Field_Number extends WPForms_Field {
123
  $form_id = $form_data['id'];
124
 
125
  // Basic required check - If field is marked as required, check for entry data
126
- if ( !empty( $form_data['fields'][$field_id]['required'] ) && empty( $field_submit ) ) {
127
  wpforms()->process->errors[$form_id][$field_id] = apply_filters( 'wpforms_required_label', __('This field is required', 'wpforms' ) );
128
  }
129
-
130
  // Check that email is valid format
131
  if ( !empty( $field_submit ) && !is_numeric( $field_submit ) ) {
132
  wpforms()->process->errors[$form_id][$field_id] = apply_filters( 'wpforms_valid_number_label', __('Please enter a valid number.', 'wpforms' ) );
35
  //--------------------------------------------------------------------//
36
  // Basic field options
37
  //--------------------------------------------------------------------//
38
+
39
  //$this->field_option( 'meta', $field );
40
  $this->field_option( 'basic-options', $field, array( 'markup' => 'open' ) );
41
  $this->field_option( 'label', $field );
42
  $this->field_option( 'description', $field );
43
  $this->field_option( 'required', $field );
44
  $this->field_option( 'basic-options', $field, array( 'markup' => 'close' ) );
45
+
46
  //--------------------------------------------------------------------//
47
  // Advanced field options
48
  //--------------------------------------------------------------------//
49
+
50
  $this->field_option( 'advanced-options', $field, array( 'markup' => 'open' ) );
51
  $this->field_option( 'size', $field );
52
  $this->field_option( 'placeholder', $field );
98
  }
99
 
100
  // Primary text field
101
+ printf(
102
  '<input type="number" name="wpforms[fields][%d]" id="%s" class="%s" value="%s" placeholder="%s" %s %s>',
103
  $field['id'],
104
  $field_id,
123
  $form_id = $form_data['id'];
124
 
125
  // Basic required check - If field is marked as required, check for entry data
126
+ if ( !empty( $form_data['fields'][$field_id]['required'] ) && empty( $field_submit ) && '0' != $field_submit ) {
127
  wpforms()->process->errors[$form_id][$field_id] = apply_filters( 'wpforms_required_label', __('This field is required', 'wpforms' ) );
128
  }
129
+
130
  // Check that email is valid format
131
  if ( !empty( $field_submit ) && !is_numeric( $field_submit ) ) {
132
  wpforms()->process->errors[$form_id][$field_id] = apply_filters( 'wpforms_valid_number_label', __('Please enter a valid number.', 'wpforms' ) );
includes/functions.php CHANGED
@@ -78,7 +78,7 @@ function wpforms_object_to_array( $object ) {
78
  if ( !is_object( $object ) && !is_array( $object ) ) {
79
  return $object;
80
  }
81
-
82
  if ( is_object( $object ) ) {
83
  $object = get_object_vars( $object );
84
  }
@@ -96,14 +96,14 @@ function wpforms_setting( $key, $default = false, $option = 'wpforms_settings'
96
  $options = get_option( $option, false );
97
 
98
  $value = is_array( $options ) && ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
99
-
100
  return $value;
101
  }
102
 
103
  /**
104
  * Check if form provided contains the specified field type.
105
  *
106
- * @since 1.0.5
107
  * @param string $type
108
  * @param mixed $form
109
  * @return bool
@@ -130,7 +130,7 @@ function wpforms_has_field_type( $type, $form, $multiple = false ) {
130
  $form_data = $form;
131
  }
132
 
133
- if ( empty( $form_data['fields'] ) )
134
  return false;
135
 
136
  foreach ( $form_data['fields'] as $single_field ) {
@@ -162,7 +162,7 @@ function wpforms_has_pagebreak( $form = false ) {
162
  $form_data = $form;
163
  }
164
 
165
- if ( empty( $form_data['fields'] ) )
166
  return false;
167
 
168
  $fields = $form_data['fields'];
@@ -190,7 +190,7 @@ function wpforms_has_pagebreak( $form = false ) {
190
  * @return boolean
191
  */
192
  function wpforms_get_pagebreak( $form = false, $type = false ) {
193
-
194
  $form_data = '';
195
 
196
  if ( is_object( $form ) && !empty( $form->post_content ) ) {
@@ -199,7 +199,7 @@ function wpforms_get_pagebreak( $form = false, $type = false ) {
199
  $form_data = $form;
200
  }
201
 
202
- if ( empty( $form_data['fields'] ) )
203
  return false;
204
 
205
  $fields = $form_data['fields'];
@@ -212,7 +212,7 @@ function wpforms_get_pagebreak( $form = false, $type = false ) {
212
  } elseif ( $position == $type ) {
213
  return $field;
214
  }
215
- }
216
  }
217
 
218
  if ( !empty( $pages ) ) {
@@ -254,23 +254,23 @@ function wpforms_size_to_bytes( $size ) {
254
  return $size;
255
  }
256
 
257
- $suffix = substr( $size, -1 );
258
  $value = substr( $size, 0, -1 );
259
 
260
- switch( strtoupper( $suffix ) ) {
261
- case 'P':
262
- $value *= 1024;
263
- case 'T':
264
- $value *= 1024;
265
- case 'G':
266
- $value *= 1024;
267
- case 'M':
268
- $value *= 1024;
269
- case 'K':
270
- $value *= 1024;
271
- break;
272
- }
273
- return $value;
274
  }
275
 
276
  /**
@@ -299,7 +299,7 @@ function wpforms_size_to_megabytes( $bytes ) {
299
  */
300
  function wpforms_max_upload( $bytes = false ) {
301
 
302
- $max = min( wpforms_size_to_bytes( ini_get( 'post_max_size' ) ), wpforms_size_to_bytes( ini_get( 'upload_max_filesize' ) ) );
303
  if ( $bytes ) {
304
  return $max;
305
  } else {
@@ -347,6 +347,7 @@ function wpforms_get_form_fields( $form = false, $whitelist = array() ) {
347
  'file-upload',
348
  'payment-single',
349
  'payment-multiple',
 
350
  'payment-total',
351
  );
352
  $allowed_form_fields = apply_filters( 'wpforms_get_form_fields_allowed', $allowed_form_fields );
@@ -386,6 +387,36 @@ function wpforms_get_form_field_meta( $id = '', $key = '', $form_data = '' ) {
386
  }
387
  }
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  /**
390
  * US States
391
  *
@@ -793,7 +824,7 @@ function wpforms_debug() {
793
  $debug = true;
794
  }
795
 
796
- $debug_option = get_option( 'wpforms_debug' );
797
 
798
  if ( $debug_option ) {
799
  $current_user = wp_get_current_user();
@@ -813,21 +844,21 @@ function wpforms_debug() {
813
  * @return string
814
  */
815
  function wpforms_debug_data( $data, $echo = true ) {
816
-
817
  if ( wpforms_debug() ) {
818
-
819
- $output = '<textarea style="background:#fff;margin: 20px 0;width:100%;height:500px;font-size:12px;font-family: Consolas,Monaco,monospace;direction: ltr;unicode-bidi: embed;line-height: 1.4;padding: 4px 6px 1px;" readonly>';
820
-
821
  $output .= "=================== WPFORMS DEBUG ===================\n\n";
822
-
823
  if ( is_array( $data ) || is_object( $data ) ) {
824
  $output .= ( print_r( $data, true ) );
825
  } else {
826
  $output .= $data;
827
  }
828
-
829
  $output .= '</textarea>';
830
-
831
  if ( $echo ) {
832
  echo $output;
833
  } else {
@@ -852,7 +883,7 @@ function wpforms_log( $title = '', $message = '', $args = array() ) {
852
 
853
  // Force logging everything when in debug mode
854
  if ( ! wpforms_debug() ) {
855
-
856
  /**
857
  * Compare error levels to determine if we should log.
858
  * Current supported levels:
@@ -886,52 +917,52 @@ function wpforms_log( $title = '', $message = '', $args = array() ) {
886
  // Make arrays and objects look nice
887
  if ( is_array( $message ) || is_object( $message ) ) {
888
  $message = '<pre>' . print_r( $message, true ) . '</pre>';
889
- }
890
 
891
  // Create log entry
892
  wpforms()->logs->add( $title, $message, $parent, $parent, $meta );
893
  }
894
 
895
- if ( ! function_exists( 'array_replace_recursive' ) ) :
896
- /**
897
- * PHP-agnostic version of {@link array_replace_recursive()}.
898
- *
899
- * The array_replace_recursive() function is a PHP 5.3 function. WordPress
900
- * currently supports down to PHP 5.2, so this method is a workaround
901
- * for PHP 5.2.
902
- *
903
- * Note: array_replace_recursive() supports infinite arguments, but for our use-
904
- * case, we only need to support two arguments.
905
- *
906
- * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
907
- *
908
- * @since 1.2.3
909
- * @see http://php.net/manual/en/function.array-replace-recursive.php#109390
910
- * @param array $base Array with keys needing to be replaced.
911
- * @param array $replacements Array with the replaced keys.
912
- * @return array
913
- */
914
- function array_replace_recursive( $base = array(), $replacements = array() ) {
915
- // PHP 5.2-compatible version
916
- // http://php.net/manual/en/function.array-replace-recursive.php#109390.
917
- foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
918
- $bref_stack = array( &$base );
919
- $head_stack = array( $replacements );
920
- do {
921
- end( $bref_stack );
922
- $bref = &$bref_stack[ key( $bref_stack ) ];
923
- $head = array_pop( $head_stack );
924
- unset( $bref_stack[ key( $bref_stack ) ] );
925
- foreach ( array_keys( $head ) as $key ) {
926
- if ( isset( $key, $bref ) && is_array( $bref[ $key ] ) && is_array( $head[ $key ] ) ) {
927
- $bref_stack[] = &$bref[ $key ];
928
- $head_stack[] = $head[ $key ];
929
- } else {
930
- $bref[ $key ] = $head[ $key ];
931
- }
932
- }
933
- } while ( count( $head_stack ) );
934
- }
935
- return $base;
936
  }
937
  endif;
78
  if ( !is_object( $object ) && !is_array( $object ) ) {
79
  return $object;
80
  }
81
+
82
  if ( is_object( $object ) ) {
83
  $object = get_object_vars( $object );
84
  }
96
  $options = get_option( $option, false );
97
 
98
  $value = is_array( $options ) && ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
99
+
100
  return $value;
101
  }
102
 
103
  /**
104
  * Check if form provided contains the specified field type.
105
  *
106
+ * @since 1.0.5
107
  * @param string $type
108
  * @param mixed $form
109
  * @return bool
130
  $form_data = $form;
131
  }
132
 
133
+ if ( empty( $form_data['fields'] ) )
134
  return false;
135
 
136
  foreach ( $form_data['fields'] as $single_field ) {
162
  $form_data = $form;
163
  }
164
 
165
+ if ( empty( $form_data['fields'] ) )
166
  return false;
167
 
168
  $fields = $form_data['fields'];
190
  * @return boolean
191
  */
192
  function wpforms_get_pagebreak( $form = false, $type = false ) {
193
+
194
  $form_data = '';
195
 
196
  if ( is_object( $form ) && !empty( $form->post_content ) ) {
199
  $form_data = $form;
200
  }
201
 
202
+ if ( empty( $form_data['fields'] ) )
203
  return false;
204
 
205
  $fields = $form_data['fields'];
212
  } elseif ( $position == $type ) {
213
  return $field;
214
  }
215
+ }
216
  }
217
 
218
  if ( !empty( $pages ) ) {
254
  return $size;
255
  }
256
 
257
+ $suffix = substr( $size, -1 );
258
  $value = substr( $size, 0, -1 );
259
 
260
+ switch( strtoupper( $suffix ) ) {
261
+ case 'P':
262
+ $value *= 1024;
263
+ case 'T':
264
+ $value *= 1024;
265
+ case 'G':
266
+ $value *= 1024;
267
+ case 'M':
268
+ $value *= 1024;
269
+ case 'K':
270
+ $value *= 1024;
271
+ break;
272
+ }
273
+ return $value;
274
  }
275
 
276
  /**
299
  */
300
  function wpforms_max_upload( $bytes = false ) {
301
 
302
+ $max = wp_max_upload_size();
303
  if ( $bytes ) {
304
  return $max;
305
  } else {
347
  'file-upload',
348
  'payment-single',
349
  'payment-multiple',
350
+ 'payment-select',
351
  'payment-total',
352
  );
353
  $allowed_form_fields = apply_filters( 'wpforms_get_form_fields_allowed', $allowed_form_fields );
387
  }
388
  }
389
 
390
+ /**
391
+ * Get meta key value for a form field.
392
+ *
393
+ * @since 1.3.1
394
+ * @param string $key Meta key
395
+ * @param array $form_data Form data array
396
+ * @return string
397
+ */
398
+ function wpforms_get_form_fields_by_meta( $key = '', $value = '', $form_data = '' ) {
399
+
400
+ if ( empty( $key ) || empty( $value ) || empty( $form_data['fields'] ) ) {
401
+ return false;
402
+ }
403
+
404
+ $found = array();
405
+
406
+ foreach( $form_data['fields'] as $id => $field ) {
407
+
408
+ if ( !empty( $field['meta'][$key] ) && $value == $field['meta'][$key] ) {
409
+ $found[$id] = $field;
410
+ }
411
+ }
412
+
413
+ if ( !empty( $found ) ) {
414
+ return $found;
415
+ } else {
416
+ return false;
417
+ }
418
+ }
419
+
420
  /**
421
  * US States
422
  *
824
  $debug = true;
825
  }
826
 
827
+ $debug_option = get_option( 'wpforms_debug' );
828
 
829
  if ( $debug_option ) {
830
  $current_user = wp_get_current_user();
844
  * @return string
845
  */
846
  function wpforms_debug_data( $data, $echo = true ) {
847
+
848
  if ( wpforms_debug() ) {
849
+
850
+ $output = '<textarea style="background:#fff;margin: 20px 0;width:100%;height:500px;font-size:12px;font-family: Consolas,Monaco,monospace;direction: ltr;unicode-bidi: embed;line-height: 1.4;padding: 4px 6px 1px;" readonly>';
851
+
852
  $output .= "=================== WPFORMS DEBUG ===================\n\n";
853
+
854
  if ( is_array( $data ) || is_object( $data ) ) {
855
  $output .= ( print_r( $data, true ) );
856
  } else {
857
  $output .= $data;
858
  }
859
+
860
  $output .= '</textarea>';
861
+
862
  if ( $echo ) {
863
  echo $output;
864
  } else {
883
 
884
  // Force logging everything when in debug mode
885
  if ( ! wpforms_debug() ) {
886
+
887
  /**
888
  * Compare error levels to determine if we should log.
889
  * Current supported levels:
917
  // Make arrays and objects look nice
918
  if ( is_array( $message ) || is_object( $message ) ) {
919
  $message = '<pre>' . print_r( $message, true ) . '</pre>';
920
+ }
921
 
922
  // Create log entry
923
  wpforms()->logs->add( $title, $message, $parent, $parent, $meta );
924
  }
925
 
926
+ if ( ! function_exists( 'array_replace_recursive' ) ) :
927
+ /**
928
+ * PHP-agnostic version of {@link array_replace_recursive()}.
929
+ *
930
+ * The array_replace_recursive() function is a PHP 5.3 function. WordPress
931
+ * currently supports down to PHP 5.2, so this method is a workaround
932
+ * for PHP 5.2.
933
+ *
934
+ * Note: array_replace_recursive() supports infinite arguments, but for our use-
935
+ * case, we only need to support two arguments.
936
+ *
937
+ * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
938
+ *
939
+ * @since 1.2.3
940
+ * @see http://php.net/manual/en/function.array-replace-recursive.php#109390
941
+ * @param array $base Array with keys needing to be replaced.
942
+ * @param array $replacements Array with the replaced keys.
943
+ * @return array
944
+ */
945
+ function array_replace_recursive( $base = array(), $replacements = array() ) {
946
+ // PHP 5.2-compatible version
947
+ // http://php.net/manual/en/function.array-replace-recursive.php#109390.
948
+ foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
949
+ $bref_stack = array( &$base );
950
+ $head_stack = array( $replacements );
951
+ do {
952
+ end( $bref_stack );
953
+ $bref = &$bref_stack[ key( $bref_stack ) ];
954
+ $head = array_pop( $head_stack );
955
+ unset( $bref_stack[ key( $bref_stack ) ] );
956
+ foreach ( array_keys( $head ) as $key ) {
957
+ if ( isset( $key, $bref ) && is_array( $bref[ $key ] ) && is_array( $head[ $key ] ) ) {
958
+ $bref_stack[] = &$bref[ $key ];
959
+ $head_stack[] = $head[ $key ];
960
+ } else {
961
+ $bref[ $key ] = $head[ $key ];
962
+ }
963
+ }
964
+ } while ( count( $head_stack ) );
965
+ }
966
+ return $base;
967
  }
968
  endif;
languages/wpforms.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the WPForms package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WPForms 1.3.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wpforms\n"
7
- "POT-Creation-Date: 2016-10-21 15:08:29+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -12,7 +12,7 @@ msgstr ""
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #: includes/admin/ajax-actions.php:24 includes/fields/class-base.php:667
16
  msgid "You do no have permission."
17
  msgstr ""
18
 
@@ -211,14 +211,14 @@ msgid "This item must contain at least one choice."
211
  msgstr ""
212
 
213
  #: includes/admin/builder/class-builder.php:301
214
- #: includes/fields/class-base.php:239 includes/fields/class-base.php:523
215
- #: lite/wpforms-lite.php:75 pro/wpforms-pro.php:258
216
  msgid "Off"
217
  msgstr ""
218
 
219
  #: includes/admin/builder/class-builder.php:302
220
- #: includes/fields/class-base.php:239 lite/wpforms-lite.php:74
221
- #: pro/wpforms-pro.php:257
222
  msgid "On"
223
  msgstr ""
224
 
@@ -227,14 +227,13 @@ msgstr ""
227
  msgid "Other"
228
  msgstr ""
229
 
230
- #: includes/admin/builder/class-builder.php:304
231
- #: includes/class-frontend.php:492
232
  #: pro/includes/fields/class-page-break.php:144
233
  msgid "Previous"
234
  msgstr ""
235
 
236
  #: includes/admin/builder/class-builder.php:307
237
- #: includes/admin/builder/functions.php:210 includes/fields/class-base.php:424
238
  msgid "Show Smart Tags"
239
  msgstr ""
240
 
@@ -278,7 +277,7 @@ msgid "Save Form"
278
  msgstr ""
279
 
280
  #: includes/admin/builder/class-builder.php:391
281
- #: pro/includes/admin/class-settings.php:441
282
  msgid "Save"
283
  msgstr ""
284
 
@@ -330,23 +329,23 @@ msgid "You don't have any fields yet. Add some!"
330
  msgstr ""
331
 
332
  #: includes/admin/builder/panels/class-fields.php:252
333
- #: includes/fields/class-base.php:703
334
  msgid "Duplicate Field"
335
  msgstr ""
336
 
337
  #: includes/admin/builder/panels/class-fields.php:254
338
- #: includes/fields/class-base.php:704
339
  msgid "Delete Field"
340
  msgstr ""
341
 
342
  #: includes/admin/builder/panels/class-fields.php:256
343
- #: includes/fields/class-base.php:705
344
  msgid "Click to edit. Drag to reorder."
345
  msgstr ""
346
 
347
  #: includes/admin/builder/panels/class-settings.php:21
348
- #: includes/admin/class-menu.php:84 lite/includes/admin/class-settings.php:388
349
- #: pro/includes/admin/class-settings.php:696
350
  msgid "Settings"
351
  msgstr ""
352
 
@@ -357,14 +356,13 @@ msgstr ""
357
  msgid "General"
358
  msgstr ""
359
 
360
- #: includes/admin/builder/panels/class-settings.php:58
361
- #: lite/wpforms-lite.php:60 lite/wpforms-lite.php:70 pro/wpforms-pro.php:244
362
- #: pro/wpforms-pro.php:253
363
  msgid "Notifications"
364
  msgstr ""
365
 
366
  #: includes/admin/builder/panels/class-settings.php:59
367
- #: includes/admin/builder/panels/class-settings.php:263
368
  msgid "Confirmation"
369
  msgstr ""
370
 
@@ -428,41 +426,41 @@ msgstr ""
428
  msgid "Enable reCAPTCHA"
429
  msgstr ""
430
 
431
- #: includes/admin/builder/panels/class-settings.php:270
432
  msgid "Confirmation Type"
433
  msgstr ""
434
 
435
- #: includes/admin/builder/panels/class-settings.php:274
436
- #: includes/templates/class-suggestion.php:74 lite/wpforms-lite.php:172
437
- #: pro/wpforms-pro.php:361
438
  msgid "Message"
439
  msgstr ""
440
 
441
- #: includes/admin/builder/panels/class-settings.php:275
442
  msgid "Show Page"
443
  msgstr ""
444
 
445
- #: includes/admin/builder/panels/class-settings.php:276
446
  msgid "Go to URL (Redirect)"
447
  msgstr ""
448
 
449
- #: includes/admin/builder/panels/class-settings.php:285
450
  msgid "Confirmation Message"
451
  msgstr ""
452
 
453
- #: includes/admin/builder/panels/class-settings.php:287
454
  msgid "Thanks for contacting us! We will be in touch with you shortly."
455
  msgstr ""
456
 
457
- #: includes/admin/builder/panels/class-settings.php:298
458
  msgid "Automatically scroll to the confirmation message"
459
  msgstr ""
460
 
461
- #: includes/admin/builder/panels/class-settings.php:311
462
  msgid "Confirmation Page"
463
  msgstr ""
464
 
465
- #: includes/admin/builder/panels/class-settings.php:319
466
  msgid "Confirmation Redirect URL"
467
  msgstr ""
468
 
@@ -531,9 +529,9 @@ msgid ""
531
  "a>?"
532
  msgstr ""
533
 
534
- #. #-#-#-#-# wpforms.pot (WPForms 1.3.0) #-#-#-#-#
535
  #. Plugin Name of the plugin/theme
536
- #. #-#-#-#-# wpforms.pot (WPForms 1.3.0) #-#-#-#-#
537
  #. Author of the plugin/theme
538
  #: includes/admin/class-menu.php:39 includes/admin/class-menu.php:40
539
  #: includes/admin/class-menu.php:51 includes/integrations.php:34
@@ -578,10 +576,10 @@ msgstr ""
578
 
579
  #: includes/admin/class-menu.php:134
580
  msgid ""
581
- "Please rate <strong>WPForms</strong> <a href=\"%s\" target=\"_blank\">&#9733;"
582
- "&#9733;&#9733;&#9733;&#9733;</a> on <a href=\"%s\" target=\"_blank"
583
- "\">WordPress.org</a> to help us spread the word. Thank you from the WPForms "
584
- "team!"
585
  msgstr ""
586
 
587
  #: includes/admin/class-welcome.php:40 includes/admin/class-welcome.php:41
@@ -619,8 +617,8 @@ msgstr ""
619
  #: includes/admin/class-welcome.php:121
620
  msgid ""
621
  "WPForms make it easy to create forms in WordPress. You can follow the video "
622
- "tutorial on the right or read our how to <a href=\"%s\" target=\"_blank"
623
- "\">create your first form guide</a>."
624
  msgstr ""
625
 
626
  #: includes/admin/class-welcome.php:122
@@ -693,8 +691,8 @@ msgstr ""
693
 
694
  #: includes/admin/overview/class-overview-table.php:173
695
  #: includes/admin/overview/class-overview-table.php:191
696
- #: pro/includes/admin/entries/class-entries-table.php:328
697
- #: pro/includes/admin/entries/class-entries-table.php:349
698
  #: pro/includes/admin/entries/class-entries.php:1013
699
  msgid "Delete"
700
  msgstr ""
@@ -799,20 +797,24 @@ msgstr ""
799
  msgid "Invalid form."
800
  msgstr ""
801
 
802
- #: includes/class-process.php:114
803
  msgid "Incorrect reCAPTCHA, please try again."
804
  msgstr ""
805
 
806
- #: includes/class-process.php:121 includes/class-process.php:164
 
 
 
 
807
  msgid "Form has not been submitted, please see the errors below."
808
  msgstr ""
809
 
810
- #: includes/class-process.php:128
811
  msgid "WPForms honeypot field triggered."
812
  msgstr ""
813
 
814
- #: includes/class-process.php:340 lite/wpforms-lite.php:52
815
- #: pro/wpforms-pro.php:237
816
  msgid "New %s Entry"
817
  msgstr ""
818
 
@@ -841,7 +843,7 @@ msgid "Embedded Post/Page ID"
841
  msgstr ""
842
 
843
  #: includes/class-smart-tags.php:40
844
- #: pro/includes/admin/entries/class-entries-export.php:172
845
  #: pro/includes/admin/entries/class-entries-table.php:129
846
  #: pro/includes/fields/class-date-time.php:69
847
  #: pro/includes/fields/class-date-time.php:117
@@ -872,26 +874,38 @@ msgid "User Email"
872
  msgstr ""
873
 
874
  #: includes/class-smart-tags.php:46
875
- msgid "Referer URL"
876
  msgstr ""
877
 
878
  #: includes/class-smart-tags.php:47
879
- msgid "Login URL"
880
  msgstr ""
881
 
882
  #: includes/class-smart-tags.php:48
883
- msgid "Logout URL"
884
  msgstr ""
885
 
886
  #: includes/class-smart-tags.php:49
887
- msgid "Register URL"
888
  msgstr ""
889
 
890
  #: includes/class-smart-tags.php:50
 
 
 
 
 
 
 
 
 
 
 
 
891
  msgid "Lost Password URL"
892
  msgstr ""
893
 
894
- #: includes/class-widget.php:127 pro/includes/admin/class-settings.php:524
895
  msgid "No forms"
896
  msgstr ""
897
 
@@ -903,13 +917,13 @@ msgstr ""
903
  msgid "Display form description"
904
  msgstr ""
905
 
906
- #: includes/emails/class-emails.php:254
907
  msgid ""
908
  "You cannot send emails with WPForms_WP_Emails until init/admin_init has been "
909
  "reached"
910
  msgstr ""
911
 
912
- #: includes/emails/class-emails.php:375 includes/emails/class-emails.php:397
913
  msgid "Field ID #"
914
  msgstr ""
915
 
@@ -953,7 +967,7 @@ msgstr ""
953
  msgid "Code"
954
  msgstr ""
955
 
956
- #: includes/fields/class-base.php:347
957
  msgid "Add choices for the form field."
958
  msgstr ""
959
 
@@ -967,14 +981,17 @@ msgid ""
967
  "span> <span class=\"dynamic-type\">%s</span>"
968
  msgstr ""
969
 
970
- #: includes/fields/class-base.php:423
 
 
 
 
971
  msgid "Enter text for the default form field value."
972
  msgstr ""
973
 
974
- #: includes/fields/class-base.php:425 includes/fields/class-name.php:81
975
  #: includes/fields/class-name.php:96 includes/fields/class-name.php:111
976
- #: includes/fields/class-name.php:126
977
- #: pro/includes/fields/class-address.php:117
978
  #: pro/includes/fields/class-address.php:133
979
  #: pro/includes/fields/class-address.php:151
980
  #: pro/includes/fields/class-address.php:166
@@ -983,125 +1000,126 @@ msgstr ""
983
  msgid "Default Value"
984
  msgstr ""
985
 
986
- #: includes/fields/class-base.php:435
987
  msgid "Select the default form field size."
988
  msgstr ""
989
 
990
- #: includes/fields/class-base.php:437
991
  msgid "Small"
992
  msgstr ""
993
 
994
- #: includes/fields/class-base.php:438
995
  msgid "Medium"
996
  msgstr ""
997
 
998
- #: includes/fields/class-base.php:439
999
  msgid "Large"
1000
  msgstr ""
1001
 
1002
- #: includes/fields/class-base.php:441
1003
  msgid "Field Size"
1004
  msgstr ""
1005
 
1006
- #: includes/fields/class-base.php:454
1007
  msgid "Advanced Options"
1008
  msgstr ""
1009
 
1010
- #: includes/fields/class-base.php:465
1011
  msgid "Enter text for the form field placeholder."
1012
  msgstr ""
1013
 
1014
- #: includes/fields/class-base.php:466
1015
  msgid "Placeholder Text"
1016
  msgstr ""
1017
 
1018
- #: includes/fields/class-base.php:475
1019
  msgid ""
1020
  "Enter CSS class names for the form field container. Class names should be "
1021
  "separated with spaces."
1022
  msgstr ""
1023
 
1024
- #: includes/fields/class-base.php:477
1025
  msgid "CSS Classes"
1026
  msgstr ""
1027
 
1028
- #: includes/fields/class-base.php:486
1029
  msgid "Check this option to hide the form field label."
1030
  msgstr ""
1031
 
1032
- #: includes/fields/class-base.php:488
1033
  msgid "Hide Label"
1034
  msgstr ""
1035
 
1036
- #: includes/fields/class-base.php:496
1037
  msgid "Check this option to hide the form field sub-label."
1038
  msgstr ""
1039
 
1040
- #: includes/fields/class-base.php:498
1041
  msgid "Hide Sub-Labels"
1042
  msgstr ""
1043
 
1044
- #: includes/fields/class-base.php:506
1045
  msgid "Select the layout for displaying field choices."
1046
  msgstr ""
1047
 
1048
- #: includes/fields/class-base.php:508
1049
  msgid "One Column"
1050
  msgstr ""
1051
 
1052
- #: includes/fields/class-base.php:509
1053
  msgid "Two Columns"
1054
  msgstr ""
1055
 
1056
- #: includes/fields/class-base.php:510
1057
  msgid "Three Columns"
1058
  msgstr ""
1059
 
1060
- #: includes/fields/class-base.php:512
1061
  msgid "Choice Layout"
1062
  msgstr ""
1063
 
1064
- #: includes/fields/class-base.php:521
1065
  msgid "Select auto-populate method to use."
1066
  msgstr ""
1067
 
1068
- #: includes/fields/class-base.php:524 includes/fields/class-base.php:543
1069
  msgid "Post Type"
1070
  msgstr ""
1071
 
1072
- #: includes/fields/class-base.php:525 includes/fields/class-base.php:549
1073
  msgid "Taxonomy"
1074
  msgstr ""
1075
 
1076
- #: includes/fields/class-base.php:527
1077
  msgid "Dynamic Choices"
1078
  msgstr ""
1079
 
1080
- #: includes/fields/class-base.php:554
1081
  msgid "Select %s to use for auto-populating field choices."
1082
  msgstr ""
1083
 
1084
- #: includes/fields/class-base.php:555
1085
  msgid "Dynamic %s Source"
1086
  msgstr ""
1087
 
1088
- #: includes/fields/class-base.php:671
1089
  msgid "No form ID found"
1090
  msgstr ""
1091
 
1092
- #: includes/fields/class-base.php:675
1093
  msgid "No field type found"
1094
  msgstr ""
1095
 
1096
- #: includes/fields/class-base.php:751 includes/fields/class-name.php:311
1097
  #: includes/fields/class-number.php:127
1098
  #: pro/includes/fields/class-address.php:624
1099
  #: pro/includes/fields/class-date-time.php:532
1100
- #: pro/includes/fields/class-file-upload.php:359
1101
  #: pro/includes/fields/class-password.php:296
1102
  #: pro/includes/fields/class-password.php:304
1103
  #: pro/includes/fields/class-password.php:309
1104
- #: pro/includes/fields/class-payment-multiple.php:177
 
1105
  #: pro/includes/fields/class-payment-single.php:189
1106
  #: pro/includes/fields/class-url.php:126
1107
  msgid "This field is required"
@@ -1148,8 +1166,8 @@ msgstr ""
1148
 
1149
  #: includes/fields/class-email.php:21 includes/fields/class-email.php:161
1150
  #: includes/fields/class-email.php:241
1151
- #: lite/includes/admin/class-settings.php:235
1152
- #: pro/includes/admin/class-settings.php:300
1153
  #: pro/includes/templates/class-donation.php:42
1154
  #: pro/includes/templates/class-order.php:42
1155
  #: pro/includes/templates/class-request-quote.php:46
@@ -1165,13 +1183,11 @@ msgstr ""
1165
  msgid "Check this option ask the user to provide their email address twice."
1166
  msgstr ""
1167
 
1168
- #: includes/fields/class-email.php:93
1169
- #: pro/includes/fields/class-password.php:91
1170
  msgid "Confirmation Placeholder Text"
1171
  msgstr ""
1172
 
1173
- #: includes/fields/class-email.php:94
1174
- #: pro/includes/fields/class-password.php:92
1175
  msgid "Enter text for the confirmation field placeholder."
1176
  msgstr ""
1177
 
@@ -1199,8 +1215,7 @@ msgstr ""
1199
  msgid "First Middle Last"
1200
  msgstr ""
1201
 
1202
- #: includes/fields/class-name.php:53
1203
- #: pro/includes/fields/class-date-time.php:56
1204
  #: pro/includes/fields/class-date-time.php:132
1205
  #: pro/includes/fields/class-date-time.php:168
1206
  #: pro/includes/fields/class-phone.php:50
@@ -1435,193 +1450,210 @@ msgstr ""
1435
 
1436
  #: lite/includes/admin/class-settings.php:176
1437
  #: pro/includes/admin/class-settings.php:183
1438
- #: pro/includes/admin/class-settings.php:393
1439
  msgid "Settings check failed."
1440
  msgstr ""
1441
 
1442
- #: lite/includes/admin/class-settings.php:196
1443
- #: pro/includes/admin/class-settings.php:203
1444
  msgid "General settings updated."
1445
  msgstr ""
1446
 
1447
- #: lite/includes/admin/class-settings.php:212
1448
- #: pro/includes/admin/class-settings.php:277
1449
  msgid "Include Form Styling"
1450
  msgstr ""
1451
 
1452
- #: lite/includes/admin/class-settings.php:216
1453
- #: pro/includes/admin/class-settings.php:281
1454
- msgid "Base and form theme styling"
1455
- msgstr ""
1456
-
1457
  #: lite/includes/admin/class-settings.php:217
1458
  #: pro/includes/admin/class-settings.php:282
1459
- msgid "Base styling only"
1460
  msgstr ""
1461
 
1462
  #: lite/includes/admin/class-settings.php:218
1463
  #: pro/includes/admin/class-settings.php:283
 
 
 
 
 
1464
  #: pro/includes/fields/class-page-break.php:58
1465
  msgid "None"
1466
  msgstr ""
1467
 
1468
- #: lite/includes/admin/class-settings.php:220
1469
- #: pro/includes/admin/class-settings.php:285
1470
  msgid "Determines which CSS files to load for the site."
1471
  msgstr ""
1472
 
1473
- #: lite/includes/admin/class-settings.php:225
1474
- #: pro/includes/admin/class-settings.php:290
1475
  msgid "Load Assets Globally"
1476
  msgstr ""
1477
 
1478
- #: lite/includes/admin/class-settings.php:229
1479
- #: pro/includes/admin/class-settings.php:294
1480
  msgid ""
1481
  "Check this if you would like to load WPForms assets site-wide. Only check if "
1482
  "your site is having compatibility issues or instructed to by support."
1483
  msgstr ""
1484
 
1485
- #: lite/includes/admin/class-settings.php:240
1486
- #: pro/includes/admin/class-settings.php:305
1487
  msgid "Email Template"
1488
  msgstr ""
1489
 
1490
- #: lite/includes/admin/class-settings.php:244
1491
- #: pro/includes/admin/class-settings.php:309
1492
  msgid "Default HTML template"
1493
  msgstr ""
1494
 
1495
- #: lite/includes/admin/class-settings.php:245
1496
- #: pro/includes/admin/class-settings.php:310
1497
  msgid "Plain Text"
1498
  msgstr ""
1499
 
1500
- #: lite/includes/admin/class-settings.php:247
1501
- #: pro/includes/admin/class-settings.php:312
1502
  msgid "Determines how email notifications will be formatted."
1503
  msgstr ""
1504
 
1505
- #: lite/includes/admin/class-settings.php:252
1506
- #: pro/includes/admin/class-settings.php:317
1507
  msgid "Email Header Image "
1508
  msgstr ""
1509
 
1510
- #: lite/includes/admin/class-settings.php:264
1511
- #: pro/includes/admin/class-settings.php:329
1512
  msgid "Upload Image"
1513
  msgstr ""
1514
 
1515
- #: lite/includes/admin/class-settings.php:266
1516
- #: pro/includes/admin/class-settings.php:331
1517
  msgid ""
1518
  "Upload or choose a logo to be displayed at the top of email notifications."
1519
  msgstr ""
1520
 
1521
- #: lite/includes/admin/class-settings.php:267
1522
- #: pro/includes/admin/class-settings.php:332
1523
  msgid "Recommended size is 300x100 or smaller for best support on all devices."
1524
  msgstr ""
1525
 
1526
- #: lite/includes/admin/class-settings.php:273
1527
- #: pro/includes/admin/class-settings.php:338
1528
  msgid "Email Background Color"
1529
  msgstr ""
1530
 
1531
- #: lite/includes/admin/class-settings.php:277
1532
- #: pro/includes/admin/class-settings.php:342
1533
  msgid "Customize the background color of the HTML email template."
1534
  msgstr ""
1535
 
1536
  #: lite/includes/admin/class-settings.php:283
1537
  #: pro/includes/admin/class-settings.php:348
 
 
 
 
 
 
 
 
 
 
 
 
1538
  msgid "reCAPTCHA"
1539
  msgstr ""
1540
 
1541
- #: lite/includes/admin/class-settings.php:284
1542
- #: pro/includes/admin/class-settings.php:349
1543
  msgid ""
1544
  "reCAPTCHA is a free anti-spam service from Google. Its helps protect your "
1545
  "website from spam and abuse while letting real people pass through with "
1546
  "ease. <a href=\"http://www.google.com/recaptcha/intro/index.html\" target="
1547
- "\"_blank\">Visit reCAPTCHA</a> to learn more and sign up for a free account "
1548
- "or <a href=\"https://wpforms.com/docs/setup-captcha-wpforms/\" target="
1549
- "\"_blank\">read our walk through</a> for step-by-step directions."
 
1550
  msgstr ""
1551
 
1552
- #: lite/includes/admin/class-settings.php:289
1553
- #: pro/includes/admin/class-settings.php:354
1554
  msgid "reCAPTCHA Site key"
1555
  msgstr ""
1556
 
1557
- #: lite/includes/admin/class-settings.php:297
1558
- #: pro/includes/admin/class-settings.php:362
1559
  msgid "reCAPTCHA Secret key"
1560
  msgstr ""
1561
 
1562
- #: lite/includes/admin/class-settings.php:306
1563
- #: pro/includes/admin/class-settings.php:371
1564
  msgid "Save General Settings"
1565
  msgstr ""
1566
 
1567
- #: lite/includes/admin/class-settings.php:418
1568
- #: lite/includes/admin/class-settings.php:422
1569
- #: pro/includes/admin/class-settings.php:726
1570
- #: pro/includes/admin/class-settings.php:730
1571
  #: pro/includes/admin/entries/class-entries.php:1088
1572
  msgid "M j, Y @ g:ia"
1573
  msgstr ""
1574
 
1575
- #: lite/wpforms-lite.php:83 pro/wpforms-pro.php:265
1576
  msgid "Default Notification"
1577
  msgstr ""
1578
 
1579
- #: lite/wpforms-lite.php:91 pro/wpforms-pro.php:280
1580
  msgid "Send To Email Address"
1581
  msgstr ""
1582
 
1583
- #: lite/wpforms-lite.php:94 pro/wpforms-pro.php:283
1584
  msgid ""
1585
  "Enter the email address to receive form entry notifications. For multiple "
1586
  "notifications, separate email addresses with a comma."
1587
  msgstr ""
1588
 
1589
- #: lite/wpforms-lite.php:109 pro/wpforms-pro.php:298
 
 
 
 
1590
  msgid "Email Subject"
1591
  msgstr ""
1592
 
1593
- #: lite/wpforms-lite.php:111 pro/wpforms-pro.php:300
1594
  msgid "New Entry: "
1595
  msgstr ""
1596
 
1597
- #: lite/wpforms-lite.php:125 pro/wpforms-pro.php:314
1598
  msgid "From Name"
1599
  msgstr ""
1600
 
1601
- #: lite/wpforms-lite.php:141 pro/wpforms-pro.php:330
1602
  msgid "From Email"
1603
  msgstr ""
1604
 
1605
- #: lite/wpforms-lite.php:157 pro/wpforms-pro.php:346
1606
  msgid "Reply-To"
1607
  msgstr ""
1608
 
1609
- #: lite/wpforms-lite.php:182 pro/wpforms-pro.php:371
1610
  msgid ""
1611
  "To display all form fields, use the <code>{all_fields}</code> Smart Tag."
1612
  msgstr ""
1613
 
1614
- #: lite/wpforms-lite.php:414
1615
  msgid "is a PRO Feature"
1616
  msgstr ""
1617
 
1618
- #: lite/wpforms-lite.php:415
1619
  msgid ""
1620
  "We're sorry, %name% is not available on your plan.<br><br>Please upgrade to "
1621
  "the PRO plan to unlock all these awesome features."
1622
  msgstr ""
1623
 
1624
- #: lite/wpforms-lite.php:416
1625
  msgid "Upgrade to PRO"
1626
  msgstr ""
1627
 
@@ -1837,9 +1869,9 @@ msgstr ""
1837
 
1838
  #: pro/includes/admin/class-license.php:288
1839
  msgid ""
1840
- "Your license key for WPForms has expired. <a href=\"%s\" target=\"_blank"
1841
- "\">Please click here to renew your license key and continue receiving "
1842
- "automatic updates.</a>"
1843
  msgstr ""
1844
 
1845
  #: pro/includes/admin/class-license.php:297
@@ -1867,114 +1899,114 @@ msgstr ""
1867
  msgid "System Info"
1868
  msgstr ""
1869
 
1870
- #: pro/includes/admin/class-settings.php:210
1871
  msgid "Please enter a license key to verify."
1872
  msgstr ""
1873
 
1874
- #: pro/includes/admin/class-settings.php:240
1875
  msgid "License"
1876
  msgstr ""
1877
 
1878
- #: pro/includes/admin/class-settings.php:241
1879
  msgid "Your license key provides access to updates and Add-ons. "
1880
  msgstr ""
1881
 
1882
- #: pro/includes/admin/class-settings.php:246
1883
  msgid "License Key"
1884
  msgstr ""
1885
 
1886
- #: pro/includes/admin/class-settings.php:250
1887
  msgid "Verify Key"
1888
  msgstr ""
1889
 
1890
- #: pro/includes/admin/class-settings.php:252
1891
  msgid "Deactivate Key"
1892
  msgstr ""
1893
 
1894
- #: pro/includes/admin/class-settings.php:260
1895
  msgid "License Key Type"
1896
  msgstr ""
1897
 
1898
- #: pro/includes/admin/class-settings.php:263
1899
  msgid "Your license key type for this site is <strong>%s.</strong>"
1900
  msgstr ""
1901
 
1902
- #: pro/includes/admin/class-settings.php:264
1903
  msgid "Refresh Key"
1904
  msgstr ""
1905
 
1906
- #: pro/includes/admin/class-settings.php:265
1907
  msgid ""
1908
  "If your license has been upgraded or is incorrect, you may force a refresh."
1909
  msgstr ""
1910
 
1911
- #: pro/includes/admin/class-settings.php:404
1912
  msgid "Settings updated."
1913
  msgstr ""
1914
 
1915
- #: pro/includes/admin/class-settings.php:418
1916
  msgid "Currency"
1917
  msgstr ""
1918
 
1919
- #: pro/includes/admin/class-settings.php:430
1920
  msgid "Determines which currency to use for payments."
1921
  msgstr ""
1922
 
1923
- #: pro/includes/admin/class-settings.php:461
1924
  msgid ""
1925
  "You do not have any marketing add-ons activated. You can head over to the <a "
1926
  "href=\"%s\">Add-Ons page</a> to install and activate the add-on for your "
1927
  "provider."
1928
  msgstr ""
1929
 
1930
- #: pro/includes/admin/class-settings.php:482
1931
  msgid "Form(s) imported"
1932
  msgstr ""
1933
 
1934
- #: pro/includes/admin/class-settings.php:491
1935
  msgid "Form Import"
1936
  msgstr ""
1937
 
1938
- #: pro/includes/admin/class-settings.php:496
1939
  msgid "Select an export file."
1940
  msgstr ""
1941
 
1942
- #: pro/includes/admin/class-settings.php:502
1943
  msgid "Import"
1944
  msgstr ""
1945
 
1946
- #: pro/includes/admin/class-settings.php:509
1947
  msgid "Form Export"
1948
  msgstr ""
1949
 
1950
- #: pro/includes/admin/class-settings.php:514
1951
  msgid ""
1952
  "Select form(s) to download an export file. This can be imported into another "
1953
  "site."
1954
  msgstr ""
1955
 
1956
- #: pro/includes/admin/class-settings.php:530
1957
  msgid "Export"
1958
  msgstr ""
1959
 
1960
- #: pro/includes/admin/class-settings.php:590
1961
  msgid "Please upload a valid .json form export file."
1962
  msgstr ""
1963
 
1964
- #: pro/includes/admin/class-settings.php:590
1965
- #: pro/includes/admin/entries/class-entries-export.php:299
1966
  msgid "Error"
1967
  msgstr ""
1968
 
1969
- #: pro/includes/admin/entries/class-entries-export.php:173
1970
  msgid "Date GMT"
1971
  msgstr ""
1972
 
1973
- #: pro/includes/admin/entries/class-entries-export.php:174
1974
  msgid "ID"
1975
  msgstr ""
1976
 
1977
- #: pro/includes/admin/entries/class-entries-export.php:299
1978
  msgid "You do not have permission to export entries."
1979
  msgstr ""
1980
 
@@ -2004,97 +2036,97 @@ msgstr ""
2004
  msgid "Actions"
2005
  msgstr ""
2006
 
2007
- #: pro/includes/admin/entries/class-entries-table.php:256
2008
  #: pro/includes/admin/entries/class-entries.php:1156
2009
  msgid "Unknown"
2010
  msgstr ""
2011
 
2012
- #: pro/includes/admin/entries/class-entries-table.php:295
2013
  #: pro/includes/admin/entries/class-entries.php:243
2014
  msgid "Unstar entry"
2015
  msgstr ""
2016
 
2017
- #: pro/includes/admin/entries/class-entries-table.php:295
2018
  #: pro/includes/admin/entries/class-entries.php:244
2019
  msgid "Star entry"
2020
  msgstr ""
2021
 
2022
- #: pro/includes/admin/entries/class-entries-table.php:300
2023
  #: pro/includes/admin/entries/class-entries.php:246
2024
  msgid "Mark entry unread"
2025
  msgstr ""
2026
 
2027
- #: pro/includes/admin/entries/class-entries-table.php:300
2028
  #: pro/includes/admin/entries/class-entries.php:245
2029
  msgid "Mark entry read"
2030
  msgstr ""
2031
 
2032
- #: pro/includes/admin/entries/class-entries-table.php:320
2033
  msgid "View Form Entry"
2034
  msgstr ""
2035
 
2036
- #: pro/includes/admin/entries/class-entries-table.php:321
2037
  msgid "View"
2038
  msgstr ""
2039
 
2040
- #: pro/includes/admin/entries/class-entries-table.php:327
2041
  msgid "Delete Form Entry"
2042
  msgstr ""
2043
 
2044
- #: pro/includes/admin/entries/class-entries-table.php:343
2045
  msgid "Mark Read"
2046
  msgstr ""
2047
 
2048
- #: pro/includes/admin/entries/class-entries-table.php:344
2049
  #: pro/includes/admin/entries/class-entries.php:1336
2050
  msgid "Mark Unread"
2051
  msgstr ""
2052
 
2053
- #: pro/includes/admin/entries/class-entries-table.php:345
2054
  #: pro/includes/admin/entries/class-entries.php:1288
2055
  msgid "Star"
2056
  msgstr ""
2057
 
2058
- #: pro/includes/admin/entries/class-entries-table.php:346
2059
  #: pro/includes/admin/entries/class-entries.php:1288
2060
  msgid "Unstar"
2061
  msgstr ""
2062
 
2063
- #: pro/includes/admin/entries/class-entries-table.php:348
2064
  msgid "----------"
2065
  msgstr ""
2066
 
2067
- #: pro/includes/admin/entries/class-entries-table.php:392
2068
  msgid "Entry marked as read."
2069
  msgid_plural "Entries marked as read."
2070
  msgstr[0] ""
2071
  msgstr[1] ""
2072
 
2073
- #: pro/includes/admin/entries/class-entries-table.php:401
2074
  msgid "Entry marked as unread."
2075
  msgid_plural "Entries marked as unread."
2076
  msgstr[0] ""
2077
  msgstr[1] ""
2078
 
2079
- #: pro/includes/admin/entries/class-entries-table.php:410
2080
  msgid "Entry starred."
2081
  msgid_plural "Entries starred."
2082
  msgstr[0] ""
2083
  msgstr[1] ""
2084
 
2085
- #: pro/includes/admin/entries/class-entries-table.php:419
2086
  msgid "Entry unstarred."
2087
  msgid_plural "Entries unstarred."
2088
  msgstr[0] ""
2089
  msgstr[1] ""
2090
 
2091
- #: pro/includes/admin/entries/class-entries-table.php:428
2092
  msgid "Entry successfully deleted."
2093
  msgid_plural "Entries successfully deleted."
2094
  msgstr[0] ""
2095
  msgstr[1] ""
2096
 
2097
- #: pro/includes/admin/entries/class-entries-table.php:442
2098
  msgid "Whoops, it appears you do not have any form entries yet."
2099
  msgstr ""
2100
 
@@ -2562,61 +2594,61 @@ msgid ""
2562
  "defaults to the maximum size the server allows which is "
2563
  msgstr ""
2564
 
2565
- #: pro/includes/fields/class-file-upload.php:208
2566
  msgid "Store file in WordPress Media Library"
2567
  msgstr ""
2568
 
2569
- #: pro/includes/fields/class-file-upload.php:209
2570
  msgid ""
2571
  "Check this option to store the final uploaded file in the WordPress Media "
2572
  "Library"
2573
  msgstr ""
2574
 
2575
- #: pro/includes/fields/class-file-upload.php:341
2576
  msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
2577
  msgstr ""
2578
 
2579
- #: pro/includes/fields/class-file-upload.php:342
2580
  msgid ""
2581
  "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
2582
  "the HTML form."
2583
  msgstr ""
2584
 
2585
- #: pro/includes/fields/class-file-upload.php:343
2586
  msgid "The uploaded file was only partially uploaded."
2587
  msgstr ""
2588
 
2589
- #: pro/includes/fields/class-file-upload.php:344
2590
  msgid "No file was uploaded."
2591
  msgstr ""
2592
 
2593
- #: pro/includes/fields/class-file-upload.php:346
2594
  msgid "Missing a temporary folder."
2595
  msgstr ""
2596
 
2597
- #: pro/includes/fields/class-file-upload.php:347
2598
  msgid "Failed to write file to disk."
2599
  msgstr ""
2600
 
2601
- #: pro/includes/fields/class-file-upload.php:348
2602
  msgid "File upload stopped by extension."
2603
  msgstr ""
2604
 
2605
- #: pro/includes/fields/class-file-upload.php:350
2606
  msgid "File upload error. "
2607
  msgstr ""
2608
 
2609
- #: pro/includes/fields/class-file-upload.php:369
2610
  msgid "File exceeds max size allowed"
2611
  msgstr ""
2612
 
2613
- #: pro/includes/fields/class-file-upload.php:387
2614
  msgid "File must have an extension."
2615
  msgstr ""
2616
 
2617
- #: pro/includes/fields/class-file-upload.php:397
2618
- #: pro/includes/fields/class-file-upload.php:416
2619
- #: pro/includes/fields/class-file-upload.php:434
2620
  msgid "File type is not allowed."
2621
  msgstr ""
2622
 
@@ -2805,35 +2837,35 @@ msgstr ""
2805
  msgid "YY"
2806
  msgstr ""
2807
 
2808
- #: pro/includes/fields/class-payment-multiple.php:21
2809
- msgid "Multiple Items"
2810
  msgstr ""
2811
 
 
2812
  #: pro/includes/fields/class-payment-multiple.php:28
2813
  #: pro/includes/templates/class-order.php:70
2814
  msgid "First Item"
2815
  msgstr ""
2816
 
 
2817
  #: pro/includes/fields/class-payment-multiple.php:33
2818
  #: pro/includes/templates/class-order.php:74
2819
  msgid "Second Item"
2820
  msgstr ""
2821
 
 
2822
  #: pro/includes/fields/class-payment-multiple.php:38
2823
  #: pro/includes/templates/class-order.php:78
2824
  msgid "Third Item"
2825
  msgstr ""
2826
 
2827
- #: pro/includes/fields/class-payment-multiple.php:61
2828
- msgid "Add item choices for the form field."
2829
- msgstr ""
2830
-
2831
- #: pro/includes/fields/class-payment-multiple.php:64
2832
- msgid "Items"
2833
  msgstr ""
2834
 
2835
- #: pro/includes/fields/class-payment-multiple.php:182
2836
- msgid "Invalid payment option"
2837
  msgstr ""
2838
 
2839
  #: pro/includes/fields/class-payment-single.php:21
@@ -3076,27 +3108,27 @@ msgstr ""
3076
  msgid "Disable storing entry information in WordPress"
3077
  msgstr ""
3078
 
3079
- #: pro/wpforms-pro.php:245
3080
  msgid "Add New Notification"
3081
  msgstr ""
3082
 
3083
- #: pro/wpforms-pro.php:384
3084
  msgid "Send"
3085
  msgstr ""
3086
 
3087
- #: pro/wpforms-pro.php:385
3088
  msgid "Don't send"
3089
  msgstr ""
3090
 
3091
- #: pro/wpforms-pro.php:387
3092
  msgid "this notification if"
3093
  msgstr ""
3094
 
3095
- #: pro/wpforms-pro.php:388
3096
  msgid "Email notifications"
3097
  msgstr ""
3098
 
3099
- #: pro/wpforms-pro.php:391
3100
  msgid ""
3101
  "Install the <a href=\"%s\">Conditional Logic add-on</a> to enable "
3102
  "conditional logic for Email Notifications."
@@ -3106,9 +3138,9 @@ msgstr ""
3106
  msgid "Please deactivate WPForms Lite before activating WPForms"
3107
  msgstr ""
3108
 
3109
- #. #-#-#-#-# wpforms.pot (WPForms 1.3.0) #-#-#-#-#
3110
  #. Plugin URI of the plugin/theme
3111
- #. #-#-#-#-# wpforms.pot (WPForms 1.3.0) #-#-#-#-#
3112
  #. Author URI of the plugin/theme
3113
  msgid "https://wpforms.com"
3114
  msgstr ""
2
  # This file is distributed under the same license as the WPForms package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WPForms 1.3.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wpforms\n"
7
+ "POT-Creation-Date: 2016-12-07 22:26:51+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: includes/admin/ajax-actions.php:24 includes/fields/class-base.php:714
16
  msgid "You do no have permission."
17
  msgstr ""
18
 
211
  msgstr ""
212
 
213
  #: includes/admin/builder/class-builder.php:301
214
+ #: includes/fields/class-base.php:239 includes/fields/class-base.php:570
215
+ #: lite/wpforms-lite.php:77 pro/wpforms-pro.php:260
216
  msgid "Off"
217
  msgstr ""
218
 
219
  #: includes/admin/builder/class-builder.php:302
220
+ #: includes/fields/class-base.php:239 lite/wpforms-lite.php:76
221
+ #: pro/wpforms-pro.php:259
222
  msgid "On"
223
  msgstr ""
224
 
227
  msgid "Other"
228
  msgstr ""
229
 
230
+ #: includes/admin/builder/class-builder.php:304 includes/class-frontend.php:492
 
231
  #: pro/includes/fields/class-page-break.php:144
232
  msgid "Previous"
233
  msgstr ""
234
 
235
  #: includes/admin/builder/class-builder.php:307
236
+ #: includes/admin/builder/functions.php:210 includes/fields/class-base.php:471
237
  msgid "Show Smart Tags"
238
  msgstr ""
239
 
277
  msgstr ""
278
 
279
  #: includes/admin/builder/class-builder.php:391
280
+ #: pro/includes/admin/class-settings.php:451
281
  msgid "Save"
282
  msgstr ""
283
 
329
  msgstr ""
330
 
331
  #: includes/admin/builder/panels/class-fields.php:252
332
+ #: includes/fields/class-base.php:750
333
  msgid "Duplicate Field"
334
  msgstr ""
335
 
336
  #: includes/admin/builder/panels/class-fields.php:254
337
+ #: includes/fields/class-base.php:751
338
  msgid "Delete Field"
339
  msgstr ""
340
 
341
  #: includes/admin/builder/panels/class-fields.php:256
342
+ #: includes/fields/class-base.php:752
343
  msgid "Click to edit. Drag to reorder."
344
  msgstr ""
345
 
346
  #: includes/admin/builder/panels/class-settings.php:21
347
+ #: includes/admin/class-menu.php:84 lite/includes/admin/class-settings.php:398
348
+ #: pro/includes/admin/class-settings.php:706
349
  msgid "Settings"
350
  msgstr ""
351
 
356
  msgid "General"
357
  msgstr ""
358
 
359
+ #: includes/admin/builder/panels/class-settings.php:58 lite/wpforms-lite.php:62
360
+ #: lite/wpforms-lite.php:72 pro/wpforms-pro.php:246 pro/wpforms-pro.php:255
 
361
  msgid "Notifications"
362
  msgstr ""
363
 
364
  #: includes/admin/builder/panels/class-settings.php:59
365
+ #: includes/admin/builder/panels/class-settings.php:176
366
  msgid "Confirmation"
367
  msgstr ""
368
 
426
  msgid "Enable reCAPTCHA"
427
  msgstr ""
428
 
429
+ #: includes/admin/builder/panels/class-settings.php:183
430
  msgid "Confirmation Type"
431
  msgstr ""
432
 
433
+ #: includes/admin/builder/panels/class-settings.php:187
434
+ #: includes/templates/class-suggestion.php:74 lite/wpforms-lite.php:191
435
+ #: pro/wpforms-pro.php:380
436
  msgid "Message"
437
  msgstr ""
438
 
439
+ #: includes/admin/builder/panels/class-settings.php:188
440
  msgid "Show Page"
441
  msgstr ""
442
 
443
+ #: includes/admin/builder/panels/class-settings.php:189
444
  msgid "Go to URL (Redirect)"
445
  msgstr ""
446
 
447
+ #: includes/admin/builder/panels/class-settings.php:198
448
  msgid "Confirmation Message"
449
  msgstr ""
450
 
451
+ #: includes/admin/builder/panels/class-settings.php:200
452
  msgid "Thanks for contacting us! We will be in touch with you shortly."
453
  msgstr ""
454
 
455
+ #: includes/admin/builder/panels/class-settings.php:211
456
  msgid "Automatically scroll to the confirmation message"
457
  msgstr ""
458
 
459
+ #: includes/admin/builder/panels/class-settings.php:224
460
  msgid "Confirmation Page"
461
  msgstr ""
462
 
463
+ #: includes/admin/builder/panels/class-settings.php:232
464
  msgid "Confirmation Redirect URL"
465
  msgstr ""
466
 
529
  "a>?"
530
  msgstr ""
531
 
532
+ #. #-#-#-#-# wpforms.pot (WPForms 1.3.1) #-#-#-#-#
533
  #. Plugin Name of the plugin/theme
534
+ #. #-#-#-#-# wpforms.pot (WPForms 1.3.1) #-#-#-#-#
535
  #. Author of the plugin/theme
536
  #: includes/admin/class-menu.php:39 includes/admin/class-menu.php:40
537
  #: includes/admin/class-menu.php:51 includes/integrations.php:34
576
 
577
  #: includes/admin/class-menu.php:134
578
  msgid ""
579
+ "Please rate <strong>WPForms</strong> <a href=\"%s\" target=\"_blank\" rel="
580
+ "\"noopener\">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href=\"%s\" "
581
+ "target=\"_blank\">WordPress.org</a> to help us spread the word. Thank you "
582
+ "from the WPForms team!"
583
  msgstr ""
584
 
585
  #: includes/admin/class-welcome.php:40 includes/admin/class-welcome.php:41
617
  #: includes/admin/class-welcome.php:121
618
  msgid ""
619
  "WPForms make it easy to create forms in WordPress. You can follow the video "
620
+ "tutorial on the right or read our how to <a href=\"%s\" target=\"_blank\" "
621
+ "rel=\"noopener\">create your first form guide</a>."
622
  msgstr ""
623
 
624
  #: includes/admin/class-welcome.php:122
691
 
692
  #: includes/admin/overview/class-overview-table.php:173
693
  #: includes/admin/overview/class-overview-table.php:191
694
+ #: pro/includes/admin/entries/class-entries-table.php:325
695
+ #: pro/includes/admin/entries/class-entries-table.php:346
696
  #: pro/includes/admin/entries/class-entries.php:1013
697
  msgid "Delete"
698
  msgstr ""
797
  msgid "Invalid form."
798
  msgstr ""
799
 
800
+ #: includes/class-process.php:111
801
  msgid "Incorrect reCAPTCHA, please try again."
802
  msgstr ""
803
 
804
+ #: includes/class-process.php:114
805
+ msgid "reCAPTCHA is required."
806
+ msgstr ""
807
+
808
+ #: includes/class-process.php:120 includes/class-process.php:163
809
  msgid "Form has not been submitted, please see the errors below."
810
  msgstr ""
811
 
812
+ #: includes/class-process.php:127
813
  msgid "WPForms honeypot field triggered."
814
  msgstr ""
815
 
816
+ #: includes/class-process.php:339 lite/wpforms-lite.php:54
817
+ #: pro/wpforms-pro.php:239
818
  msgid "New %s Entry"
819
  msgstr ""
820
 
843
  msgstr ""
844
 
845
  #: includes/class-smart-tags.php:40
846
+ #: pro/includes/admin/entries/class-entries-export.php:173
847
  #: pro/includes/admin/entries/class-entries-table.php:129
848
  #: pro/includes/fields/class-date-time.php:69
849
  #: pro/includes/fields/class-date-time.php:117
874
  msgstr ""
875
 
876
  #: includes/class-smart-tags.php:46
877
+ msgid "Author ID"
878
  msgstr ""
879
 
880
  #: includes/class-smart-tags.php:47
881
+ msgid "Author Name"
882
  msgstr ""
883
 
884
  #: includes/class-smart-tags.php:48
885
+ msgid "Author Email"
886
  msgstr ""
887
 
888
  #: includes/class-smart-tags.php:49
889
+ msgid "Referer URL"
890
  msgstr ""
891
 
892
  #: includes/class-smart-tags.php:50
893
+ msgid "Login URL"
894
+ msgstr ""
895
+
896
+ #: includes/class-smart-tags.php:51
897
+ msgid "Logout URL"
898
+ msgstr ""
899
+
900
+ #: includes/class-smart-tags.php:52
901
+ msgid "Register URL"
902
+ msgstr ""
903
+
904
+ #: includes/class-smart-tags.php:53
905
  msgid "Lost Password URL"
906
  msgstr ""
907
 
908
+ #: includes/class-widget.php:127 pro/includes/admin/class-settings.php:534
909
  msgid "No forms"
910
  msgstr ""
911
 
917
  msgid "Display form description"
918
  msgstr ""
919
 
920
+ #: includes/emails/class-emails.php:296
921
  msgid ""
922
  "You cannot send emails with WPForms_WP_Emails until init/admin_init has been "
923
  "reached"
924
  msgstr ""
925
 
926
+ #: includes/emails/class-emails.php:421 includes/emails/class-emails.php:443
927
  msgid "Field ID #"
928
  msgstr ""
929
 
967
  msgid "Code"
968
  msgstr ""
969
 
970
+ #: includes/fields/class-base.php:347 includes/fields/class-base.php:419
971
  msgid "Add choices for the form field."
972
  msgstr ""
973
 
981
  "span> <span class=\"dynamic-type\">%s</span>"
982
  msgstr ""
983
 
984
+ #: includes/fields/class-base.php:428
985
+ msgid "Items"
986
+ msgstr ""
987
+
988
+ #: includes/fields/class-base.php:470
989
  msgid "Enter text for the default form field value."
990
  msgstr ""
991
 
992
+ #: includes/fields/class-base.php:472 includes/fields/class-name.php:81
993
  #: includes/fields/class-name.php:96 includes/fields/class-name.php:111
994
+ #: includes/fields/class-name.php:126 pro/includes/fields/class-address.php:117
 
995
  #: pro/includes/fields/class-address.php:133
996
  #: pro/includes/fields/class-address.php:151
997
  #: pro/includes/fields/class-address.php:166
1000
  msgid "Default Value"
1001
  msgstr ""
1002
 
1003
+ #: includes/fields/class-base.php:482
1004
  msgid "Select the default form field size."
1005
  msgstr ""
1006
 
1007
+ #: includes/fields/class-base.php:484
1008
  msgid "Small"
1009
  msgstr ""
1010
 
1011
+ #: includes/fields/class-base.php:485
1012
  msgid "Medium"
1013
  msgstr ""
1014
 
1015
+ #: includes/fields/class-base.php:486
1016
  msgid "Large"
1017
  msgstr ""
1018
 
1019
+ #: includes/fields/class-base.php:488
1020
  msgid "Field Size"
1021
  msgstr ""
1022
 
1023
+ #: includes/fields/class-base.php:501
1024
  msgid "Advanced Options"
1025
  msgstr ""
1026
 
1027
+ #: includes/fields/class-base.php:512
1028
  msgid "Enter text for the form field placeholder."
1029
  msgstr ""
1030
 
1031
+ #: includes/fields/class-base.php:513
1032
  msgid "Placeholder Text"
1033
  msgstr ""
1034
 
1035
+ #: includes/fields/class-base.php:522
1036
  msgid ""
1037
  "Enter CSS class names for the form field container. Class names should be "
1038
  "separated with spaces."
1039
  msgstr ""
1040
 
1041
+ #: includes/fields/class-base.php:524
1042
  msgid "CSS Classes"
1043
  msgstr ""
1044
 
1045
+ #: includes/fields/class-base.php:533
1046
  msgid "Check this option to hide the form field label."
1047
  msgstr ""
1048
 
1049
+ #: includes/fields/class-base.php:535
1050
  msgid "Hide Label"
1051
  msgstr ""
1052
 
1053
+ #: includes/fields/class-base.php:543
1054
  msgid "Check this option to hide the form field sub-label."
1055
  msgstr ""
1056
 
1057
+ #: includes/fields/class-base.php:545
1058
  msgid "Hide Sub-Labels"
1059
  msgstr ""
1060
 
1061
+ #: includes/fields/class-base.php:553
1062
  msgid "Select the layout for displaying field choices."
1063
  msgstr ""
1064
 
1065
+ #: includes/fields/class-base.php:555
1066
  msgid "One Column"
1067
  msgstr ""
1068
 
1069
+ #: includes/fields/class-base.php:556
1070
  msgid "Two Columns"
1071
  msgstr ""
1072
 
1073
+ #: includes/fields/class-base.php:557
1074
  msgid "Three Columns"
1075
  msgstr ""
1076
 
1077
+ #: includes/fields/class-base.php:559
1078
  msgid "Choice Layout"
1079
  msgstr ""
1080
 
1081
+ #: includes/fields/class-base.php:568
1082
  msgid "Select auto-populate method to use."
1083
  msgstr ""
1084
 
1085
+ #: includes/fields/class-base.php:571 includes/fields/class-base.php:590
1086
  msgid "Post Type"
1087
  msgstr ""
1088
 
1089
+ #: includes/fields/class-base.php:572 includes/fields/class-base.php:596
1090
  msgid "Taxonomy"
1091
  msgstr ""
1092
 
1093
+ #: includes/fields/class-base.php:574
1094
  msgid "Dynamic Choices"
1095
  msgstr ""
1096
 
1097
+ #: includes/fields/class-base.php:601
1098
  msgid "Select %s to use for auto-populating field choices."
1099
  msgstr ""
1100
 
1101
+ #: includes/fields/class-base.php:602
1102
  msgid "Dynamic %s Source"
1103
  msgstr ""
1104
 
1105
+ #: includes/fields/class-base.php:718
1106
  msgid "No form ID found"
1107
  msgstr ""
1108
 
1109
+ #: includes/fields/class-base.php:722
1110
  msgid "No field type found"
1111
  msgstr ""
1112
 
1113
+ #: includes/fields/class-base.php:798 includes/fields/class-name.php:311
1114
  #: includes/fields/class-number.php:127
1115
  #: pro/includes/fields/class-address.php:624
1116
  #: pro/includes/fields/class-date-time.php:532
1117
+ #: pro/includes/fields/class-file-upload.php:356
1118
  #: pro/includes/fields/class-password.php:296
1119
  #: pro/includes/fields/class-password.php:304
1120
  #: pro/includes/fields/class-password.php:309
1121
+ #: pro/includes/fields/class-payment-dropdown.php:208
1122
+ #: pro/includes/fields/class-payment-multiple.php:175
1123
  #: pro/includes/fields/class-payment-single.php:189
1124
  #: pro/includes/fields/class-url.php:126
1125
  msgid "This field is required"
1166
 
1167
  #: includes/fields/class-email.php:21 includes/fields/class-email.php:161
1168
  #: includes/fields/class-email.php:241
1169
+ #: lite/includes/admin/class-settings.php:236
1170
+ #: pro/includes/admin/class-settings.php:301
1171
  #: pro/includes/templates/class-donation.php:42
1172
  #: pro/includes/templates/class-order.php:42
1173
  #: pro/includes/templates/class-request-quote.php:46
1183
  msgid "Check this option ask the user to provide their email address twice."
1184
  msgstr ""
1185
 
1186
+ #: includes/fields/class-email.php:93 pro/includes/fields/class-password.php:91
 
1187
  msgid "Confirmation Placeholder Text"
1188
  msgstr ""
1189
 
1190
+ #: includes/fields/class-email.php:94 pro/includes/fields/class-password.php:92
 
1191
  msgid "Enter text for the confirmation field placeholder."
1192
  msgstr ""
1193
 
1215
  msgid "First Middle Last"
1216
  msgstr ""
1217
 
1218
+ #: includes/fields/class-name.php:53 pro/includes/fields/class-date-time.php:56
 
1219
  #: pro/includes/fields/class-date-time.php:132
1220
  #: pro/includes/fields/class-date-time.php:168
1221
  #: pro/includes/fields/class-phone.php:50
1450
 
1451
  #: lite/includes/admin/class-settings.php:176
1452
  #: pro/includes/admin/class-settings.php:183
1453
+ #: pro/includes/admin/class-settings.php:403
1454
  msgid "Settings check failed."
1455
  msgstr ""
1456
 
1457
+ #: lite/includes/admin/class-settings.php:197
1458
+ #: pro/includes/admin/class-settings.php:204
1459
  msgid "General settings updated."
1460
  msgstr ""
1461
 
1462
+ #: lite/includes/admin/class-settings.php:213
1463
+ #: pro/includes/admin/class-settings.php:278
1464
  msgid "Include Form Styling"
1465
  msgstr ""
1466
 
 
 
 
 
 
1467
  #: lite/includes/admin/class-settings.php:217
1468
  #: pro/includes/admin/class-settings.php:282
1469
+ msgid "Base and form theme styling"
1470
  msgstr ""
1471
 
1472
  #: lite/includes/admin/class-settings.php:218
1473
  #: pro/includes/admin/class-settings.php:283
1474
+ msgid "Base styling only"
1475
+ msgstr ""
1476
+
1477
+ #: lite/includes/admin/class-settings.php:219
1478
+ #: pro/includes/admin/class-settings.php:284
1479
  #: pro/includes/fields/class-page-break.php:58
1480
  msgid "None"
1481
  msgstr ""
1482
 
1483
+ #: lite/includes/admin/class-settings.php:221
1484
+ #: pro/includes/admin/class-settings.php:286
1485
  msgid "Determines which CSS files to load for the site."
1486
  msgstr ""
1487
 
1488
+ #: lite/includes/admin/class-settings.php:226
1489
+ #: pro/includes/admin/class-settings.php:291
1490
  msgid "Load Assets Globally"
1491
  msgstr ""
1492
 
1493
+ #: lite/includes/admin/class-settings.php:230
1494
+ #: pro/includes/admin/class-settings.php:295
1495
  msgid ""
1496
  "Check this if you would like to load WPForms assets site-wide. Only check if "
1497
  "your site is having compatibility issues or instructed to by support."
1498
  msgstr ""
1499
 
1500
+ #: lite/includes/admin/class-settings.php:241
1501
+ #: pro/includes/admin/class-settings.php:306
1502
  msgid "Email Template"
1503
  msgstr ""
1504
 
1505
+ #: lite/includes/admin/class-settings.php:245
1506
+ #: pro/includes/admin/class-settings.php:310
1507
  msgid "Default HTML template"
1508
  msgstr ""
1509
 
1510
+ #: lite/includes/admin/class-settings.php:246
1511
+ #: pro/includes/admin/class-settings.php:311
1512
  msgid "Plain Text"
1513
  msgstr ""
1514
 
1515
+ #: lite/includes/admin/class-settings.php:248
1516
+ #: pro/includes/admin/class-settings.php:313
1517
  msgid "Determines how email notifications will be formatted."
1518
  msgstr ""
1519
 
1520
+ #: lite/includes/admin/class-settings.php:253
1521
+ #: pro/includes/admin/class-settings.php:318
1522
  msgid "Email Header Image "
1523
  msgstr ""
1524
 
1525
+ #: lite/includes/admin/class-settings.php:265
1526
+ #: pro/includes/admin/class-settings.php:330
1527
  msgid "Upload Image"
1528
  msgstr ""
1529
 
1530
+ #: lite/includes/admin/class-settings.php:267
1531
+ #: pro/includes/admin/class-settings.php:332
1532
  msgid ""
1533
  "Upload or choose a logo to be displayed at the top of email notifications."
1534
  msgstr ""
1535
 
1536
+ #: lite/includes/admin/class-settings.php:268
1537
+ #: pro/includes/admin/class-settings.php:333
1538
  msgid "Recommended size is 300x100 or smaller for best support on all devices."
1539
  msgstr ""
1540
 
1541
+ #: lite/includes/admin/class-settings.php:274
1542
+ #: pro/includes/admin/class-settings.php:339
1543
  msgid "Email Background Color"
1544
  msgstr ""
1545
 
1546
+ #: lite/includes/admin/class-settings.php:278
1547
+ #: pro/includes/admin/class-settings.php:343
1548
  msgid "Customize the background color of the HTML email template."
1549
  msgstr ""
1550
 
1551
  #: lite/includes/admin/class-settings.php:283
1552
  #: pro/includes/admin/class-settings.php:348
1553
+ msgid "Email Carbon Copy"
1554
+ msgstr ""
1555
+
1556
+ #: lite/includes/admin/class-settings.php:287
1557
+ #: pro/includes/admin/class-settings.php:352
1558
+ msgid ""
1559
+ "Check this is you would like to enable the ability to CC: email addresses in "
1560
+ "the form notification settings."
1561
+ msgstr ""
1562
+
1563
+ #: lite/includes/admin/class-settings.php:293
1564
+ #: pro/includes/admin/class-settings.php:358
1565
  msgid "reCAPTCHA"
1566
  msgstr ""
1567
 
1568
+ #: lite/includes/admin/class-settings.php:294
1569
+ #: pro/includes/admin/class-settings.php:359
1570
  msgid ""
1571
  "reCAPTCHA is a free anti-spam service from Google. Its helps protect your "
1572
  "website from spam and abuse while letting real people pass through with "
1573
  "ease. <a href=\"http://www.google.com/recaptcha/intro/index.html\" target="
1574
+ "\"_blank\" rel=\"noopener\">Visit reCAPTCHA</a> to learn more and sign up "
1575
+ "for a free account or <a href=\"https://wpforms.com/docs/setup-captcha-"
1576
+ "wpforms/\" target=\"_blank\" rel=\"noopener\">read our walk through</a> for "
1577
+ "step-by-step directions."
1578
  msgstr ""
1579
 
1580
+ #: lite/includes/admin/class-settings.php:299
1581
+ #: pro/includes/admin/class-settings.php:364
1582
  msgid "reCAPTCHA Site key"
1583
  msgstr ""
1584
 
1585
+ #: lite/includes/admin/class-settings.php:307
1586
+ #: pro/includes/admin/class-settings.php:372
1587
  msgid "reCAPTCHA Secret key"
1588
  msgstr ""
1589
 
1590
+ #: lite/includes/admin/class-settings.php:316
1591
+ #: pro/includes/admin/class-settings.php:381
1592
  msgid "Save General Settings"
1593
  msgstr ""
1594
 
1595
+ #: lite/includes/admin/class-settings.php:428
1596
+ #: lite/includes/admin/class-settings.php:432
1597
+ #: pro/includes/admin/class-settings.php:736
1598
+ #: pro/includes/admin/class-settings.php:740
1599
  #: pro/includes/admin/entries/class-entries.php:1088
1600
  msgid "M j, Y @ g:ia"
1601
  msgstr ""
1602
 
1603
+ #: lite/wpforms-lite.php:85 pro/wpforms-pro.php:267
1604
  msgid "Default Notification"
1605
  msgstr ""
1606
 
1607
+ #: lite/wpforms-lite.php:93 pro/wpforms-pro.php:282
1608
  msgid "Send To Email Address"
1609
  msgstr ""
1610
 
1611
+ #: lite/wpforms-lite.php:96 pro/wpforms-pro.php:285
1612
  msgid ""
1613
  "Enter the email address to receive form entry notifications. For multiple "
1614
  "notifications, separate email addresses with a comma."
1615
  msgstr ""
1616
 
1617
+ #: lite/wpforms-lite.php:112 pro/wpforms-pro.php:301
1618
+ msgid "CC"
1619
+ msgstr ""
1620
+
1621
+ #: lite/wpforms-lite.php:128 pro/wpforms-pro.php:317
1622
  msgid "Email Subject"
1623
  msgstr ""
1624
 
1625
+ #: lite/wpforms-lite.php:130 pro/wpforms-pro.php:319
1626
  msgid "New Entry: "
1627
  msgstr ""
1628
 
1629
+ #: lite/wpforms-lite.php:144 pro/wpforms-pro.php:333
1630
  msgid "From Name"
1631
  msgstr ""
1632
 
1633
+ #: lite/wpforms-lite.php:160 pro/wpforms-pro.php:349
1634
  msgid "From Email"
1635
  msgstr ""
1636
 
1637
+ #: lite/wpforms-lite.php:176 pro/wpforms-pro.php:365
1638
  msgid "Reply-To"
1639
  msgstr ""
1640
 
1641
+ #: lite/wpforms-lite.php:201 pro/wpforms-pro.php:390
1642
  msgid ""
1643
  "To display all form fields, use the <code>{all_fields}</code> Smart Tag."
1644
  msgstr ""
1645
 
1646
+ #: lite/wpforms-lite.php:440
1647
  msgid "is a PRO Feature"
1648
  msgstr ""
1649
 
1650
+ #: lite/wpforms-lite.php:441
1651
  msgid ""
1652
  "We're sorry, %name% is not available on your plan.<br><br>Please upgrade to "
1653
  "the PRO plan to unlock all these awesome features."
1654
  msgstr ""
1655
 
1656
+ #: lite/wpforms-lite.php:442
1657
  msgid "Upgrade to PRO"
1658
  msgstr ""
1659
 
1869
 
1870
  #: pro/includes/admin/class-license.php:288
1871
  msgid ""
1872
+ "Your license key for WPForms has expired. <a href=\"%s\" target=\"_blank\" "
1873
+ "rel=\"noopener\">Please click here to renew your license key and continue "
1874
+ "receiving automatic updates.</a>"
1875
  msgstr ""
1876
 
1877
  #: pro/includes/admin/class-license.php:297
1899
  msgid "System Info"
1900
  msgstr ""
1901
 
1902
+ #: pro/includes/admin/class-settings.php:211
1903
  msgid "Please enter a license key to verify."
1904
  msgstr ""
1905
 
1906
+ #: pro/includes/admin/class-settings.php:241
1907
  msgid "License"
1908
  msgstr ""
1909
 
1910
+ #: pro/includes/admin/class-settings.php:242
1911
  msgid "Your license key provides access to updates and Add-ons. "
1912
  msgstr ""
1913
 
1914
+ #: pro/includes/admin/class-settings.php:247
1915
  msgid "License Key"
1916
  msgstr ""
1917
 
1918
+ #: pro/includes/admin/class-settings.php:251
1919
  msgid "Verify Key"
1920
  msgstr ""
1921
 
1922
+ #: pro/includes/admin/class-settings.php:253
1923
  msgid "Deactivate Key"
1924
  msgstr ""
1925
 
1926
+ #: pro/includes/admin/class-settings.php:261
1927
  msgid "License Key Type"
1928
  msgstr ""
1929
 
1930
+ #: pro/includes/admin/class-settings.php:264
1931
  msgid "Your license key type for this site is <strong>%s.</strong>"
1932
  msgstr ""
1933
 
1934
+ #: pro/includes/admin/class-settings.php:265
1935
  msgid "Refresh Key"
1936
  msgstr ""
1937
 
1938
+ #: pro/includes/admin/class-settings.php:266
1939
  msgid ""
1940
  "If your license has been upgraded or is incorrect, you may force a refresh."
1941
  msgstr ""
1942
 
1943
+ #: pro/includes/admin/class-settings.php:414
1944
  msgid "Settings updated."
1945
  msgstr ""
1946
 
1947
+ #: pro/includes/admin/class-settings.php:428
1948
  msgid "Currency"
1949
  msgstr ""
1950
 
1951
+ #: pro/includes/admin/class-settings.php:440
1952
  msgid "Determines which currency to use for payments."
1953
  msgstr ""
1954
 
1955
+ #: pro/includes/admin/class-settings.php:471
1956
  msgid ""
1957
  "You do not have any marketing add-ons activated. You can head over to the <a "
1958
  "href=\"%s\">Add-Ons page</a> to install and activate the add-on for your "
1959
  "provider."
1960
  msgstr ""
1961
 
1962
+ #: pro/includes/admin/class-settings.php:492
1963
  msgid "Form(s) imported"
1964
  msgstr ""
1965
 
1966
+ #: pro/includes/admin/class-settings.php:501
1967
  msgid "Form Import"
1968
  msgstr ""
1969
 
1970
+ #: pro/includes/admin/class-settings.php:506
1971
  msgid "Select an export file."
1972
  msgstr ""
1973
 
1974
+ #: pro/includes/admin/class-settings.php:512
1975
  msgid "Import"
1976
  msgstr ""
1977
 
1978
+ #: pro/includes/admin/class-settings.php:519
1979
  msgid "Form Export"
1980
  msgstr ""
1981
 
1982
+ #: pro/includes/admin/class-settings.php:524
1983
  msgid ""
1984
  "Select form(s) to download an export file. This can be imported into another "
1985
  "site."
1986
  msgstr ""
1987
 
1988
+ #: pro/includes/admin/class-settings.php:540
1989
  msgid "Export"
1990
  msgstr ""
1991
 
1992
+ #: pro/includes/admin/class-settings.php:600
1993
  msgid "Please upload a valid .json form export file."
1994
  msgstr ""
1995
 
1996
+ #: pro/includes/admin/class-settings.php:600
1997
+ #: pro/includes/admin/entries/class-entries-export.php:300
1998
  msgid "Error"
1999
  msgstr ""
2000
 
2001
+ #: pro/includes/admin/entries/class-entries-export.php:174
2002
  msgid "Date GMT"
2003
  msgstr ""
2004
 
2005
+ #: pro/includes/admin/entries/class-entries-export.php:175
2006
  msgid "ID"
2007
  msgstr ""
2008
 
2009
+ #: pro/includes/admin/entries/class-entries-export.php:300
2010
  msgid "You do not have permission to export entries."
2011
  msgstr ""
2012
 
2036
  msgid "Actions"
2037
  msgstr ""
2038
 
2039
+ #: pro/includes/admin/entries/class-entries-table.php:253
2040
  #: pro/includes/admin/entries/class-entries.php:1156
2041
  msgid "Unknown"
2042
  msgstr ""
2043
 
2044
+ #: pro/includes/admin/entries/class-entries-table.php:292
2045
  #: pro/includes/admin/entries/class-entries.php:243
2046
  msgid "Unstar entry"
2047
  msgstr ""
2048
 
2049
+ #: pro/includes/admin/entries/class-entries-table.php:292
2050
  #: pro/includes/admin/entries/class-entries.php:244
2051
  msgid "Star entry"
2052
  msgstr ""
2053
 
2054
+ #: pro/includes/admin/entries/class-entries-table.php:297
2055
  #: pro/includes/admin/entries/class-entries.php:246
2056
  msgid "Mark entry unread"
2057
  msgstr ""
2058
 
2059
+ #: pro/includes/admin/entries/class-entries-table.php:297
2060
  #: pro/includes/admin/entries/class-entries.php:245
2061
  msgid "Mark entry read"
2062
  msgstr ""
2063
 
2064
+ #: pro/includes/admin/entries/class-entries-table.php:317
2065
  msgid "View Form Entry"
2066
  msgstr ""
2067
 
2068
+ #: pro/includes/admin/entries/class-entries-table.php:318
2069
  msgid "View"
2070
  msgstr ""
2071
 
2072
+ #: pro/includes/admin/entries/class-entries-table.php:324
2073
  msgid "Delete Form Entry"
2074
  msgstr ""
2075
 
2076
+ #: pro/includes/admin/entries/class-entries-table.php:340
2077
  msgid "Mark Read"
2078
  msgstr ""
2079
 
2080
+ #: pro/includes/admin/entries/class-entries-table.php:341
2081
  #: pro/includes/admin/entries/class-entries.php:1336
2082
  msgid "Mark Unread"
2083
  msgstr ""
2084
 
2085
+ #: pro/includes/admin/entries/class-entries-table.php:342
2086
  #: pro/includes/admin/entries/class-entries.php:1288
2087
  msgid "Star"
2088
  msgstr ""
2089
 
2090
+ #: pro/includes/admin/entries/class-entries-table.php:343
2091
  #: pro/includes/admin/entries/class-entries.php:1288
2092
  msgid "Unstar"
2093
  msgstr ""
2094
 
2095
+ #: pro/includes/admin/entries/class-entries-table.php:345
2096
  msgid "----------"
2097
  msgstr ""
2098
 
2099
+ #: pro/includes/admin/entries/class-entries-table.php:389
2100
  msgid "Entry marked as read."
2101
  msgid_plural "Entries marked as read."
2102
  msgstr[0] ""
2103
  msgstr[1] ""
2104
 
2105
+ #: pro/includes/admin/entries/class-entries-table.php:398
2106
  msgid "Entry marked as unread."
2107
  msgid_plural "Entries marked as unread."
2108
  msgstr[0] ""
2109
  msgstr[1] ""
2110
 
2111
+ #: pro/includes/admin/entries/class-entries-table.php:407
2112
  msgid "Entry starred."
2113
  msgid_plural "Entries starred."
2114
  msgstr[0] ""
2115
  msgstr[1] ""
2116
 
2117
+ #: pro/includes/admin/entries/class-entries-table.php:416
2118
  msgid "Entry unstarred."
2119
  msgid_plural "Entries unstarred."
2120
  msgstr[0] ""
2121
  msgstr[1] ""
2122
 
2123
+ #: pro/includes/admin/entries/class-entries-table.php:425
2124
  msgid "Entry successfully deleted."
2125
  msgid_plural "Entries successfully deleted."
2126
  msgstr[0] ""
2127
  msgstr[1] ""
2128
 
2129
+ #: pro/includes/admin/entries/class-entries-table.php:439
2130
  msgid "Whoops, it appears you do not have any form entries yet."
2131
  msgstr ""
2132
 
2594
  "defaults to the maximum size the server allows which is "
2595
  msgstr ""
2596
 
2597
+ #: pro/includes/fields/class-file-upload.php:205
2598
  msgid "Store file in WordPress Media Library"
2599
  msgstr ""
2600
 
2601
+ #: pro/includes/fields/class-file-upload.php:206
2602
  msgid ""
2603
  "Check this option to store the final uploaded file in the WordPress Media "
2604
  "Library"
2605
  msgstr ""
2606
 
2607
+ #: pro/includes/fields/class-file-upload.php:338
2608
  msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini."
2609
  msgstr ""
2610
 
2611
+ #: pro/includes/fields/class-file-upload.php:339
2612
  msgid ""
2613
  "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
2614
  "the HTML form."
2615
  msgstr ""
2616
 
2617
+ #: pro/includes/fields/class-file-upload.php:340
2618
  msgid "The uploaded file was only partially uploaded."
2619
  msgstr ""
2620
 
2621
+ #: pro/includes/fields/class-file-upload.php:341
2622
  msgid "No file was uploaded."
2623
  msgstr ""
2624
 
2625
+ #: pro/includes/fields/class-file-upload.php:343
2626
  msgid "Missing a temporary folder."
2627
  msgstr ""
2628
 
2629
+ #: pro/includes/fields/class-file-upload.php:344
2630
  msgid "Failed to write file to disk."
2631
  msgstr ""
2632
 
2633
+ #: pro/includes/fields/class-file-upload.php:345
2634
  msgid "File upload stopped by extension."
2635
  msgstr ""
2636
 
2637
+ #: pro/includes/fields/class-file-upload.php:347
2638
  msgid "File upload error. "
2639
  msgstr ""
2640
 
2641
+ #: pro/includes/fields/class-file-upload.php:366
2642
  msgid "File exceeds max size allowed"
2643
  msgstr ""
2644
 
2645
+ #: pro/includes/fields/class-file-upload.php:384
2646
  msgid "File must have an extension."
2647
  msgstr ""
2648
 
2649
+ #: pro/includes/fields/class-file-upload.php:394
2650
+ #: pro/includes/fields/class-file-upload.php:413
2651
+ #: pro/includes/fields/class-file-upload.php:431
2652
  msgid "File type is not allowed."
2653
  msgstr ""
2654
 
2837
  msgid "YY"
2838
  msgstr ""
2839
 
2840
+ #: pro/includes/fields/class-payment-dropdown.php:21
2841
+ msgid "Dropdown Items"
2842
  msgstr ""
2843
 
2844
+ #: pro/includes/fields/class-payment-dropdown.php:28
2845
  #: pro/includes/fields/class-payment-multiple.php:28
2846
  #: pro/includes/templates/class-order.php:70
2847
  msgid "First Item"
2848
  msgstr ""
2849
 
2850
+ #: pro/includes/fields/class-payment-dropdown.php:33
2851
  #: pro/includes/fields/class-payment-multiple.php:33
2852
  #: pro/includes/templates/class-order.php:74
2853
  msgid "Second Item"
2854
  msgstr ""
2855
 
2856
+ #: pro/includes/fields/class-payment-dropdown.php:38
2857
  #: pro/includes/fields/class-payment-multiple.php:38
2858
  #: pro/includes/templates/class-order.php:78
2859
  msgid "Third Item"
2860
  msgstr ""
2861
 
2862
+ #: pro/includes/fields/class-payment-dropdown.php:214
2863
+ #: pro/includes/fields/class-payment-multiple.php:180
2864
+ msgid "Invalid payment option"
 
 
 
2865
  msgstr ""
2866
 
2867
+ #: pro/includes/fields/class-payment-multiple.php:21
2868
+ msgid "Multiple Items"
2869
  msgstr ""
2870
 
2871
  #: pro/includes/fields/class-payment-single.php:21
3108
  msgid "Disable storing entry information in WordPress"
3109
  msgstr ""
3110
 
3111
+ #: pro/wpforms-pro.php:247
3112
  msgid "Add New Notification"
3113
  msgstr ""
3114
 
3115
+ #: pro/wpforms-pro.php:403
3116
  msgid "Send"
3117
  msgstr ""
3118
 
3119
+ #: pro/wpforms-pro.php:404
3120
  msgid "Don't send"
3121
  msgstr ""
3122
 
3123
+ #: pro/wpforms-pro.php:406
3124
  msgid "this notification if"
3125
  msgstr ""
3126
 
3127
+ #: pro/wpforms-pro.php:407
3128
  msgid "Email notifications"
3129
  msgstr ""
3130
 
3131
+ #: pro/wpforms-pro.php:410
3132
  msgid ""
3133
  "Install the <a href=\"%s\">Conditional Logic add-on</a> to enable "
3134
  "conditional logic for Email Notifications."
3138
  msgid "Please deactivate WPForms Lite before activating WPForms"
3139
  msgstr ""
3140
 
3141
+ #. #-#-#-#-# wpforms.pot (WPForms 1.3.1) #-#-#-#-#
3142
  #. Plugin URI of the plugin/theme
3143
+ #. #-#-#-#-# wpforms.pot (WPForms 1.3.1) #-#-#-#-#
3144
  #. Author URI of the plugin/theme
3145
  msgid "https://wpforms.com"
3146
  msgstr ""
lite/includes/admin/class-settings.php CHANGED
@@ -55,7 +55,7 @@ class WPForms_Settings {
55
  * @since 1.0.0
56
  */
57
  public function init() {
58
-
59
  // Check what page we are on
60
  $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
61
 
@@ -85,41 +85,41 @@ class WPForms_Settings {
85
  wp_enqueue_media();
86
 
87
  // CSS
88
- wp_enqueue_style(
89
- 'font-awesome',
90
- WPFORMS_PLUGIN_URL . 'assets/css/font-awesome.min.css',
91
- null,
92
  '4.4.0'
93
  );
94
 
95
- wp_enqueue_style(
96
  'wpforms-settings',
97
- WPFORMS_PLUGIN_URL . 'assets/css/admin-settings.css',
98
  null,
99
  WPFORMS_VERSION
100
  );
101
 
102
- wp_enqueue_style(
103
- 'minicolors',
104
- WPFORMS_PLUGIN_URL . 'assets/css/jquery.minicolors.css',
105
- null,
106
  '2.2.3'
107
  );
108
 
109
  // JS
110
- wp_enqueue_script(
111
- 'minicolors',
112
- WPFORMS_PLUGIN_URL . 'assets/js/jquery.minicolors.min.js',
113
- array( 'jquery' ),
114
- '2.2.3',
115
  false
116
  );
117
 
118
- wp_enqueue_script(
119
- 'wpforms-settings',
120
  WPFORMS_PLUGIN_URL . 'assets/js/admin-settings.js',
121
- array( 'jquery', 'jquery-ui-tabs' ),
122
- WPFORMS_VERSION,
123
  false
124
  );
125
  wp_localize_script(
@@ -134,7 +134,7 @@ class WPForms_Settings {
134
  'upload_button' => __( 'Use Image', 'wpforms' ),
135
  )
136
  );
137
-
138
  // Hook for add-ons
139
  do_action( 'wpforms_settings_enqueue' );
140
  }
@@ -184,6 +184,7 @@ class WPForms_Settings {
184
  $this->options['email-template'] = !empty( $_POST['email-template'] ) ? esc_attr( $_POST['email-template'] ) : 'default';
185
  $this->options['email-header-image'] = !empty( $_POST['email-header-image'] ) ? esc_url_raw( $_POST['email-header-image'] ) : '';
186
  $this->options['email-background-color'] = !empty( $_POST['email-background-color'] ) ? wpforms_sanitize_hex_color( $_POST['email-background-color'] ) : '#e9eaec';
 
187
  $this->options['disable-css'] = !empty( $_POST['disable-css'] ) ? intval( $_POST['disable-css'] ) : '1';
188
  $this->options['global-assets'] = !empty( $_POST['global-assets'] ) ? '1' : false;
189
  $this->options['recaptcha-site-key'] = !empty( $_POST['recaptcha-site-key'] ) ? esc_html( $_POST['recaptcha-site-key'] ) : '';
@@ -200,11 +201,11 @@ class WPForms_Settings {
200
  ?>
201
 
202
  <div id="wpforms-settings-general">
203
-
204
  <form method="post">
205
 
206
  <?php wp_nonce_field( 'wpforms-settings-general-nonce', 'wpforms-settings-general-nonce' ); ?>
207
-
208
  <table class="form-table">
209
  <tbody>
210
  <tr>
@@ -226,7 +227,7 @@ class WPForms_Settings {
226
  </th>
227
  <td>
228
  <input type="checkbox" name="global-assets" id="wpforms-settings-general-global-assets" value="1" <?php checked( '1', $this->get( 'global-assets' ) ); ?>>
229
- <label for="wpforms-settings-general-global-assets"><?php _e( 'Check this if you would like to load WPForms assets site-wide. Only check if your site is having compatibility issues or instructed to by support.', 'wpforms_paypals' ); ?></label>
230
  </td>
231
  </tr>
232
  <tr>
@@ -253,7 +254,7 @@ class WPForms_Settings {
253
  </th>
254
  <td>
255
  <label for="wpforms-settings-general-email-header-image" class="wpforms-settings-upload-image-display">
256
- <?php
257
  $email_header = $this->get( 'email-header-image' );
258
  if ( $email_header ) {
259
  echo '<img src="' . esc_url_raw( $email_header ) . '">';
@@ -266,7 +267,7 @@ class WPForms_Settings {
266
  <?php _e( 'Upload or choose a logo to be displayed at the top of email notifications.', 'wpforms' ); ?><br>
267
  <?php _e( 'Recommended size is 300x100 or smaller for best support on all devices.', 'wpforms' ); ?>
268
  </p>
269
- </td>
270
  </tr>
271
  <tr>
272
  <th scope="row">
@@ -277,11 +278,20 @@ class WPForms_Settings {
277
  <p class="description"><?php _e( 'Customize the background color of the HTML email template.', 'wpforms' ); ?></p>
278
  </td>
279
  </tr>
 
 
 
 
 
 
 
 
 
280
  <tr>
281
  <td class="section" colspan="2">
282
  <hr>
283
  <h4><?php _e( 'reCAPTCHA', 'wpforms' ); ?></h4>
284
- <p><?php _e( 'reCAPTCHA is a free anti-spam service from Google. Its helps protect your website from spam and abuse while letting real people pass through with ease. <a href="http://www.google.com/recaptcha/intro/index.html" target="_blank">Visit reCAPTCHA</a> to learn more and sign up for a free account or <a href="https://wpforms.com/docs/setup-captcha-wpforms/" target="_blank">read our walk through</a> for step-by-step directions.', 'wpforms' ); ?></p>
285
  </td>
286
  </tr>
287
  <tr>
@@ -306,7 +316,7 @@ class WPForms_Settings {
306
  <?php submit_button( __( 'Save General Settings', 'wpforms'), 'primary', 'submit-general' ); ?>
307
 
308
  </form>
309
-
310
  </div>
311
  <?php
312
  }
@@ -317,12 +327,12 @@ class WPForms_Settings {
317
  * @since 1.2.3
318
  */
319
  public function settings_page_tab_system() {
320
-
321
  ?>
322
  <div id="wpforms-settings-system">
323
-
324
  <textarea readonly="readonly" class="system-info-textarea"><?php echo $this->get_system_info(); ?></textarea>
325
-
326
  </div>
327
  <?php
328
  }
@@ -353,7 +363,7 @@ class WPForms_Settings {
353
  <div class="wpforms-circle-11 wpforms-circle"></div>
354
  <div class="wpforms-circle-12 wpforms-circle"></div>
355
  </div>
356
-
357
  <div id="wpforms-tabs" class="wpforms-clear">
358
 
359
  <!-- Output tabs navigation -->
55
  * @since 1.0.0
56
  */
57
  public function init() {
58
+
59
  // Check what page we are on
60
  $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
61
 
85
  wp_enqueue_media();
86
 
87
  // CSS
88
+ wp_enqueue_style(
89
+ 'font-awesome',
90
+ WPFORMS_PLUGIN_URL . 'assets/css/font-awesome.min.css',
91
+ null,
92
  '4.4.0'
93
  );
94
 
95
+ wp_enqueue_style(
96
  'wpforms-settings',
97
+ WPFORMS_PLUGIN_URL . 'assets/css/admin-settings.css',
98
  null,
99
  WPFORMS_VERSION
100
  );
101
 
102
+ wp_enqueue_style(
103
+ 'minicolors',
104
+ WPFORMS_PLUGIN_URL . 'assets/css/jquery.minicolors.css',
105
+ null,
106
  '2.2.3'
107
  );
108
 
109
  // JS
110
+ wp_enqueue_script(
111
+ 'minicolors',
112
+ WPFORMS_PLUGIN_URL . 'assets/js/jquery.minicolors.min.js',
113
+ array( 'jquery' ),
114
+ '2.2.3',
115
  false
116
  );
117
 
118
+ wp_enqueue_script(
119
+ 'wpforms-settings',
120
  WPFORMS_PLUGIN_URL . 'assets/js/admin-settings.js',
121
+ array( 'jquery', 'jquery-ui-tabs' ),
122
+ WPFORMS_VERSION,
123
  false
124
  );
125
  wp_localize_script(
134
  'upload_button' => __( 'Use Image', 'wpforms' ),
135
  )
136
  );
137
+
138
  // Hook for add-ons
139
  do_action( 'wpforms_settings_enqueue' );
140
  }
184
  $this->options['email-template'] = !empty( $_POST['email-template'] ) ? esc_attr( $_POST['email-template'] ) : 'default';
185
  $this->options['email-header-image'] = !empty( $_POST['email-header-image'] ) ? esc_url_raw( $_POST['email-header-image'] ) : '';
186
  $this->options['email-background-color'] = !empty( $_POST['email-background-color'] ) ? wpforms_sanitize_hex_color( $_POST['email-background-color'] ) : '#e9eaec';
187
+ $this->options['email-carbon-copy'] = !empty( $_POST['email-carbon-copy'] ) ? '1' : false;
188
  $this->options['disable-css'] = !empty( $_POST['disable-css'] ) ? intval( $_POST['disable-css'] ) : '1';
189
  $this->options['global-assets'] = !empty( $_POST['global-assets'] ) ? '1' : false;
190
  $this->options['recaptcha-site-key'] = !empty( $_POST['recaptcha-site-key'] ) ? esc_html( $_POST['recaptcha-site-key'] ) : '';
201
  ?>
202
 
203
  <div id="wpforms-settings-general">
204
+
205
  <form method="post">
206
 
207
  <?php wp_nonce_field( 'wpforms-settings-general-nonce', 'wpforms-settings-general-nonce' ); ?>
208
+
209
  <table class="form-table">
210
  <tbody>
211
  <tr>
227
  </th>
228
  <td>
229
  <input type="checkbox" name="global-assets" id="wpforms-settings-general-global-assets" value="1" <?php checked( '1', $this->get( 'global-assets' ) ); ?>>
230
+ <label for="wpforms-settings-general-global-assets"><?php _e( 'Check this if you would like to load WPForms assets site-wide. Only check if your site is having compatibility issues or instructed to by support.', 'wpforms' ); ?></label>
231
  </td>
232
  </tr>
233
  <tr>
254
  </th>
255
  <td>
256
  <label for="wpforms-settings-general-email-header-image" class="wpforms-settings-upload-image-display">
257
+ <?php
258
  $email_header = $this->get( 'email-header-image' );
259
  if ( $email_header ) {
260
  echo '<img src="' . esc_url_raw( $email_header ) . '">';
267
  <?php _e( 'Upload or choose a logo to be displayed at the top of email notifications.', 'wpforms' ); ?><br>
268
  <?php _e( 'Recommended size is 300x100 or smaller for best support on all devices.', 'wpforms' ); ?>
269
  </p>
270
+ </td>
271
  </tr>
272
  <tr>
273
  <th scope="row">
278
  <p class="description"><?php _e( 'Customize the background color of the HTML email template.', 'wpforms' ); ?></p>
279
  </td>
280
  </tr>
281
+ <tr>
282
+ <th scope="row">
283
+ <label for="wpforms-settings-general-email-carbon-copy"><?php _e( 'Email Carbon Copy', 'wpforms' ); ?></label>
284
+ </th>
285
+ <td>
286
+ <input type="checkbox" name="email-carbon-copy" id="wpforms-settings-general-email-carbon-copy" value="1" <?php checked( '1', $this->get( 'email-carbon-copy' ) ); ?>>
287
+ <label for="wpforms-settings-general-email-carbon-copy"><?php _e( 'Check this is you would like to enable the ability to CC: email addresses in the form notification settings.', 'wpforms' ); ?></label>
288
+ </td>
289
+ </tr>
290
  <tr>
291
  <td class="section" colspan="2">
292
  <hr>
293
  <h4><?php _e( 'reCAPTCHA', 'wpforms' ); ?></h4>
294
+ <p><?php _e( 'reCAPTCHA is a free anti-spam service from Google. Its helps protect your website from spam and abuse while letting real people pass through with ease. <a href="http://www.google.com/recaptcha/intro/index.html" target="_blank" rel="noopener">Visit reCAPTCHA</a> to learn more and sign up for a free account or <a href="https://wpforms.com/docs/setup-captcha-wpforms/" target="_blank" rel="noopener">read our walk through</a> for step-by-step directions.', 'wpforms' ); ?></p>
295
  </td>
296
  </tr>
297
  <tr>
316
  <?php submit_button( __( 'Save General Settings', 'wpforms'), 'primary', 'submit-general' ); ?>
317
 
318
  </form>
319
+
320
  </div>
321
  <?php
322
  }
327
  * @since 1.2.3
328
  */
329
  public function settings_page_tab_system() {
330
+
331
  ?>
332
  <div id="wpforms-settings-system">
333
+
334
  <textarea readonly="readonly" class="system-info-textarea"><?php echo $this->get_system_info(); ?></textarea>
335
+
336
  </div>
337
  <?php
338
  }
363
  <div class="wpforms-circle-11 wpforms-circle"></div>
364
  <div class="wpforms-circle-12 wpforms-circle"></div>
365
  </div>
366
+
367
  <div id="wpforms-tabs" class="wpforms-clear">
368
 
369
  <!-- Output tabs navigation -->
lite/wpforms-lite.php CHANGED
@@ -46,6 +46,8 @@ class WPForms_Lite {
46
  */
47
  public function form_settings_notifications( $settings ) {
48
 
 
 
49
  // Fetch next ID and handle backwards compatibility
50
  if ( empty( $settings->form_data['settings']['notifications'] ) ) {
51
  $settings->form_data['settings']['notifications'][1]['email'] = !empty( $settings->form_data['settings']['notification_email'] ) ? $settings->form_data['settings']['notification_email'] : '{admin_email}';
@@ -60,8 +62,8 @@ class WPForms_Lite {
60
  _e( 'Notifications', 'wpforms' );
61
  echo '</div>';
62
 
63
- echo '<p class="wpforms-alert wpforms-alert-info">Want multiple notifications with smart conditional logic?<br><a href="' . $this->upgrade_link() . 'target="_blank"><strong>Upgrade to PRO</strong></a> to unlock it and more awesome features.</p>';
64
-
65
  wpforms_panel_field(
66
  'select',
67
  'settings',
@@ -89,7 +91,7 @@ class WPForms_Lite {
89
  'email',
90
  $settings->form_data,
91
  __( 'Send To Email Address', 'wpforms' ),
92
- array(
93
  'default' => '{admin_email}',
94
  'tooltip' => __( 'Enter the email address to receive form entry notifications. For multiple notifications, separate email addresses with a comma.', 'wpforms' ),
95
  'smarttags' => array(
@@ -101,13 +103,30 @@ class WPForms_Lite {
101
  'class' => 'email-recipient',
102
  )
103
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  wpforms_panel_field(
105
  'text',
106
  'notifications',
107
  'subject',
108
  $settings->form_data,
109
  __( 'Email Subject', 'wpforms' ),
110
- array(
111
  'default' => __( 'New Entry: ' , 'wpforms' ) . $settings->form->post_title,
112
  'smarttags' => array(
113
  'type' => 'fields',
@@ -123,7 +142,7 @@ class WPForms_Lite {
123
  'sender_name',
124
  $settings->form_data,
125
  __( 'From Name', 'wpforms' ),
126
- array(
127
  'default' => sanitize_text_field( get_option( 'blogname' ) ),
128
  'smarttags' => array(
129
  'type' => 'fields',
@@ -139,7 +158,7 @@ class WPForms_Lite {
139
  'sender_address',
140
  $settings->form_data,
141
  __( 'From Email', 'wpforms' ),
142
- array(
143
  'default' => '{admin_email}',
144
  'smarttags' => array(
145
  'type' => 'fields',
@@ -155,7 +174,7 @@ class WPForms_Lite {
155
  'replyto',
156
  $settings->form_data,
157
  __( 'Reply-To', 'wpforms' ),
158
- array(
159
  'smarttags' => array(
160
  'type' => 'fields',
161
  'fields' => 'name,email,text',
@@ -248,7 +267,7 @@ class WPForms_Lite {
248
  )
249
  );
250
  ?>
251
- <div class="wpforms-setup-title">Unlock Pre-Made Form Templates <a href="<?php echo $this->upgrade_link(); ?>" target="_blank" class="btn-green" style="text-transform:uppercase;font-size:13px;font-weight:700;padding:5px 10px;vertical-align:text-bottom;">Upgrade</a></div>
252
  <p class="wpforms-setup-desc">While WPForms Lite allows you to create any type of form, you can speed up the process by unlocking our other pre-built form templates among other features, so you never have to start from scratch again...</p>
253
  <div class="wpforms-setup-templates wpforms-clear" style="opacity:0.5;">
254
  <?php
@@ -281,95 +300,102 @@ class WPForms_Lite {
281
  */
282
  public function form_fields( $fields ) {
283
 
284
- $fields['fancy']['fields'][] = array(
285
  'icon' => 'fa-link',
286
  'name' => 'Website / URL',
287
  'type' => 'url',
288
  'order' => '1',
289
  'class' => 'upgrade-modal',
290
  );
291
- $fields['fancy']['fields'][] = array(
292
  'icon' => 'fa-map-marker',
293
  'name' => 'Address',
294
  'type' => 'address',
295
  'order' => '2',
296
  'class' => 'upgrade-modal',
297
  );
298
- $fields['fancy']['fields'][] = array(
299
  'icon' => 'fa-phone',
300
  'name' => 'Phone',
301
  'type' => 'phone',
302
  'order' => '3',
303
  'class' => 'upgrade-modal',
304
  );
305
- $fields['fancy']['fields'][] = array(
306
  'icon' => 'fa-lock',
307
  'name' => 'Password',
308
  'type' => 'password',
309
  'order' => '4',
310
  'class' => 'upgrade-modal',
311
  );
312
- $fields['fancy']['fields'][] = array(
313
  'icon' => 'fa-calendar-o',
314
  'name' => 'Date / Time',
315
  'type' => 'date-time',
316
  'order' => '5',
317
  'class' => 'upgrade-modal',
318
  );
319
- $fields['fancy']['fields'][] = array(
320
  'icon' => 'fa-eye-slash',
321
  'name' => 'Hidden Field',
322
  'type' => 'hidden',
323
  'order' => '6',
324
  'class' => 'upgrade-modal',
325
  );
326
- $fields['fancy']['fields'][] = array(
327
  'icon' => 'fa-upload',
328
  'name' => 'File Upload',
329
  'type' => 'file-upload',
330
  'order' => '7',
331
  'class' => 'upgrade-modal',
332
  );
333
- $fields['fancy']['fields'][] = array(
334
  'icon' => 'fa-code',
335
  'name' => 'HTML',
336
  'type' => 'html',
337
  'order' => '8',
338
  'class' => 'upgrade-modal',
339
  );
340
- $fields['fancy']['fields'][] = array(
341
  'icon' => 'fa-files-o',
342
  'name' => 'Page Break',
343
  'type' => 'pagebreak',
344
  'order' => '9',
345
  'class' => 'upgrade-modal',
346
  );
347
- $fields['fancy']['fields'][] = array(
348
  'icon' => 'fa-arrows-h',
349
  'name' => 'Divider',
350
  'type' => 'Divider',
351
  'order' => '10',
352
  'class' => 'upgrade-modal',
353
  );
354
- $fields['payment']['fields'][] = array(
355
  'icon' => 'fa-file-o',
356
  'name' => 'Single Item',
357
  'type' => 'payment-single',
358
  'order' => '1',
359
  'class' => 'upgrade-modal',
360
  );
361
- $fields['payment']['fields'][] = array(
362
  'icon' => 'fa-list-ul',
363
  'name' => 'Multiple Items',
364
  'type' => 'payment-multiple',
365
  'order' => '2',
366
  'class' => 'upgrade-modal',
367
  );
368
- $fields['payment']['fields'][] = array(
 
 
 
 
 
 
 
369
  'icon' => 'fa-money',
370
  'name' => 'Total',
371
  'type' => 'payment-total',
372
- 'order' => '3',
373
  'class' => 'upgrade-modal',
374
  );
375
  return $fields;
@@ -399,11 +425,11 @@ class WPForms_Lite {
399
  */
400
  public function builder_enqueues() {
401
 
402
- wp_enqueue_script(
403
- 'wpforms-builder-lite',
404
- WPFORMS_PLUGIN_URL . 'lite/assets/js/admin-builder-lite.js',
405
- array( 'jquery', 'jquery-confirm' ),
406
- WPFORMS_VERSION,
407
  false
408
  );
409
 
@@ -439,7 +465,7 @@ class WPForms_Lite {
439
  <div class="notice notice-info below-h2">
440
  <p><strong>Entry management and storage is a PRO feature.</strong></p>
441
  <p>Please upgrade to the PRO plan to unlock it and more awesome features.</p>
442
- <p><a href="<?php echo $this->upgrade_link(); ?>" class="button button-primary" target="_blank">Upgrade Now</a></p>
443
  </div>
444
  </div>
445
  <?php
@@ -456,16 +482,16 @@ class WPForms_Lite {
456
  return;
457
 
458
  // CSS
459
- wp_enqueue_style(
460
- 'font-awesome',
461
- WPFORMS_PLUGIN_URL . 'assets/css/font-awesome.min.css',
462
- null,
463
  '4.4.0'
464
  );
465
- wp_enqueue_style(
466
- 'wpforms-addons',
467
- WPFORMS_PLUGIN_URL . 'assets/css/admin-addons.css',
468
- null,
469
  WPFORMS_VERSION
470
  );
471
  }
@@ -559,7 +585,7 @@ class WPForms_Lite {
559
  <h4><?php echo $addon['name']; ?> Addon</h4>
560
  <p class="desc"><?php echo $addon['desc']; ?></p>
561
  </div>
562
- <div class="wpforms-addon-action"><a href="<?php echo $upgrade; ?>" target="_blank">Upgrade Now</a></div>
563
  </div>
564
  <?php endforeach; ?>
565
  <div style="clear:both"></div>
46
  */
47
  public function form_settings_notifications( $settings ) {
48
 
49
+ $cc = wpforms_setting( 'email-carbon-copy', false );
50
+
51
  // Fetch next ID and handle backwards compatibility
52
  if ( empty( $settings->form_data['settings']['notifications'] ) ) {
53
  $settings->form_data['settings']['notifications'][1]['email'] = !empty( $settings->form_data['settings']['notification_email'] ) ? $settings->form_data['settings']['notification_email'] : '{admin_email}';
62
  _e( 'Notifications', 'wpforms' );
63
  echo '</div>';
64
 
65
+ echo '<p class="wpforms-alert wpforms-alert-info">Want multiple notifications with smart conditional logic?<br><a href="' . $this->upgrade_link() . 'target="_blank" rel="noopener"><strong>Upgrade to PRO</strong></a> to unlock it and more awesome features.</p>';
66
+
67
  wpforms_panel_field(
68
  'select',
69
  'settings',
91
  'email',
92
  $settings->form_data,
93
  __( 'Send To Email Address', 'wpforms' ),
94
+ array(
95
  'default' => '{admin_email}',
96
  'tooltip' => __( 'Enter the email address to receive form entry notifications. For multiple notifications, separate email addresses with a comma.', 'wpforms' ),
97
  'smarttags' => array(
103
  'class' => 'email-recipient',
104
  )
105
  );
106
+ if ( $cc ) :
107
+ wpforms_panel_field(
108
+ 'text',
109
+ 'notifications',
110
+ 'carboncopy',
111
+ $settings->form_data,
112
+ __( 'CC', 'wpforms' ),
113
+ array(
114
+ 'smarttags' => array(
115
+ 'type' => 'fields',
116
+ 'fields' => 'email',
117
+ ),
118
+ 'parent' => 'settings',
119
+ 'subsection' => $id
120
+ )
121
+ );
122
+ endif;
123
  wpforms_panel_field(
124
  'text',
125
  'notifications',
126
  'subject',
127
  $settings->form_data,
128
  __( 'Email Subject', 'wpforms' ),
129
+ array(
130
  'default' => __( 'New Entry: ' , 'wpforms' ) . $settings->form->post_title,
131
  'smarttags' => array(
132
  'type' => 'fields',
142
  'sender_name',
143
  $settings->form_data,
144
  __( 'From Name', 'wpforms' ),
145
+ array(
146
  'default' => sanitize_text_field( get_option( 'blogname' ) ),
147
  'smarttags' => array(
148
  'type' => 'fields',
158
  'sender_address',
159
  $settings->form_data,
160
  __( 'From Email', 'wpforms' ),
161
+ array(
162
  'default' => '{admin_email}',
163
  'smarttags' => array(
164
  'type' => 'fields',
174
  'replyto',
175
  $settings->form_data,
176
  __( 'Reply-To', 'wpforms' ),
177
+ array(
178
  'smarttags' => array(
179
  'type' => 'fields',
180
  'fields' => 'name,email,text',
267
  )
268
  );
269
  ?>
270
+ <div class="wpforms-setup-title">Unlock Pre-Made Form Templates <a href="<?php echo $this->upgrade_link(); ?>" target="_blank" rel="noopener" class="btn-green" style="text-transform:uppercase;font-size:13px;font-weight:700;padding:5px 10px;vertical-align:text-bottom;">Upgrade</a></div>
271
  <p class="wpforms-setup-desc">While WPForms Lite allows you to create any type of form, you can speed up the process by unlocking our other pre-built form templates among other features, so you never have to start from scratch again...</p>
272
  <div class="wpforms-setup-templates wpforms-clear" style="opacity:0.5;">
273
  <?php
300
  */
301
  public function form_fields( $fields ) {
302
 
303
+ $fields['fancy']['fields'][] = array(
304
  'icon' => 'fa-link',
305
  'name' => 'Website / URL',
306
  'type' => 'url',
307
  'order' => '1',
308
  'class' => 'upgrade-modal',
309
  );
310
+ $fields['fancy']['fields'][] = array(
311
  'icon' => 'fa-map-marker',
312
  'name' => 'Address',
313
  'type' => 'address',
314
  'order' => '2',
315
  'class' => 'upgrade-modal',
316
  );
317
+ $fields['fancy']['fields'][] = array(
318
  'icon' => 'fa-phone',
319
  'name' => 'Phone',
320
  'type' => 'phone',
321
  'order' => '3',
322
  'class' => 'upgrade-modal',
323
  );
324
+ $fields['fancy']['fields'][] = array(
325
  'icon' => 'fa-lock',
326
  'name' => 'Password',
327
  'type' => 'password',
328
  'order' => '4',
329
  'class' => 'upgrade-modal',
330
  );
331
+ $fields['fancy']['fields'][] = array(
332
  'icon' => 'fa-calendar-o',
333
  'name' => 'Date / Time',
334
  'type' => 'date-time',
335
  'order' => '5',
336
  'class' => 'upgrade-modal',
337
  );
338
+ $fields['fancy']['fields'][] = array(
339
  'icon' => 'fa-eye-slash',
340
  'name' => 'Hidden Field',
341
  'type' => 'hidden',
342
  'order' => '6',
343
  'class' => 'upgrade-modal',
344
  );
345
+ $fields['fancy']['fields'][] = array(
346
  'icon' => 'fa-upload',
347
  'name' => 'File Upload',
348
  'type' => 'file-upload',
349
  'order' => '7',
350
  'class' => 'upgrade-modal',
351
  );
352
+ $fields['fancy']['fields'][] = array(
353
  'icon' => 'fa-code',
354
  'name' => 'HTML',
355
  'type' => 'html',
356
  'order' => '8',
357
  'class' => 'upgrade-modal',
358
  );
359
+ $fields['fancy']['fields'][] = array(
360
  'icon' => 'fa-files-o',
361
  'name' => 'Page Break',
362
  'type' => 'pagebreak',
363
  'order' => '9',
364
  'class' => 'upgrade-modal',
365
  );
366
+ $fields['fancy']['fields'][] = array(
367
  'icon' => 'fa-arrows-h',
368
  'name' => 'Divider',
369
  'type' => 'Divider',
370
  'order' => '10',
371
  'class' => 'upgrade-modal',
372
  );
373
+ $fields['payment']['fields'][] = array(
374
  'icon' => 'fa-file-o',
375
  'name' => 'Single Item',
376
  'type' => 'payment-single',
377
  'order' => '1',
378
  'class' => 'upgrade-modal',
379
  );
380
+ $fields['payment']['fields'][] = array(
381
  'icon' => 'fa-list-ul',
382
  'name' => 'Multiple Items',
383
  'type' => 'payment-multiple',
384
  'order' => '2',
385
  'class' => 'upgrade-modal',
386
  );
387
+ $fields['payment']['fields'][] = array(
388
+ 'icon' => 'fa-caret-square-o-down',
389
+ 'name' => 'Dropdown Items',
390
+ 'type' => 'payment-multiple',
391
+ 'order' => '3',
392
+ 'class' => 'upgrade-modal',
393
+ );
394
+ $fields['payment']['fields'][] = array(
395
  'icon' => 'fa-money',
396
  'name' => 'Total',
397
  'type' => 'payment-total',
398
+ 'order' => '4',
399
  'class' => 'upgrade-modal',
400
  );
401
  return $fields;
425
  */
426
  public function builder_enqueues() {
427
 
428
+ wp_enqueue_script(
429
+ 'wpforms-builder-lite',
430
+ WPFORMS_PLUGIN_URL . 'lite/assets/js/admin-builder-lite.js',
431
+ array( 'jquery', 'jquery-confirm' ),
432
+ WPFORMS_VERSION,
433
  false
434
  );
435
 
465
  <div class="notice notice-info below-h2">
466
  <p><strong>Entry management and storage is a PRO feature.</strong></p>
467
  <p>Please upgrade to the PRO plan to unlock it and more awesome features.</p>
468
+ <p><a href="<?php echo $this->upgrade_link(); ?>" class="button button-primary" target="_blank" rel="noopener">Upgrade Now</a></p>
469
  </div>
470
  </div>
471
  <?php
482
  return;
483
 
484
  // CSS
485
+ wp_enqueue_style(
486
+ 'font-awesome',
487
+ WPFORMS_PLUGIN_URL . 'assets/css/font-awesome.min.css',
488
+ null,
489
  '4.4.0'
490
  );
491
+ wp_enqueue_style(
492
+ 'wpforms-addons',
493
+ WPFORMS_PLUGIN_URL . 'assets/css/admin-addons.css',
494
+ null,
495
  WPFORMS_VERSION
496
  );
497
  }
585
  <h4><?php echo $addon['name']; ?> Addon</h4>
586
  <p class="desc"><?php echo $addon['desc']; ?></p>
587
  </div>
588
+ <div class="wpforms-addon-action"><a href="<?php echo $upgrade; ?>" target="_blank" rel="noopener">Upgrade Now</a></div>
589
  </div>
590
  <?php endforeach; ?>
591
  <div style="clear:both"></div>
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
- === Easy WordPress Contact Form Plugin - WPForms Lite ===
2
  Contributors: wpforms, jaredatch, smub
3
- Tags: contact form, contact form plugin, contact button, contact me, custom form, custom contact form, form builder, form manager, form, forms builder, forms creator, captcha, recaptcha, Akismet, email form, web form, feedback form, payment form, survey form, donation form, email submit form, message form, mailchimp, mailchimp form, aweber, aweber form, paypal, paypal form, stripe, stripe form, getresponse, getresponse form, email subscription, contact form widget, user registration form, wordpress registration, wordpress login form
4
- Requires at least: 4.4
5
- Tested up to: 4.6.1
6
  Stable tag: trunk
7
  License: GNU General Public License v2.0 or later
8
 
@@ -35,18 +35,18 @@ We were tired of the bloated and buggy contact form plugins. That's why we built
35
 
36
  But don't just take our word. See what one of the WordPress experts are saying:
37
 
38
- > WPForms is by far the <strong>easiest form plugin to use</strong>. My clients love it its one of the few plugins they can use without any training. As a developer I appreciate how fast, modern, clean and extensible it is.<br>
39
  > Bill Erickson - Expert WordPress Consultant
40
 
41
  = Pre-built Form Templates =
42
 
43
- Building forms in WordPress can be time consuming. Why?
44
 
45
- Because every other WordPress contact form plugin requires you to build your form from scratch. The truth is its often not necessary to create a form completely from scratch unless you really want to.
46
 
47
  Whether you’re looking to create a simple contact form, request a quote form, donation form, payment order form, or a subscription form, we have a form template for you.
48
 
49
- WPForms comes with <a href="https://wpforms.com/features/form-templates/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">pre-built form templates</a> to help you save time. You can add, remove, or re-arrange fields as necessary.
50
 
51
  = Mobile Ready, SEO Friendly and Optimized for Speed =
52
 
@@ -97,7 +97,7 @@ We also knew that our developer friends may want to extend it further. That's wh
97
 
98
  After reading this feature list, you can probably imagine why WPForms is the best WordPress forms plugin in the market.
99
 
100
- Give WPForms a try.
101
 
102
  Want to unlock more features? <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">Upgrade to our Pro version</a>.
103
 
@@ -149,7 +149,7 @@ Yes, WPForms has full translation and localization support via the wpforms textd
149
 
150
  == Notes ==
151
 
152
- WPForms is absolutely, positively the most <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="Best WordPress contact form plugin">beginner friendly WordPress contact form plugin</a> on the market. It is both easy and powerful.
153
 
154
  We took the pain out of creating online forms and made it easy. Check out all <a href="https://wpforms.com/features/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">WPForms features</a>.
155
 
@@ -163,9 +163,17 @@ Syed Balkhi
163
 
164
  == Changelog ==
165
 
 
 
 
 
 
 
 
 
 
 
166
  = 1.3.0 =
167
- ## [1.3.0] - 2016-10-07
168
- ### Added
169
  - Added: Email field confirmantion
170
  - Added: Support for Visual Composer
171
  - Added: Field class to force elements to full-width on mobile devices, `wpforms-mobile-full`
@@ -212,7 +220,7 @@ Syed Balkhi
212
  - Added: Setting for Email template background color
213
  - Added: Form setting for form wrapper CSS class
214
  - Changed: Multiple Payment field stores Choice label text
215
- - Changed: reCAPTCHA tweaks and added filter
216
  - Changed: Improved IP detection
217
  - Fixed: Mapped select fields in builder triggered JS error
218
 
@@ -261,7 +269,7 @@ Syed Balkhi
261
  * Fixed: reCAPTCHA button overlaying submit button preventing it from being clicked
262
 
263
  = 1.2.0.1 =
264
- * Changed: Improved field and column gutter consistency
265
 
266
  = 1.2.0 =
267
  * Added: Form preview
@@ -400,7 +408,7 @@ Syed Balkhi
400
  = 1.0.3 =
401
  * Added: Basic TinyMCE editor for form confirmation messages
402
  * Changed: Removed form ID from form overview table, ID still visible in shortcode column
403
- * Fixed: Checkbox/radio form elements alignment
404
  * Fixed: Quotation slashes in email notification text
405
  * Fixed: SSL verification preventing proper API calls on some servers
406
 
1
+ === Contact Form by WPForms - Drag & Drop Form Builder for WordPress ===
2
  Contributors: wpforms, jaredatch, smub
3
+ Tags: contact form, contact form plugin, contact button, contact me, custom form, custom contact form, form builder, form manager, form, forms builder, forms creator, captcha, recaptcha, Akismet, email form, web form, feedback form, payment form, survey form, donation form, email submit form, message form, mailchimp, mailchimp form, aweber, aweber form, paypal, paypal form, stripe, stripe form, getresponse, getresponse form, email subscription, contact form widget, user registration form, wordpress registration, wordpress login form
4
+ Requires at least: 4.5
5
+ Tested up to: 4.7
6
  Stable tag: trunk
7
  License: GNU General Public License v2.0 or later
8
 
35
 
36
  But don't just take our word. See what one of the WordPress experts are saying:
37
 
38
+ > WPForms is by far the <strong>easiest form plugin to use</strong>. My clients love WPForms and it's one of the few plugins they can use without any training. As a developer I appreciate how fast, modern, clean and extensible it is.<br>
39
  > Bill Erickson - Expert WordPress Consultant
40
 
41
  = Pre-built Form Templates =
42
 
43
+ Building forms in WordPress can be time consuming. Why?
44
 
45
+ Because every other WordPress contact form plugin requires you to build your form from scratch. The truth is it's often not necessary to create a form completely from scratch unless you really want to.
46
 
47
  Whether you’re looking to create a simple contact form, request a quote form, donation form, payment order form, or a subscription form, we have a form template for you.
48
 
49
+ WPForms comes with <a href="https://wpforms.com/features/form-templates/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">pre-built form templates</a> to help you save time. You can add, remove, or re-arrange fields as necessary.
50
 
51
  = Mobile Ready, SEO Friendly and Optimized for Speed =
52
 
97
 
98
  After reading this feature list, you can probably imagine why WPForms is the best WordPress forms plugin in the market.
99
 
100
+ Give WPForms a try.
101
 
102
  Want to unlock more features? <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">Upgrade to our Pro version</a>.
103
 
149
 
150
  == Notes ==
151
 
152
+ WPForms is absolutely, positively the most <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="Best WordPress contact form plugin">beginner friendly WordPress contact form plugin</a> on the market. It is both easy and powerful.
153
 
154
  We took the pain out of creating online forms and made it easy. Check out all <a href="https://wpforms.com/features/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">WPForms features</a>.
155
 
163
 
164
  == Changelog ==
165
 
166
+ = 1.3.1 =
167
+ - Added: Smart Tags for author ID, email, and name
168
+ - Added: Carbon Copy (CC) support for form notifications; enable in WPForms Settings
169
+ - Fixed: Field duplication issues
170
+ - Fixed: TinyMCE "Add Form" button not opening modal with dynamic TinyMCE instances
171
+ - Fixed: Email formatting issues when using plain text formatting
172
+ - Fixed: Number field validation tripping when number submitted is zero
173
+ - Fixed: reCAPTCHA validation passing when reCAPTCHA left blank
174
+ - Fixed: Dropdown field size not reflecting in builder
175
+
176
  = 1.3.0 =
 
 
177
  - Added: Email field confirmantion
178
  - Added: Support for Visual Composer
179
  - Added: Field class to force elements to full-width on mobile devices, `wpforms-mobile-full`
220
  - Added: Setting for Email template background color
221
  - Added: Form setting for form wrapper CSS class
222
  - Changed: Multiple Payment field stores Choice label text
223
+ - Changed: reCAPTCHA tweaks and added filter
224
  - Changed: Improved IP detection
225
  - Fixed: Mapped select fields in builder triggered JS error
226
 
269
  * Fixed: reCAPTCHA button overlaying submit button preventing it from being clicked
270
 
271
  = 1.2.0.1 =
272
+ * Changed: Improved field and column gutter consistency
273
 
274
  = 1.2.0 =
275
  * Added: Form preview
408
  = 1.0.3 =
409
  * Added: Basic TinyMCE editor for form confirmation messages
410
  * Changed: Removed form ID from form overview table, ID still visible in shortcode column
411
+ * Fixed: Checkbox/radio form elements alignment
412
  * Fixed: Quotation slashes in email notification text
413
  * Fixed: SSL verification preventing proper API calls on some servers
414
 
wpforms.php CHANGED
@@ -1,297 +1,426 @@
1
- <?php
2
- /**
3
- * Plugin Name: WPForms Lite
4
- * Plugin URI: https://wpforms.com
5
- * Description: Beginner friendly WordPress contact form plugin. Use our Drag & Drop form builder to create your WordPress forms.
6
- * Author: WPForms
7
- * Author URI: https://wpforms.com
8
- * Version: 1.3.0
9
- * Text Domain: wpforms
10
- * Domain Path: languages
11
- *
12
- * WPForms is free software: you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation, either version 2 of the License, or
15
- * any later version.
16
- *
17
- * WPForms is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with WPForms. If not, see <http://www.gnu.org/licenses/>.
24
- *
25
- * @package WPForms
26
- * @author WPForms
27
- * @since 1.0.0
28
- * @license GPL-2.0+
29
- * @copyright Copyright (c) 2016, WPForms LLC
30
- */
31
-
32
- // Exit if accessed directly
33
- if ( ! defined( 'ABSPATH' ) ) exit;
34
-
35
- // Don't allow multiple versions to be active
36
- if ( class_exists( 'WPForms' ) ) :
37
-
38
- /**
39
- * Deactivate if WPForms already activated.
40
- *
41
- * @since 1.0.0
42
- */
43
- function wpforms_deactivate() {
44
- deactivate_plugins( plugin_basename( __FILE__ ) );
45
- }
46
- add_action( 'admin_init', 'wpforms_deactivate' );
47
-
48
- /**
49
- * Display notice after deactivation.
50
- *
51
- * @since 1.0.0
52
- */
53
- function wpforms_lite_notice() {
54
- echo '<div class="notice notice-warning"><p>' . __( 'Please deactivate WPForms Lite before activating WPForms', 'wpforms' ) . '</p></div>';
55
- if ( isset( $_GET['activate'] ) )
56
- unset( $_GET['activate'] );
57
- }
58
- add_action( 'admin_notices', 'wpforms_lite_notice' );
59
-
60
- else :
61
-
62
- /**
63
- * Main WPForms class.
64
- *
65
- * @since 1.0.0
66
- * @package WPForms
67
- */
68
- final class WPForms {
69
-
70
- /**
71
- * One is the loneliest number that you'll ever do.
72
- *
73
- * @since 1.0.0
74
- * @var object
75
- */
76
- private static $instance;
77
-
78
- /**
79
- * Plugin version for enqueueing, etc.
80
- *
81
- * @since 1.0.0
82
- * @var sting
83
- */
84
- public $version = '1.3.0';
85
-
86
- /**
87
- * The form data handler instance.
88
- *
89
- * @var object WPForms_Form_Handler
90
- * @since 1.0.0
91
- */
92
- public $form;
93
-
94
- /**
95
- * The entry data handler instance (Pro).
96
- *
97
- * @var object WPForms_Entry_Handler
98
- * @since 1.0.0
99
- */
100
- public $entry;
101
-
102
- /**
103
- * The entry meta data handler instance (Pro).
104
- *
105
- * @var object WPForms_Entry_Meta_Handler
106
- * @since 1.1.6
107
- */
108
- public $entry_meta;
109
-
110
- /**
111
- * The front-end instance.
112
- *
113
- * @var object WPForms_Frontend
114
- * @since 1.0.0
115
- */
116
- public $frontend;
117
-
118
- /**
119
- * The process instance.
120
- *
121
- * @var object WPForms_Process
122
- * @since 1.0.0
123
- */
124
- public $process;
125
-
126
- /**
127
- * The smart tags instance.
128
- *
129
- * @var object WPForms_Smart_Tags
130
- * @since 1.0.0
131
- */
132
- public $smart_tags;
133
-
134
- /**
135
- * The Logging instance.
136
- *
137
- * @var object WPForms_Logging
138
- * @since 1.0.0
139
- */
140
- public $logs;
141
-
142
- /**
143
- * The Preview instance.
144
- *
145
- * @var object WPForms_Preview
146
- * @since 1.1.9
147
- */
148
- public $preview;
149
-
150
- /**
151
- * The License class instance (Pro).
152
- *
153
- * @var object WPForms_License
154
- * @since 1.0.0
155
- */
156
- public $license;
157
-
158
- /**
159
- * Main WPForms Instance.
160
- *
161
- * Insures that only one instance of WPForms exists in memory at any one
162
- * time. Also prevents needing to define globals all over the place.
163
- *
164
- * @since 1.0.0
165
- * @return WPForms
166
- */
167
- public static function instance() {
168
-
169
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPForms ) ) {
170
-
171
- self::$instance = new WPForms;
172
- self::$instance->constants();
173
- self::$instance->load_textdomain();
174
- self::$instance->includes();
175
-
176
- // Load Pro or Lite specific files
177
- if ( file_exists( WPFORMS_PLUGIN_DIR . 'pro/wpforms-pro.php' ) ) {
178
- require_once WPFORMS_PLUGIN_DIR . 'pro/wpforms-pro.php';
179
- } else {
180
- require_once WPFORMS_PLUGIN_DIR . 'lite/wpforms-lite.php';
181
- }
182
-
183
- add_action( 'plugins_loaded', array( self::$instance, 'objects' ), 10 );
184
- }
185
- return self::$instance;
186
- }
187
-
188
- /**
189
- * Include files.
190
- *
191
- * @since 1.0.0
192
- */
193
- private function includes() {
194
-
195
- // Global includes
196
- require_once WPFORMS_PLUGIN_DIR . 'includes/functions.php';
197
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-install.php';
198
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-form.php';
199
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-fields.php';
200
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-frontend.php';
201
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-templates.php';
202
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-process.php';
203
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-smart-tags.php';
204
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-logging.php';
205
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-widget.php';
206
- require_once WPFORMS_PLUGIN_DIR . 'includes/class-preview.php';
207
- require_once WPFORMS_PLUGIN_DIR . 'includes/emails/class-emails.php';
208
- require_once WPFORMS_PLUGIN_DIR . 'includes/integrations.php';
209
-
210
- // Admin/Dashboard only includes
211
- if ( is_admin() ) {
212
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/class-menu.php';
213
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/overview/class-overview.php';
214
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/builder/class-builder.php';
215
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/builder/functions.php';
216
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/class-welcome.php';
217
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/class-editor.php';
218
- require_once WPFORMS_PLUGIN_DIR . 'includes/admin/ajax-actions.php';
219
- }
220
- }
221
-
222
- /**
223
- * Setup objects.
224
- *
225
- * @since 1.0.0
226
- */
227
- public function objects() {
228
-
229
- // Global objects
230
- $this->form = new WPForms_Form_Handler;
231
- $this->frontend = new WPForms_Frontend;
232
- $this->process = new WPForms_Process;
233
- $this->smart_tags = new WPForms_Smart_Tags;
234
- $this->logs = new WPForms_Logging;
235
- $this->preview = new WPForms_Preview;
236
-
237
- // Hook now that all of the WPForms stuff is loaded.
238
- do_action( 'wpforms_loaded' );
239
- }
240
-
241
- /**
242
- * Setup plugin constants.
243
- *
244
- * @since 1.0.0
245
- */
246
- private function constants() {
247
-
248
- // Plugin version
249
- if ( ! defined( 'WPFORMS_VERSION' ) ) {
250
- define( 'WPFORMS_VERSION', $this->version );
251
- }
252
-
253
- // Plugin Folder Path
254
- if ( ! defined( 'WPFORMS_PLUGIN_DIR' ) ) {
255
- define( 'WPFORMS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
256
- }
257
-
258
- // Plugin Folder URL
259
- if ( ! defined( 'WPFORMS_PLUGIN_URL' ) ) {
260
- define( 'WPFORMS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
261
- }
262
-
263
- // Plugin Root File
264
- if ( ! defined( 'WPFORMS_PLUGIN_FILE' ) ) {
265
- define( 'WPFORMS_PLUGIN_FILE', __FILE__ );
266
- }
267
- }
268
-
269
- /**
270
- * Loads the plugin language files.
271
- *
272
- * @since 1.0.0
273
- */
274
- public function load_textdomain() {
275
-
276
- load_plugin_textdomain( 'wpforms', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
277
- }
278
- }
279
-
280
- /**
281
- * The function which returns the one WPForms instance.
282
- *
283
- * Use this function like you would a global variable, except without needing
284
- * to declare the global.
285
- *
286
- * Example: <?php $wpforms = wpforms(); ?>
287
- *
288
- * @since 1.0.0
289
- * @return object
290
- */
291
- function wpforms() {
292
-
293
- return WPForms::instance();
294
- }
295
- wpforms();
296
-
297
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Contact Form by WPForms - Drag & Drop Form Builder for WordPress ===
2
+ Contributors: wpforms, jaredatch, smub
3
+ Tags: contact form, contact form plugin, contact button, contact me, custom form, custom contact form, form builder, form manager, form, forms builder, forms creator, captcha, recaptcha, Akismet, email form, web form, feedback form, payment form, survey form, donation form, email submit form, message form, mailchimp, mailchimp form, aweber, aweber form, paypal, paypal form, stripe, stripe form, getresponse, getresponse form, email subscription, contact form widget, user registration form, wordpress registration, wordpress login form
4
+ Requires at least: 4.5
5
+ Tested up to: 4.7
6
+ Stable tag: trunk
7
+ License: GNU General Public License v2.0 or later
8
+
9
+ The best WordPress contact form plugin. Drag & Drop online form builder that helps you create beautiful contact forms with just a few clicks.
10
+
11
+ == Description ==
12
+
13
+ = WordPress Contact Form Plugin =
14
+
15
+ We believe that you shouldn't have to hire a developer to create a WordPress contact form. That's why we built <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">WPForms</a>, a drag & drop WordPress form builder that's EASY and POWERFUL.
16
+
17
+ WPForms allow you to create beautiful contact forms, subscription forms, payment forms, and other type of forms for your site in minutes, not hours!
18
+
19
+ At WPForms, user experience is our #1 priority. Our pre-built form templates and workflows make WPForms the most beginner friendly contact form plugin in the market.
20
+
21
+ WPForms is 100% mobile responsive, so your forms will always look great on all devices (mobile, tablet, laptop, and desktop).
22
+
23
+ WPForms is also highly optimized for web and server performance because we understand the importance of speed when it comes to SEO and conversion. We can honestly say that WPForms is one of the fastest WordPress forms plugin available.
24
+
25
+ > <strong>WPForms Pro</strong><br />
26
+ > This plugin is the lite version of the WPForms Pro plugin that comes with all the form features you will ever need including email subscription forms, multi-page forms, file uploads, conditional logic, payment integrations, form templates, and tons more. <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">Click here to purchase the best premium WordPress contact form plugin now!</a>
27
+
28
+ We took the pain out of creating online forms and made it easy. Here's why smart business owners, designers, and developers love WPForms, and you will too!
29
+
30
+ https://www.youtube.com/watch?v=eiQ3viAGung&rel=0
31
+
32
+ = Drag & Drop Online Form Builder =
33
+
34
+ We were tired of the bloated and buggy contact form plugins. That's why we built WPForms to adapt to your workflow and allow you to create custom online forms in minutes. By using our easy to use <a href="https://wpforms.com/features/drag-drop-online-form-builder/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">drag and drop online form builder</a>, you can easy add custom form fields, rearrange them, and basically create a complete form in 5 minutes or less.
35
+
36
+ But don't just take our word. See what one of the WordPress experts are saying:
37
+
38
+ > WPForms is by far the <strong>easiest form plugin to use</strong>. My clients love it it’s one of the few plugins they can use without any training. As a developer I appreciate how fast, modern, clean and extensible it is.<br>
39
+ > Bill Erickson - Expert WordPress Consultant
40
+
41
+ = Pre-built Form Templates =
42
+
43
+ Building forms in WordPress can be time consuming. Why?
44
+
45
+ Because every other WordPress contact form plugin requires you to build your form from scratch. The truth is it’s often not necessary to create a form completely from scratch unless you really want to.
46
+
47
+ Whether you’re looking to create a simple contact form, request a quote form, donation form, payment order form, or a subscription form, we have a form template for you.
48
+
49
+ WPForms comes with <a href="https://wpforms.com/features/form-templates/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">pre-built form templates</a> to help you save time. You can add, remove, or re-arrange fields as necessary.
50
+
51
+ = Mobile Ready, SEO Friendly and Optimized for Speed =
52
+
53
+ WPForms is 100% responsive and mobile-friendly by default. We also optimized every query on the front-end and the back-end to ensure maximum speed - Yes, WPForms is one of the fastest WordPress contact form plugin.
54
+
55
+ You can embed your forms on any page with optimized title and description. With the speed and proper formatting, WPForms is also one of the most SEO friendly forms plugin.
56
+
57
+ = All the Fields & Features that You Need to Succeed =
58
+
59
+ From radio buttons to file uploads to multi-page forms, we have all the fields you need.
60
+
61
+ You can easily integrate your forms with an email marketing service or collect payments for bookings and orders. WPForms allows you to do it all.
62
+
63
+ The best part is, you can do it all without hiring a developer.
64
+
65
+ See what one business owner has to say about WPForms:
66
+
67
+ >As a business owner, time is my most valuable asset. WPForms allow me to create smart online forms with just a few clicks. With their pre-built form templates and the drag & drop builder, I can create a new form that works in less than 2 minutes without writing a single line of code. Well worth the investment.<br>
68
+ > David Henzel - Co-founder of MaxCDN
69
+
70
+ = Easy to Customize and Extend =
71
+
72
+ You can easily customize your WPForms with our section dividers, HTML blocks, an custom CSS.
73
+
74
+ We also knew that our developer friends may want to extend it further. That's why WPForms come with tons of hooks and filters to create custom functionality.
75
+
76
+ = Full WPForms Feature List =
77
+
78
+ * <a href="https://wpforms.com/features/drag-drop-online-form-builder/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Online Form Builder</a> - Our powerful drag & drop online form builder allows you to easily create WordPress contact forms and other online forms in just a few minutes without writing any code.
79
+ * 100% Responsive - Mobile Friendly
80
+ * <a href="https://wpforms.com/features/form-templates/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Form Templates</a> - Use our pre-built form templates to save time. Never start from scratch again.
81
+ * <a href="https://wpforms.com/features/spam-protection/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Spam Protection</a> - WPForms utilizes smart CAPTCHA and Honeypot method to stop spam form submissions.
82
+ * <a href="https://wpforms.com/features/instant-notifications/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Instant Form Notification</a> - Quickly respond to incoming inquiries with our instant form notification system.
83
+ * <a href="https://wpforms.com/features/form-confirmation/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Smart Form Confirmation</a> - Show a custom success message, or redirect users to a custom thank you page.
84
+ * <a href="https://wpforms.com/features/file-uploads/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">File Uploads</a> - Collect files and media through your online forms with File Uploads.
85
+ * <a href="https://wpforms.com/features/multi-page-forms/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Multi-Page Forms</a> - Split long forms into multiple pages to improve user experience.
86
+ * <a href="https://wpforms.com/addons/mailchimp-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">MailChimp Forms</a> - Create MailChimp newsletter signup forms in WordPress to grow your email list.
87
+ * <a href="https://wpforms.com/addons/aweber-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">AWeber Forms</a> - Create AWeber newsletter signup forms in WordPress to grow your email list.
88
+ * <a href="https://wpforms.com/addons/campaign-monitor-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Campaign Monitor Forms</a> - Create Campaign Monitor newsletter signup forms in WordPress to grow your email list.
89
+ * <a href="https://wpforms.com/addons/getresponse-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">GetResponse Forms</a> - Create GetResponse newsletter signup forms in WordPress to grow your email list.
90
+ * <a href="https://wpforms.com/addons/paypal-standard-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">PayPal Payment Forms</a> - Create PayPal forms to easily collect payments, donations, and online orders.
91
+ * <a href="https://wpforms.com/addons/stripe-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Stripe Forms</a> - Easily collect payments, donations, and online orders with our Stripe addon.
92
+ * <a href="https://wpforms.com/addons/user-registration-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">User Registration Forms</a> - Create custom WordPress user registration form.
93
+ * <a href="https://wpforms.com/addons/conditional-logic-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Smart Conditional Logic</a> - Show or hide fields and form sections based on user behavior.
94
+ * <a href="https://wpforms.com/addons/geolocation-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Geolocation</a> - Display location information about your users.
95
+ * <a href="https://wpforms.com/addons/custom-catpcha-addon/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">Custom Captchas</a> - Create custom captchas for your forms.
96
+ * Want us to add something else? Suggest a feature and we'll get it added!
97
+
98
+ After reading this feature list, you can probably imagine why WPForms is the best WordPress forms plugin in the market.
99
+
100
+ Give WPForms a try.
101
+
102
+ Want to unlock more features? <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">Upgrade to our Pro version</a>.
103
+
104
+
105
+ = Credits =
106
+
107
+ This plugin is created by <a href="http://www.jaredatchison.com/" rel="friend" title="Jared Atchison">Jared Atchison</a> and <a href="https://syedbalkhi.com/" rel="friend" title="Syed Balkhi">Syed Balkhi</a>.
108
+
109
+ = What's Next =
110
+
111
+ If you like this plugin, then consider checking out our other projects:
112
+
113
+ * <a href="http://optinmonster.com/" rel="friend" title="OptinMonster">OptinMonster</a> - Get More Email Subscribers
114
+ * <a href="http://soliloquywp.com/" rel="friend" title="Soliloquy">Soliloquy</a> - Best WordPress Slider Plugin
115
+ * <a href="http://enviragallery.com/" rel="friend" title="Envira Gallery">Envira Gallery</a> - Best WordPress Gallery Plugin
116
+
117
+ Visit <a href="http://www.wpbeginner.com/" rel="friend" title="WPBeginner">WPBeginner</a> to learn from our <a href="http://www.wpbeginner.com/category/wp-tutorials/" rel="friend" title="WordPress Tutorials">WordPress Tutorials</a> and find out about other <a href="http://www.wpbeginner.com/category/plugins/" rel="friend" title="Best WordPress Plugins">best WordPress plugins</a>.
118
+
119
+
120
+ == Installation ==
121
+
122
+ 1. Install WPForms Lite either via the WordPress.org plugin repository or by uploading the files to your server. (See instructions on <a href="http://www.wpbeginner.com/beginners-guide/step-by-step-guide-to-install-a-wordpress-plugin-for-beginners/" rel="friend">how to install a WordPress plugin</a>)
123
+ 2. Activate WPForms Lite.
124
+ 3. Navigate to the WPForms tab at the bottom of your admin menu and click the "Add New" button to begin creating your new WordPress contact form.
125
+ 4. Want more features? <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="WPForms">Purchase the full version of WPForms</a>!
126
+
127
+ == Screenshots ==
128
+
129
+ 1. WPForms Drag & Drop Online Form Builder
130
+ 2. WPForms Form Preview
131
+
132
+ == Frequently Asked Questions ==
133
+
134
+ = I'd like access to all features. How can I get them? =
135
+
136
+ You can get access to more features, Addons and support by <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="Click here to learn more about WPForms!">visiting the WPForms website and purchasing a support license</a>. Purchasing a support license gets you access to the full version of WPForms, automatic updates and support, and depending on the level of support license, you can even get exclusive access to WPForms Addons!
137
+
138
+ = Who should use WPForms? =
139
+
140
+ WPForms is perfect for business owners, bloggers, designers, developers, photographers, and basically everyone else. If you want to create a custom WordPress form, then you need to use WPForms.
141
+
142
+ = Do I need to have coding skills to use WPForms? =
143
+
144
+ Absolutely not. You can create and manage forms without any coding knowledge. WPForms is the most beginner friendly contact form solution in the market.
145
+
146
+ = Is WPForms translation ready? =
147
+
148
+ Yes, WPForms has full translation and localization support via the wpforms textdomain. All .mo and .po translation files should go into the languages folder in the base of the plugin. The same is true for every WPForms Addon as well.
149
+
150
+ == Notes ==
151
+
152
+ WPForms is absolutely, positively the most <a href="https://wpforms.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend" title="Best WordPress contact form plugin">beginner friendly WordPress contact form plugin</a> on the market. It is both easy and powerful.
153
+
154
+ We took the pain out of creating online forms and made it easy. Check out all <a href="https://wpforms.com/features/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion" rel="friend">WPForms features</a>.
155
+
156
+ Also, I'm the founder of <a href="http://www.wpbeginner.com/" rel="friend">WPBeginner</a>, the largest WordPress resource site for beginners. It was a huge priority for me to make a WordPress contact form plugin that beginners can use without any training.
157
+
158
+ I feel that we have done that here. I hope you enjoy using WPForms.
159
+
160
+ Thank you
161
+
162
+ Syed Balkhi
163
+
164
+ == Changelog ==
165
+
166
+ = 1.3.1 =
167
+ - Added: Smart Tags for author ID, email, and name
168
+ - Added: Carbon Copy (CC) support for form notifications; enable in WPForms Settings
169
+ - Fixed: Field duplication issues
170
+ - Fixed: TinyMCE "Add Form" button not opening modal with dynamic TinyMCE instances
171
+ - Fixed: Email formatting issues when using plain text formatting
172
+ - Fixed: Number field validation tripping when number submitted is zero
173
+ - Fixed: reCAPTCHA validation passing when reCAPTCHA left blank
174
+ - Fixed: Dropdown field size not reflecting in builder
175
+
176
+ = 1.3.0 =
177
+ - Added: Email field confirmantion
178
+ - Added: Support for Visual Composer
179
+ - Added: Field class to force elements to full-width on mobile devices, `wpforms-mobile-full`
180
+ - Changed: Placeholders are added/updated in real-time for Dropdown fields in the form builder
181
+ - Changed: Add empty value to select element placeholders when displaying form for better markup validation
182
+ - Fixed: Multiple instances of reCAPTCHA on a page not correctly loading
183
+ - Fixed: Field choice defaults not restoring in form builder
184
+ - Fixed: Field alignment issues in the form builder when dragging field more than once
185
+ - Fixed: PHP fatal erroring if form notification email address provided is not valid upon sending
186
+ - Fixed: Compatibility issuses when network activated on a Multisite install
187
+
188
+ = 1.2.9 =
189
+ - Added: Individual fields can be duplicated in the form builder
190
+ - Changed: How data is stored for fields using Dynanic Choices
191
+ - Fixed: Global assets setting causing errors in some cases
192
+ - Fixed: Writing setting ("correct invalidly nested XHTML") breaking forms containing HTML
193
+ - Fixed: Forms being displayed/included on the native WordPress Export page
194
+ - Fixed: Dynamic Choices erroring when used with Post Types
195
+ - Fixed: Form labels including blank IDs
196
+
197
+ = 1.2.8.1 =
198
+ - Fixed: Form javascript email validation being too strict (introducted in 1.2.8)
199
+
200
+ = 1.2.8 =
201
+ - Added: Dynamic choice feature for Dropdown, Multiple Choice, and Checkbox fields
202
+ - Changed: Loading order of templates and field classes - moved to `init`
203
+ - Changed: Form javascript email validation requires domain TLD to pass
204
+ - Fixed: HTML email notification templates uses site locale text-direction
205
+ - Fixed: Javascript in the form builder conflicting with certain locales
206
+
207
+ = 1.2.7 =
208
+ - Added: Store intial plugin activation date
209
+ - Added: Duplicate form submit protection
210
+ - Fixed: Strip slashes from entry data before processing
211
+
212
+ = 1.2.6 =
213
+ - Added: Miscellaneous internal improvements
214
+ - Fixed: Incorrectly named variables in the front-end javascript preventing features from properly being extendable
215
+
216
+ = 1.2.5.1 =
217
+ - Fixed: Removed duplicate Settings page title
218
+
219
+ = 1.2.5 =
220
+ - Added: Setting for Email template background color
221
+ - Added: Form setting for form wrapper CSS class
222
+ - Changed: Multiple Payment field stores Choice label text
223
+ - Changed: reCAPTCHA tweaks and added filter
224
+ - Changed: Improved IP detection
225
+ - Fixed: Mapped select fields in builder triggered JS error
226
+
227
+ = 1.2.4.1 =
228
+ - Fixed: Plugin settings page not correctly showing
229
+
230
+ = 1.2.4 =
231
+ - Added: Additional logging and error reporting
232
+ - Changed: Footer asset detection priority, for improved capatibility with other services
233
+ - Changed: Refactored and refined front-end javascript
234
+ - Fixed: Rogue PHP notices
235
+
236
+ = 1.2.3.2 =
237
+ - Fixed: Default field validation considered 0 as empty
238
+
239
+ = 1.2.3.1 =
240
+ - Fixed: Blank form email notification defaults
241
+
242
+ = 1.2.3 =
243
+ - Added: Form notification message setting
244
+ - Added: Additional Smart Tags available inside Form Settings panels
245
+ - Added: Process Smart Tags inside form confirmation messages and URLs
246
+ - Added: Hide WPForms Preview page from WordPress dashboard
247
+ - Added: System Details tab to WPForms Settings, to display debug information, etc
248
+ - Changed: Many form builder javascript improvements
249
+ - Changed: Improved internal logging and debugging tools
250
+ - Fixed: Large forms not always saving because of max_input_vars PHP setting
251
+
252
+ = 1.2.2.2 =
253
+ - Fixed: Javascript asset not loading due to incorrect path
254
+
255
+ = 1.2.2.1 =
256
+ - Fixed: Form select inside modal window overflowing when a form exists with a long title
257
+
258
+ = 1.2.2 =
259
+ - Changed: Choice Layouts now use flexbox instead of CSS columns for better rendering
260
+ - Fixed: Class name typo in a CSS column class introduced with 1.2.1
261
+ - Fixed: PHP notice on Entries page when there are no forms
262
+
263
+ = 1.2.1 =
264
+ * Added: Drag and drop field buttons - simply drag the desired field to the form!
265
+ * Added: Choice Layout option for Checkboxes and Multiple Choice fields (under Advanced Options)
266
+ * Added: Full and expanded column class/grid support
267
+ * Changed: Refactored CSS column classes, previous classes are deprecated
268
+ * Fixed: Form ending with column classes not closing correctly
269
+ * Fixed: reCAPTCHA button overlaying submit button preventing it from being clicked
270
+
271
+ = 1.2.0.1 =
272
+ * Changed: Improved field and column gutter consistency
273
+
274
+ = 1.2.0 =
275
+ * Added: Form preview
276
+ * Added: Column classes for Checkbox and Multiple choice inputs
277
+ * Changed: Some fields did not have the correct (unique) CSS ID, this has been corrected, which means custom styling may need to be adjusted
278
+ * Changed: Removed nonce verification
279
+
280
+ = 1.1.8.4 =
281
+ * Changed: Form notification settings hide if set to Off
282
+
283
+ = 1.1.8.3 =
284
+ * Fixed: Issue with submit button position when form ends with columns classes
285
+
286
+ = 1.1.8.2 =
287
+ * Changed: reCAPTCHA settings description to include link to how-to article
288
+
289
+ = 1.1.8.1 =
290
+ * Fixed: PHP warnings inside the form builder
291
+
292
+ = 1.1.8 =
293
+ * Changed: Moved email related settings into email settings group
294
+
295
+ = 1.1.7.2 =
296
+ * Added: "WPForm" to new-content admin bar menu item
297
+
298
+ = 1.1.7.1 =
299
+ * Changed: Removed "New" field name prefix
300
+
301
+ = 1.1.7 =
302
+ * Added: Smart Tag for Dropdown/Multiple choice raw values, allowing for conditional email addres notifications (https://wpforms.com/docs/how-to-create-conditional-form-notifications-in-wpforms)
303
+ * Added: Three column CSS field classes (https://wpforms.com/docs/how-to-create-multi-column-form-layouts-in-wpforms/)
304
+ * Changed: Checkbox/Multiple Choice fields allow certain HTML to display in choice labels
305
+
306
+ = 1.1.6.1 =
307
+ * Added: Support for WordPress Zero Spam plugin (https://wordpress.org/plugins/zero-spam/)
308
+ * Fixed: Issue when stacking fields with 2 column classes
309
+
310
+ = 1.1.5.3 =
311
+ * Changed: Email Header Image setting description to include recommended sizing
312
+
313
+ = 1.1.5.2 =
314
+ * Fixed: reCAPTCHA cutting off with full form theme
315
+
316
+ = 1.1.5.1 =
317
+ * Fixed: Debug output from wpforms.js
318
+
319
+ = 1.1.5 =
320
+ * Changed: HTML Email template footer text appearance
321
+
322
+ = 1.1.4.2 =
323
+ * Fixed: HTML emails not displaying correctly in Thunderbird
324
+
325
+ = 1.1.4.1 =
326
+ * Fixed: Form builder textareas not displaying full width
327
+
328
+ = 1.1.4 =
329
+ * Added: Form general setting for "Submit Button CSS Class"
330
+ * Added: Duplicate forms from the Forms Overview page (All Forms)
331
+ * Changed: Adjusted field display inside the Form Builder to better resemble full theme
332
+ * Fixed: Don't allow inserting shortcode via modal if there are no forms
333
+ * Fixed: Error when deleting a form
334
+
335
+ = 1.1.3.2 =
336
+ * Added: Suggestion form template
337
+
338
+ = 1.1.3.1 =
339
+ * Fixed: Form base theme CSS compatibility issue with Firefox
340
+
341
+ = 1.1.3 =
342
+ * Added: New class that handles sending/processing emails
343
+ * Added: Form notification setting for "From Address", defaults to site administrator's email address
344
+ * Added: HTML email template for sleek emails (enabled by default, see more below)
345
+ * Added: General setting to configure email notification format
346
+ * Added: General setting to optionally configure email notification header image
347
+ * Changed: Default email notification format is now HTML, can go back to plain text format via option on WPForms > Settings page
348
+ * Changed: Empty fields are no longer included in email notifications
349
+ * Fixed: Issue with Checkbox field when empty
350
+
351
+ = 1.1.2 =
352
+ * Added: Form option to scroll page to form after submit, defaults on for new forms
353
+ * Changed: Revamped "Full" form theme to be more consistent across different themes, browsers, and devices
354
+ * Changed: Full theme and bare theme separated
355
+
356
+ = 1.1.1.1 =
357
+ * Changed: Upgrade information
358
+
359
+ = 1.1.1 =
360
+ * Fixed: Settings page typo
361
+
362
+ = 1.1 =
363
+ * Changed: CSS updates to improve compatibility
364
+ * Fixed: PHP notices when saving plugin Settings
365
+
366
+ = 1.0.9 =
367
+ * Changed: Email field required by default
368
+
369
+ = 1.0.8 =
370
+ * Fixed: Name field setting always showing Required
371
+ * Fixed: Debug function incorrectly requiring WP_DEBUG
372
+
373
+ = 1.0.7 =
374
+ * Changed: CSS tweaks
375
+ * Fixed: Filter (wpforms_manage_cap) incorrectly named in some instances
376
+
377
+ = 1.0.6 =
378
+ * Added: Embed button inside the Form Builder
379
+ * Added: Basic two column CSS class support
380
+ * Added: French translation
381
+ * Changed: Form names are no longer required, if no form name is provided the template name is used
382
+ * Changed: Inputmask script, for better broad device support
383
+ * Changed: Field specific assets are now conditionally loaded
384
+ * Changed: CSS tweaks for form display
385
+ * Fixed: Issue with Date/Time field
386
+ * Fixed: Issue Address field preventing Country select from hiding in some configurations
387
+ * Fixed: Localization string errors
388
+
389
+ = 1.0.5 =
390
+ * Changed: Checkboxes/Dropdown/Multiple Choice fields always show choice label value in e-mail notifications
391
+ * Fixed: PHP notices inside the Form Builder
392
+ * Fixed: Typo inside Form Builder tooltip
393
+
394
+ = 1.0.4.2 =
395
+ * Changed: Removed files not needed for WordPress.org release [Lite]
396
+
397
+ = 1.0.4.1 =
398
+ * Added: Check for TinyMCE in the builder before triggering TinyMCE save
399
+ * Fixed: Sub labels showing when configured to hide
400
+ * Fixed: Forms pagination number screen setting not saving
401
+ * Fixed: Email notification setting always displaying "On"
402
+
403
+ = 1.0.4 =
404
+ * Changed: Improved marketing provider conditional logic
405
+ * Changed: Addons page [Lite]
406
+ * Fixed: Variable assignment in the builder
407
+
408
+ = 1.0.3 =
409
+ * Added: Basic TinyMCE editor for form confirmation messages
410
+ * Changed: Removed form ID from form overview table, ID still visible in shortcode column
411
+ * Fixed: Checkbox/radio form elements alignment
412
+ * Fixed: Quotation slashes in email notification text
413
+ * Fixed: SSL verification preventing proper API calls on some servers
414
+
415
+ = 1.0.2 =
416
+ * Added: Widget to display form
417
+ * Added: Function to display form, `wpforms_display( $form_id )`
418
+ * Changed: Default notification settings for Contact form template
419
+ * Changed: Success message styling for full form theme
420
+
421
+ = 1.0.1 =
422
+ * Added: "From Name" and "Reply To" Setting>Notification fields
423
+ * Added: Smart Tags feature to all Setting>Notification fields
424
+
425
+ = 1.0.0 =
426
+ * Initial release.