Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms - Version 1.5.0

Version Description

  • Improvement: Forms are now submitted without page refresh.
  • Improvement: Submitted values are preserved after an unsuccessful submission.
  • Improvement: Added new filters for greater part rendering customization.
  • Improvement: Added new actions for integration with third party plugins and tools.
  • Improvement: Scale part now support range selection.
  • Improvement: Better management of years displayed in Date & Time part.
  • Improvement: Order of month and day fields in Date & Time part now defaults to a date format setting in WordPress.
  • Improvement: Month names in Date & Time part have been moved to an array and are now easy to translate.
  • Bug fix: Various UI glitches affected form previews in Customize screen.
  • Bug fix: Various UI glitches affected part rendering of labels and preset values.
Download this release

Release Info

Developer thethemefoundry
Plugin Icon 128x128 Form builder to get in touch with visitors, grow your email list and collect payments — Happyforms
Version 1.5.0
Comparing to
See all releases

Code changes from version 1.4.6 to 1.5.0

Files changed (71) hide show
  1. assets/css/frontend.css +145 -64
  2. assets/css/preview.css +2 -1
  3. assets/js/customize.js +72 -93
  4. assets/js/frontend.js +130 -144
  5. assets/js/frontend/address.js +12 -14
  6. assets/js/frontend/date.js +191 -165
  7. assets/js/frontend/number.js +2 -10
  8. assets/js/frontend/phone.js +52 -39
  9. assets/js/frontend/rating.js +19 -0
  10. assets/js/frontend/recaptcha.js +77 -0
  11. assets/js/frontend/scale.js +86 -21
  12. assets/js/lib/multirange.js +87 -0
  13. assets/js/parts/part-date.js +43 -0
  14. assets/js/parts/part-scale.js +84 -41
  15. assets/js/preview.js +21 -1
  16. happyforms.php +2 -2
  17. inc/classes/class-email-message.php +14 -10
  18. inc/classes/class-form-admin.php +24 -4
  19. inc/classes/class-form-controller.php +66 -6
  20. inc/classes/class-form-part.php +0 -6
  21. inc/classes/class-happyforms-plugin.php +3 -3
  22. inc/classes/class-message-controller.php +92 -71
  23. inc/classes/class-message-notices.php +0 -191
  24. inc/classes/class-session.php +140 -0
  25. inc/classes/class-wp-customize-form-manager.php +0 -17
  26. inc/classes/parts/class-part-address.php +55 -29
  27. inc/classes/parts/class-part-checkbox.php +21 -28
  28. inc/classes/parts/class-part-date.php +120 -84
  29. inc/classes/parts/class-part-email.php +44 -51
  30. inc/classes/parts/class-part-legal.php +4 -24
  31. inc/classes/parts/class-part-multi-line-text.php +16 -20
  32. inc/classes/parts/class-part-number.php +46 -50
  33. inc/classes/parts/class-part-phone.php +298 -274
  34. inc/classes/parts/class-part-placeholder.php +13 -3
  35. inc/classes/parts/class-part-radio.php +13 -32
  36. inc/classes/parts/class-part-rating.php +33 -25
  37. inc/classes/parts/class-part-scale.php +59 -28
  38. inc/classes/parts/class-part-select.php +8 -27
  39. inc/classes/parts/class-part-single-line-text.php +16 -20
  40. inc/classes/parts/class-part-title.php +15 -35
  41. inc/classes/parts/class-part-website-url.php +18 -26
  42. inc/helpers/helper-activation.php +2 -6
  43. inc/helpers/helper-form-templates.php +91 -41
  44. inc/helpers/helper-misc.php +22 -0
  45. inc/templates/admin-message-edit.php +10 -4
  46. inc/templates/customize-form-setup.php +16 -16
  47. inc/templates/parts/customize-date.php +18 -3
  48. inc/templates/parts/customize-phone.php +5 -7
  49. inc/templates/parts/customize-scale.php +22 -7
  50. inc/templates/parts/frontend-address.php +4 -4
  51. inc/templates/parts/frontend-checkbox.php +9 -5
  52. inc/templates/parts/frontend-date-day.php +11 -0
  53. inc/templates/parts/frontend-date-month.php +12 -0
  54. inc/templates/parts/frontend-date.php +37 -33
  55. inc/templates/parts/frontend-email.php +6 -17
  56. inc/templates/parts/frontend-legal.php +1 -1
  57. inc/templates/parts/frontend-multi-line-text.php +2 -2
  58. inc/templates/parts/frontend-number.php +12 -17
  59. inc/templates/parts/frontend-phone.php +10 -15
  60. inc/templates/parts/frontend-placeholder.php +1 -1
  61. inc/templates/parts/frontend-radio.php +6 -4
  62. inc/templates/parts/frontend-rating.php +1 -1
  63. inc/templates/parts/frontend-scale.php +26 -12
  64. inc/templates/parts/frontend-select.php +7 -5
  65. inc/templates/parts/frontend-single-line-text.php +2 -2
  66. inc/templates/parts/frontend-title.php +5 -3
  67. inc/templates/parts/frontend-website-url.php +2 -2
  68. inc/templates/preview-form-edit.php +10 -32
  69. inc/templates/single-form.php +10 -3
  70. languages/happyforms.pot +508 -442
  71. readme.txt +17 -2
assets/css/frontend.css CHANGED
@@ -16,6 +16,8 @@
16
  --happyforms-color-submit-background-hover: #dbdbdb;
17
  --happyforms-color-submit-background-focus: #dbdbdb;
18
  --happyforms-color-submit-border: transparent;
 
 
19
  --happyforms-color-rating: #ccc;
20
  --happyforms-color-rating-hover: #f39c00;
21
  /* font */
@@ -136,22 +138,22 @@ h3.happyforms-form__title {
136
  .happyforms-part input[type=tel],
137
  .happyforms-part input[type=number],
138
  .happyforms-part input[type=range],
139
- .happyforms-part textarea {
140
  width: 100%;
141
  max-width: none;
142
  height: auto !important;
143
  padding: 10px;
144
  border-width: 1px;
145
  border-style: solid;
146
- border-color: #dbdbdb;
147
- border-color: var(--happyforms-color-part-border);
148
  border-radius: 6px;
149
  box-shadow: none;
150
  font-style: normal;
151
  font-size: 16px;
152
  font-size: var(--happyforms-part-value-font-size);
153
- background-color: #fff;
154
- background-color: var(--happyforms-color-part-background);
155
  color: #000;
156
  color: var(--happyforms-color-part-value);
157
  transition-property: none;
@@ -207,7 +209,7 @@ h3.happyforms-form__title {
207
  .happyforms-form--part-border-off .happyforms-part input[type=number],
208
  .happyforms-form--part-border-off .happyforms-part input[type=range],
209
  .happyforms-form--part-border-off .happyforms-part textarea {
210
- border-color: transparent;
211
  }
212
 
213
  .happyforms-part input[type=text]:focus,
@@ -218,10 +220,10 @@ h3.happyforms-form__title {
218
  outline: 0;
219
  border-width: 1px;
220
  border-style: solid;
221
- border-color: #000;
222
- border-color: var(--happyforms-color-part-border-focus);
223
- background-color: #fff;
224
- background-color: var(--happyforms-color-part-background-focus);
225
  }
226
 
227
  .happyforms-part select:focus {
@@ -233,7 +235,7 @@ h3.happyforms-form__title {
233
  .happyforms-form--part-border-off .happyforms-part input[type=tel]:focus,
234
  .happyforms-form--part-border-off .happyforms-part input[type=number]:focus,
235
  .happyforms-form--part-border-off .happyforms-part textarea:focus {
236
- border-color: transparent;
237
  }
238
 
239
  .happyforms-part.happyforms-part--error input[type=text],
@@ -308,6 +310,7 @@ h3.happyforms-form__title {
308
  .happyforms-part--label-below .happyforms-part__label {
309
  order: 2;
310
  width: 100%;
 
311
  margin-bottom: 5px;
312
  }
313
 
@@ -826,13 +829,62 @@ h3.happyforms-form__title {
826
  color: var(--happyforms-color-part-value);
827
  }
828
 
 
 
 
 
 
829
  .happyforms-part--scale__labels {
830
  position: relative;
831
  width: 100%;
 
 
832
  color: #aaa;
833
  color: var(--happyforms-color-part-placeholder);
834
  }
835
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836
  .happyforms-part--scale__labels .label-min {
837
  float: left;
838
  }
@@ -1108,6 +1160,10 @@ h3.happyforms-form__title {
1108
  stroke: var(--happyforms-color-rating-hover);
1109
  }
1110
 
 
 
 
 
1111
  .happyforms-part--rating label {
1112
  display: inline;
1113
  fill: inherit;
@@ -1366,8 +1422,8 @@ input[type=submit][disabled] {
1366
  height: auto;
1367
  padding: 17px 50px;
1368
  border-radius: 6px;
1369
- border: 1px solid transparent;
1370
- border-color: var(--happyforms-color-submit-border);
1371
  font-weight: normal;
1372
  font-style: normal;
1373
  font-size: 18px;
@@ -1392,8 +1448,8 @@ input[type=submit][disabled].happyforms-button--submit:hover {
1392
  input[type=submit].happyforms-button--submit:hover,
1393
  input[type=submit][disabled].happyforms-button--submit:hover {
1394
  border-radius: 6px;
1395
- border-color: transparent;
1396
- border-color: var(--happyforms-color-submit-border);
1397
  background-color: #dbdbdb;
1398
  background-color: var(--happyforms-color-submit-background-hover);
1399
  text-transform: none;
@@ -1413,68 +1469,44 @@ input[type=submit].happyforms-button--submit:focus {
1413
  }
1414
 
1415
  /* notices */
1416
-
1417
- .happyforms-message-notice h2 {
1418
- margin-top: 0;
1419
- margin-bottom: 0;
1420
- font-weight: bold;
1421
- font-size: 14px !important;
1422
- padding: 20px;
1423
- color: #000;
1424
- color: var(--happyforms-color-primary);
1425
- }
1426
-
1427
- .happyforms-message-notice.error h2 {
1428
- margin-top: 0;
1429
- margin-bottom: 5px;
1430
- padding: 0;
1431
- font-weight: normal;
1432
- color: #ff7550;
1433
- color: var(--happyforms-color-error);
1434
- }
1435
-
1436
- .happyforms-message-notice.success h2,
1437
- .happyforms-message-notice.error-submission h2 {
1438
- margin-top: 0 !important;
1439
- margin-bottom: 0 !important;
1440
- padding-top: 0 !important;
1441
- padding-bottom: 0 !important;
1442
- font-size: 16px !important;
1443
  }
1444
 
1445
- .happyforms-message-notice.success,
1446
- .happyforms-message-notice.error-submission {
1447
- padding: 25px 0;
1448
  border: 3px solid;
1449
- border-width: 3px;
1450
- border-color: #000;
1451
- border-color: var(--happyforms-color-primary);
1452
  background-color: transparent;
 
1453
  }
1454
 
1455
- .happyforms-message-notice.success h2 {
1456
- color: #39b54a;
1457
- color: var(--happyforms-color-success);
1458
  }
1459
 
1460
- .happyforms-message-notice.error-submission {
1461
  border-color: #ff7550;
1462
  border-color: var(--happyforms-color-error);
1463
  }
1464
 
1465
- .happyforms-part .happyforms-message-notices {
1466
- padding: 0;
 
 
 
 
1467
  }
1468
 
1469
- .happyforms-part .happyforms-message-notices h2 {
1470
- font-size: 14px;
 
 
1471
  }
1472
 
1473
- .happyforms-part .happyforms-error+input,
1474
- .happyforms-part .happyforms-error+textarea {
1475
- border: 2px solid;
1476
- border-color: #ff7550;
1477
- border-color: var(--happyforms-color-error);
1478
  }
1479
 
1480
  .happyforms-form__title+.happyforms-message-notices {
@@ -1576,6 +1608,10 @@ input[type=submit].happyforms-button--submit:focus {
1576
  padding-top: 35px !important;
1577
  }
1578
 
 
 
 
 
1579
  /* part borders */
1580
  .happyforms-form--part-borders-bottom-only .happyforms-part input[type=text],
1581
  .happyforms-form--part-borders-bottom-only .happyforms-part input[type=email],
@@ -1642,6 +1678,7 @@ input[type=submit].happyforms-button--submit:focus {
1642
  /* part padding */
1643
 
1644
  .happyforms-form--part-outer-padding-narrow .happyforms-form__part {
 
1645
  padding: 0 0.5%;
1646
  }
1647
 
@@ -1683,13 +1720,20 @@ input[type=submit].happyforms-button--submit:focus {
1683
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=email],
1684
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=tel],
1685
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=number],
1686
- .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=range],
1687
  .happyforms-form--part-inner-padding-narrow .happyforms-part textarea,
1688
  .happyforms-form--part-inner-padding-narrow .happyforms-part select,
1689
  .happyforms-form--part-inner-padding-narrow .happyforms-part .option-label {
1690
  padding: 5px;
1691
  }
1692
 
 
 
 
 
 
 
 
 
1693
  .happyforms-form--part-inner-padding-narrow .happyforms-part--checkbox .option-label {
1694
  margin-right: 0;
1695
  margin-bottom: 0;
@@ -1705,7 +1749,6 @@ input[type=submit].happyforms-button--submit:focus {
1705
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=email],
1706
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=tel],
1707
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=number],
1708
- .happyforms-form--part-inner-padding-wide .happyforms-part input[type=range],
1709
  .happyforms-form--part-inner-padding-wide .happyforms-part textarea,
1710
  .happyforms-form--part-inner-padding-wide .happyforms-part select,
1711
  .happyforms-form--part-inner-padding-wide .happyforms-part .option-label {
@@ -1786,4 +1829,42 @@ input[type=submit].happyforms-button--submit:focus {
1786
  .widget input[type=submit][disabled].happyforms-button--submit,
1787
  .widget input[type=submit][disabled].happyforms-button--submit:hover {
1788
  width: 100%;
1789
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  --happyforms-color-submit-background-hover: #dbdbdb;
17
  --happyforms-color-submit-background-focus: #dbdbdb;
18
  --happyforms-color-submit-border: transparent;
19
+ --happyforms-color-submit-text: #fff;
20
+ --happyforms-color-submit-text-hover: #000;
21
  --happyforms-color-rating: #ccc;
22
  --happyforms-color-rating-hover: #f39c00;
23
  /* font */
138
  .happyforms-part input[type=tel],
139
  .happyforms-part input[type=number],
140
  .happyforms-part input[type=range],
141
+ .happyforms-part textarea.happyforms-part__el {
142
  width: 100%;
143
  max-width: none;
144
  height: auto !important;
145
  padding: 10px;
146
  border-width: 1px;
147
  border-style: solid;
148
+ border-color: #dbdbdb !important;
149
+ border-color: var(--happyforms-color-part-border) !important;
150
  border-radius: 6px;
151
  box-shadow: none;
152
  font-style: normal;
153
  font-size: 16px;
154
  font-size: var(--happyforms-part-value-font-size);
155
+ background-color: #fff !important;
156
+ background-color: var(--happyforms-color-part-background) !important;
157
  color: #000;
158
  color: var(--happyforms-color-part-value);
159
  transition-property: none;
209
  .happyforms-form--part-border-off .happyforms-part input[type=number],
210
  .happyforms-form--part-border-off .happyforms-part input[type=range],
211
  .happyforms-form--part-border-off .happyforms-part textarea {
212
+ border-color: transparent !important;
213
  }
214
 
215
  .happyforms-part input[type=text]:focus,
220
  outline: 0;
221
  border-width: 1px;
222
  border-style: solid;
223
+ border-color: #000 !important;
224
+ border-color: var(--happyforms-color-part-border-focus) !important;
225
+ background-color: #fff !important;
226
+ background-color: var(--happyforms-color-part-background-focus) !important;
227
  }
228
 
229
  .happyforms-part select:focus {
235
  .happyforms-form--part-border-off .happyforms-part input[type=tel]:focus,
236
  .happyforms-form--part-border-off .happyforms-part input[type=number]:focus,
237
  .happyforms-form--part-border-off .happyforms-part textarea:focus {
238
+ border-color: transparent !important;
239
  }
240
 
241
  .happyforms-part.happyforms-part--error input[type=text],
310
  .happyforms-part--label-below .happyforms-part__label {
311
  order: 2;
312
  width: 100%;
313
+ margin-top: 10px;
314
  margin-bottom: 5px;
315
  }
316
 
829
  color: var(--happyforms-color-part-value);
830
  }
831
 
832
+ .happyforms-part--scale output span {
833
+ position: absolute;
834
+ left: 0;
835
+ }
836
+
837
  .happyforms-part--scale__labels {
838
  position: relative;
839
  width: 100%;
840
+ font-size: 16px;
841
+ font-size: var(--happyforms-part-value-font-size);
842
  color: #aaa;
843
  color: var(--happyforms-color-part-placeholder);
844
  }
845
 
846
+ .happyforms-part--scale-multiple .happyforms-part--scale__labels {
847
+ position: absolute;
848
+ top: -40px;
849
+ }
850
+
851
+ .happyforms-part--label-left .happyforms-part--scale__inputwrap {
852
+ position: relative;
853
+ top: 10px;
854
+ float: right;
855
+ width: 75%;
856
+ }
857
+
858
+ .happyforms-part--scale-multiple .happyforms-part--scale__inputwrap {
859
+ position: relative;
860
+ }
861
+
862
+ .happyforms-part--label-below .happyforms-part--scale__inputwrap {
863
+ width: 100%;
864
+ order: 3;
865
+ }
866
+
867
+ .happyforms-part--scale-multiple.happyforms-part--label-left {
868
+ margin-top: 30px;
869
+ }
870
+
871
+ .happyforms-part--scale-multiple.happyforms-part--label-below .happyforms-part--scale__inputwrap {
872
+ position: relative;
873
+ top: 40px;
874
+ }
875
+
876
+ .happyforms-part--scale-multiple.happyforms-part--label-below label {
877
+ margin-top: 75px;
878
+ }
879
+
880
+ .happyforms-part--label-above.happyforms-part--scale-multiple .happyforms-part--scale__inputwrap {
881
+ padding-top: 30px;
882
+ }
883
+
884
+ .happyforms-part--label-above.happyforms-part--scale-multiple .happyforms-part--scale__labels {
885
+ top: -15px;
886
+ }
887
+
888
  .happyforms-part--scale__labels .label-min {
889
  float: left;
890
  }
1160
  stroke: var(--happyforms-color-rating-hover);
1161
  }
1162
 
1163
+ .happyforms-part--rating .happyforms-part__label {
1164
+ display: block;
1165
+ }
1166
+
1167
  .happyforms-part--rating label {
1168
  display: inline;
1169
  fill: inherit;
1422
  height: auto;
1423
  padding: 17px 50px;
1424
  border-radius: 6px;
1425
+ border: 1px solid transparent !important;
1426
+ border-color: var(--happyforms-color-submit-border) !important;
1427
  font-weight: normal;
1428
  font-style: normal;
1429
  font-size: 18px;
1448
  input[type=submit].happyforms-button--submit:hover,
1449
  input[type=submit][disabled].happyforms-button--submit:hover {
1450
  border-radius: 6px;
1451
+ border-color: transparent !important;
1452
+ border-color: var(--happyforms-color-submit-border) !important;
1453
  background-color: #dbdbdb;
1454
  background-color: var(--happyforms-color-submit-background-hover);
1455
  text-transform: none;
1469
  }
1470
 
1471
  /* notices */
1472
+ form > .happyforms-message-notices {
1473
+ padding: 0 1%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1474
  }
1475
 
1476
+ form > .happyforms-message-notices .happyforms-message-notice {
1477
+ padding: 25px;
 
1478
  border: 3px solid;
 
 
 
1479
  background-color: transparent;
1480
+ color: var(--happyforms-color-primary);
1481
  }
1482
 
1483
+ form > .happyforms-message-notices .success {
1484
+ border-color: #39b54a;
1485
+ border-color: var(--happyforms-color-success);
1486
  }
1487
 
1488
+ form > .happyforms-message-notices .error {
1489
  border-color: #ff7550;
1490
  border-color: var(--happyforms-color-error);
1491
  }
1492
 
1493
+ .happyforms-message-notices h2 {
1494
+ margin-top: 0 !important;
1495
+ margin-bottom: 0 !important;
1496
+ padding-top: 0 !important;
1497
+ padding-bottom: 0 !important;
1498
+ font-size: 16px !important;
1499
  }
1500
 
1501
+ .happyforms-form__part .happyforms-message-notices h2 {
1502
+ font-weight: normal !important;
1503
+ font-size: 16px !important;
1504
+ font-size: var(--happyforms-part-value-font-size) !important;
1505
  }
1506
 
1507
+ .happyforms-form__part .happyforms-message-notice.error h2 {
1508
+ color: #ff7550;
1509
+ color: var(--happyforms-color-error);
 
 
1510
  }
1511
 
1512
  .happyforms-form__title+.happyforms-message-notices {
1608
  padding-top: 35px !important;
1609
  }
1610
 
1611
+ .happyforms-part--label-as_placeholder a.address-geolocate {
1612
+ padding-top: 25px !important;
1613
+ }
1614
+
1615
  /* part borders */
1616
  .happyforms-form--part-borders-bottom-only .happyforms-part input[type=text],
1617
  .happyforms-form--part-borders-bottom-only .happyforms-part input[type=email],
1678
  /* part padding */
1679
 
1680
  .happyforms-form--part-outer-padding-narrow .happyforms-form__part {
1681
+ margin-bottom: 5px;
1682
  padding: 0 0.5%;
1683
  }
1684
 
1720
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=email],
1721
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=tel],
1722
  .happyforms-form--part-inner-padding-narrow .happyforms-part input[type=number],
 
1723
  .happyforms-form--part-inner-padding-narrow .happyforms-part textarea,
1724
  .happyforms-form--part-inner-padding-narrow .happyforms-part select,
1725
  .happyforms-form--part-inner-padding-narrow .happyforms-part .option-label {
1726
  padding: 5px;
1727
  }
1728
 
1729
+ .happyforms-form--part-inner-padding-narrow .happyforms-part__label {
1730
+ margin-bottom: 5px;
1731
+ }
1732
+
1733
+ .happyforms-form--part-inner-padding-narrow .happyforms-part--label-below .happyforms-part__label {
1734
+ margin-top: 5px;
1735
+ }
1736
+
1737
  .happyforms-form--part-inner-padding-narrow .happyforms-part--checkbox .option-label {
1738
  margin-right: 0;
1739
  margin-bottom: 0;
1749
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=email],
1750
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=tel],
1751
  .happyforms-form--part-inner-padding-wide .happyforms-part input[type=number],
 
1752
  .happyforms-form--part-inner-padding-wide .happyforms-part textarea,
1753
  .happyforms-form--part-inner-padding-wide .happyforms-part select,
1754
  .happyforms-form--part-inner-padding-wide .happyforms-part .option-label {
1829
  .widget input[type=submit][disabled].happyforms-button--submit,
1830
  .widget input[type=submit][disabled].happyforms-button--submit:hover {
1831
  width: 100%;
1832
+ }
1833
+
1834
+ /* multirange */
1835
+ @supports (--css: variables) {
1836
+ input[type="range"].multirange {
1837
+ padding: 0;
1838
+ margin: 0;
1839
+ display: inline-block;
1840
+ vertical-align: top;
1841
+ }
1842
+ input[type="range"].multirange.original {
1843
+ position: absolute;
1844
+ }
1845
+ input[type="range"].multirange.original::-webkit-slider-thumb {
1846
+ position: relative;
1847
+ z-index: 2;
1848
+ }
1849
+ input[type="range"].multirange.original::-moz-range-thumb {
1850
+ transform: scale(1);
1851
+ /* FF doesn't apply position it seems */
1852
+ z-index: 1;
1853
+ }
1854
+ input[type="range"].multirange::-moz-range-track {
1855
+ border-color: transparent;
1856
+ /* needed to switch FF to "styleable" control */
1857
+ }
1858
+ input[type="range"].multirange.ghost {
1859
+ position: relative;
1860
+ background: var(--track-background);
1861
+ --track-background: linear-gradient(to right, var(--happyforms-color-part-border) var(--low), var(--range-color) 0, var(--range-color) var(--high), var(--happyforms-color-part-border) 0) no-repeat 0 45% / 100% 10%;
1862
+ --range-color: var(--happyforms-color-part-value);
1863
+ }
1864
+ input[type="range"].multirange.ghost::-webkit-slider-runnable-track {
1865
+ background: var(--track-background);
1866
+ }
1867
+ input[type="range"].multirange.ghost::-moz-range-track {
1868
+ background: var(--track-background);
1869
+ }
1870
+ }
assets/css/preview.css CHANGED
@@ -64,6 +64,7 @@ body::before, body::after {
64
  outline: 1px solid lightblue;
65
  }
66
 
67
- a.happyforms-ask-link {
 
68
  cursor: pointer !important;
69
  }
64
  outline: 1px solid lightblue;
65
  }
66
 
67
+ a.happyforms-ask-link,
68
+ a.happyforms-ask-link.customize-unpreviewable {
69
  cursor: pointer !important;
70
  }
assets/js/customize.js CHANGED
@@ -151,8 +151,8 @@
151
 
152
  flushBuffer: function() {
153
  if ( this.buffer.length > 0 ) {
154
- _.each( this.buffer, function( response ) {
155
- api.previewer.send( 'happyforms-form-part-add', response );
156
  } );
157
 
158
  this.buffer = [];
@@ -531,7 +531,10 @@
531
  if ( happyForms.previewer.ready ) {
532
  api.previewer.send( 'happyforms-form-part-add', response );
533
  } else {
534
- happyForms.buffer.push( response );
 
 
 
535
  }
536
  } );
537
  },
@@ -553,7 +556,10 @@
553
  if ( happyForms.previewer.ready ) {
554
  api.previewer.send( 'happyforms-form-part-add', response );
555
  } else {
556
- happyForms.buffer.push( response );
 
 
 
557
  }
558
  } );
559
  },
@@ -573,6 +579,11 @@
573
 
574
  if ( happyForms.previewer.ready ) {
575
  api.previewer.send( 'happyforms-form-part-remove', partModel.id );
 
 
 
 
 
576
  }
577
  },
578
 
@@ -1025,24 +1036,29 @@
1025
  */
1026
  onLabelPlacementChange: function( model, value, options ) {
1027
  var $select = $( '[data-bind=label_placement]', this.$el );
1028
- $select.val( this.model.get( 'label_placement' ) );
1029
-
1030
- if ( ! options.skipGlobalReveal ) {
1031
- var $globalWrap = this.$( '.label_placement-options', this.$el );
1032
- // reset global checkbox
1033
- this.$( 'input', $globalWrap ).prop( 'checked', false );
1034
- // fade in the global checkbox wrapper
1035
- $globalWrap.fadeIn();
1036
- }
1037
 
1038
- this.model.fetchHtml( function( response ) {
1039
- var data = {
1040
- id: model.get( 'id' ),
1041
- html: response,
1042
- };
1043
 
1044
- api.previewer.send( 'happyforms-form-part-refresh', data );
1045
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1046
  },
1047
 
1048
  onCSSClassChange: function( model, value, options ) {
@@ -1120,6 +1136,9 @@
1120
  classes.views.Base.prototype.initialize.apply( this, arguments );
1121
 
1122
  this.listenTo( this.model, 'change:captcha', this.onChangeCaptcha );
 
 
 
1123
  },
1124
 
1125
  render: function() {
@@ -1196,13 +1215,6 @@
1196
  }
1197
 
1198
  this.model.set( attribute, value );
1199
-
1200
- if ( $el.data( 'preview-selector' ) && happyForms.previewLoaded ) {
1201
- api.previewer.send( 'happyforms-part-dom-update', {
1202
- selector: $el.data( 'preview-selector' ),
1203
- text: value,
1204
- } );
1205
- }
1206
  },
1207
 
1208
  onHelpMouseOver: function( e ) {
@@ -1233,6 +1245,27 @@
1233
  } else {
1234
  $captchaSettings.hide();
1235
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1236
  },
1237
 
1238
  remove: function() {
@@ -1250,13 +1283,6 @@
1250
  events: {
1251
  'click h3.accordion-section-title': 'onGroupClick',
1252
  'click .customize-panel-back': 'onGroupBackClick',
1253
- // 'change input[type=checkbox]': 'onCheckboxChange',
1254
- // 'keyup #hf_style_required_text': 'onRequiredTextChange',
1255
- // 'change #hf_style_disable_button_until_required_filled': 'onDisableButtonChange',
1256
- // 'change .happyforms-buttonset-container input': 'onInputChange',
1257
- // 'change input[type=number]': 'onInputChange',
1258
- // 'change input[type=text]': 'onInputChange',
1259
- // 'change select': 'onInputChange'
1260
  'change [data-target="form_class"] input': 'onFormClassChange',
1261
  'change [data-target="form_class"] select': 'onFormClassChange',
1262
  'change [data-target="form_class"] input[type="checkbox"]': 'onFormClassCheckboxChange',
@@ -1529,63 +1555,6 @@
1529
 
1530
  api.previewer.send('happyforms-css-variable-update', data);
1531
  },
1532
-
1533
- onCheckboxChange: function( e ) {
1534
- var $el = $( e.target );
1535
- var value = $el.is( ':checked' ) ? 1 : 0;
1536
-
1537
- this.model.set( $el.attr( 'data-attribute' ), value );
1538
-
1539
- if (happyForms.previewLoaded) {
1540
- // api.previewer.send( 'happyforms-style-update', this.model );
1541
- }
1542
- },
1543
-
1544
- onDisableButtonChange: function(e) {
1545
- var $el = $( e.target );
1546
- var value = $el.is( ':checked' ) ? 1 : 0;
1547
-
1548
- this.model.set( $el.attr( 'data-attribute' ), value );
1549
-
1550
- if (happyForms.previewLoaded) {
1551
- var eventData = {
1552
- selector: '.happyforms-button--submit',
1553
- attributes: {
1554
- 'disabled': true
1555
- }
1556
- };
1557
-
1558
- if (value === 0) {
1559
- eventData.attributeMethod = 'remove';
1560
- eventData.attributes = 'disabled';
1561
- }
1562
-
1563
- // api.previewer.send('happyforms-part-dom-update', eventData);
1564
- }
1565
- },
1566
-
1567
- onRequiredTextChange: function( e ) {
1568
- var $el = $(e.target);
1569
- var value = $el.val();
1570
- var eventData = {
1571
- 'selector': '.happyforms-required',
1572
- 'text': value
1573
- };
1574
-
1575
- this.model.set( $el.attr( 'data-attribute' ), value );
1576
- // api.previewer.send( 'happyforms-part-dom-update', eventData );
1577
- },
1578
-
1579
- onInputChange: function( e ) {
1580
- var $el = $( e.target );
1581
- var value = $el.val();
1582
-
1583
- this.model.set( $el.attr('data-attribute'), value );
1584
-
1585
- if ( happyForms.previewLoaded ) {
1586
- // api.previewer.send('happyforms-style-update', this.model);
1587
- }
1588
- }
1589
  } );
1590
 
1591
  classes.views.FormDone = classes.views.Base.extend( {
@@ -1779,6 +1748,18 @@
1779
 
1780
  $form.removeClass( previousClass );
1781
  $form.addClass( currentClass );
 
 
 
 
 
 
 
 
 
 
 
 
1782
  }
1783
  };
1784
 
@@ -1789,8 +1770,6 @@
1789
 
1790
  api.bind( 'ready', function() {
1791
  happyForms.start();
1792
- // Backbone.history.start();
1793
- // api.previewer.previewUrl( happyForms.form.getPreviewUrl() );
1794
 
1795
  api.previewer.bind( 'ready', function() {
1796
  happyForms.flushBuffer();
151
 
152
  flushBuffer: function() {
153
  if ( this.buffer.length > 0 ) {
154
+ _.each( this.buffer, function( entry ) {
155
+ api.previewer.send( entry.event, entry.data );
156
  } );
157
 
158
  this.buffer = [];
531
  if ( happyForms.previewer.ready ) {
532
  api.previewer.send( 'happyforms-form-part-add', response );
533
  } else {
534
+ happyForms.buffer.push( {
535
+ event: 'happyforms-form-part-add',
536
+ data: response
537
+ } );
538
  }
539
  } );
540
  },
556
  if ( happyForms.previewer.ready ) {
557
  api.previewer.send( 'happyforms-form-part-add', response );
558
  } else {
559
+ happyForms.buffer.push( {
560
+ event: 'happyforms-form-part-add',
561
+ data: response
562
+ } );
563
  }
564
  } );
565
  },
579
 
580
  if ( happyForms.previewer.ready ) {
581
  api.previewer.send( 'happyforms-form-part-remove', partModel.id );
582
+ } else {
583
+ happyForms.buffer.push( {
584
+ event: 'happyforms-form-part-remove',
585
+ data: partModel.id
586
+ } );
587
  }
588
  },
589
 
1036
  */
1037
  onLabelPlacementChange: function( model, value, options ) {
1038
  var $select = $( '[data-bind=label_placement]', this.$el );
 
 
 
 
 
 
 
 
 
1039
 
1040
+ if ( $('option[value='+value+']', $select).length > 0 ) {
1041
+ $select.val( value );
 
 
 
1042
 
1043
+ if ( ! options.skipGlobalReveal ) {
1044
+ var $globalWrap = this.$( '.label_placement-options', this.$el );
1045
+ // reset global checkbox
1046
+ this.$( 'input', $globalWrap ).prop( 'checked', false );
1047
+ // fade in the global checkbox wrapper
1048
+ $globalWrap.fadeIn();
1049
+ }
1050
+
1051
+ model.fetchHtml( function( response ) {
1052
+ var data = {
1053
+ id: model.get( 'id' ),
1054
+ html: response,
1055
+ };
1056
+
1057
+ api.previewer.send( 'happyforms-form-part-refresh', data );
1058
+ } );
1059
+ } else {
1060
+ model.set('label_placement', model.previous('label_placement'), { silent: true });
1061
+ }
1062
  },
1063
 
1064
  onCSSClassChange: function( model, value, options ) {
1136
  classes.views.Base.prototype.initialize.apply( this, arguments );
1137
 
1138
  this.listenTo( this.model, 'change:captcha', this.onChangeCaptcha );
1139
+ this.listenTo( this.model, 'change:captcha_site_key', this.onChangeCaptchaKey );
1140
+ this.listenTo( this.model, 'change:captcha_secret_key', this.onChangeCaptchaKey );
1141
+ this.listenTo( this.model, 'change:submit_button_label', this.onSubmitButtonLabelChange );
1142
  },
1143
 
1144
  render: function() {
1215
  }
1216
 
1217
  this.model.set( attribute, value );
 
 
 
 
 
 
 
1218
  },
1219
 
1220
  onHelpMouseOver: function( e ) {
1245
  } else {
1246
  $captchaSettings.hide();
1247
  }
1248
+
1249
+ this.onChangeCaptchaKey();
1250
+ },
1251
+
1252
+ onChangeCaptchaKey: function() {
1253
+ var data = {
1254
+ callback: 'onRecaptchaUpdate',
1255
+ };
1256
+
1257
+ if ( happyForms.previewer.ready ) {
1258
+ api.previewer.send( 'happyforms-form-recaptcha-update', data );
1259
+ } else {
1260
+ happyForms.buffer.push( {
1261
+ event: 'happyforms-form-recaptcha-update',
1262
+ data: data
1263
+ } );
1264
+ }
1265
+ },
1266
+
1267
+ onSubmitButtonLabelChange: function( model, value ) {
1268
+ api.previewer.send( 'happyforms-submit-button-text-update', value );
1269
  },
1270
 
1271
  remove: function() {
1283
  events: {
1284
  'click h3.accordion-section-title': 'onGroupClick',
1285
  'click .customize-panel-back': 'onGroupBackClick',
 
 
 
 
 
 
 
1286
  'change [data-target="form_class"] input': 'onFormClassChange',
1287
  'change [data-target="form_class"] select': 'onFormClassChange',
1288
  'change [data-target="form_class"] input[type="checkbox"]': 'onFormClassCheckboxChange',
1555
 
1556
  api.previewer.send('happyforms-css-variable-update', data);
1557
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1558
  } );
1559
 
1560
  classes.views.FormDone = classes.views.Base.extend( {
1748
 
1749
  $form.removeClass( previousClass );
1750
  $form.addClass( currentClass );
1751
+ },
1752
+
1753
+ onRecaptchaUpdate: function( $recaptcha, $ ) {
1754
+ var captcha = happyForms.form.get( 'captcha' );
1755
+
1756
+ if ( captcha ) {
1757
+ var siteKey = happyForms.form.get( 'captcha_site_key' ) || 'null';
1758
+ $recaptcha.attr( 'data-sitekey', siteKey );
1759
+ $recaptcha.happyFormPart( 'render' );
1760
+ } else {
1761
+ $recaptcha.happyFormPart( 'reset' );
1762
+ }
1763
  }
1764
  };
1765
 
1770
 
1771
  api.bind( 'ready', function() {
1772
  happyForms.start();
 
 
1773
 
1774
  api.previewer.bind( 'ready', function() {
1775
  happyForms.flushBuffer();
assets/js/frontend.js CHANGED
@@ -4,77 +4,20 @@
4
 
5
  HappyForms.parts.base = {
6
  init: function() {
7
- var type = this.$el.data( 'happyforms-type' );
8
-
9
- switch ( type ) {
10
- case 'single_line_text':
11
- case 'email':
12
- case 'website_url':
13
- case 'checkbox':
14
- case 'radio':
15
- case 'number':
16
- case 'legal':
17
- case 'rating':
18
- this.$input = $( 'input', this.$el );
19
- break;
20
-
21
- case 'multi_line_text':
22
- this.$input = $( 'textarea', this.$el );
23
- break;
24
-
25
- case 'select':
26
- case 'date':
27
- case 'title':
28
- this.$input = $( 'select', this.$el );
29
- break;
30
-
31
- case 'recaptcha':
32
- this.$input = this.$el;
33
- this.initRecaptcha();
34
- break;
35
-
36
- case 'phone':
37
- // Overwritten in phone.js
38
- break;
39
-
40
- case 'address':
41
- // Overwritten in address.js
42
- break;
43
-
44
- case 'scale':
45
- // Overwritten in scale.js
46
- break;
47
-
48
- default:
49
- return;
50
- break;
51
- }
52
 
53
  this.$input.on( 'keyup change', this.triggerChange.bind( this ) );
54
-
55
- $( 'input, textarea', this.$el ).on( 'blur', this.onBlur.bind( this ) );
56
  },
57
 
58
- initRecaptcha: function() {
59
- var self = this;
60
- var recaptchaElementId = $('> div', this.$el).attr('id');
61
-
62
- grecaptcha.ready(function() {
63
- grecaptcha.render(recaptchaElementId, {
64
- sitekey: self.$el.attr('data-sitekey'),
65
- callback: function( response ) {
66
- self.triggerChange( {
67
- recaptcha: true,
68
- response: response
69
- });
70
- }
71
- });
72
- });
73
  },
74
 
75
  onBlur: function() {
76
  if ( this.$el.is( '.happyforms-part--label-as_placeholder' ) ) {
77
- if ( this.getValue() ) {
78
  this.$el.addClass( 'happyforms-part--filled' );
79
  } else {
80
  this.$el.removeClass( 'happyforms-part--filled' );
@@ -83,10 +26,6 @@
83
  },
84
 
85
  triggerChange: function( data ) {
86
- if ( 'undefined' === typeof data ) {
87
- data = '';
88
- }
89
-
90
  this.$el.trigger( 'happyforms-change', data );
91
  },
92
 
@@ -94,83 +33,79 @@
94
  return this.$el.is( '[data-happyforms-required]' );
95
  },
96
 
97
- getValue: function() {
98
- var type = this.$el.data( 'happyforms-type' );
 
 
99
 
100
- switch ( type ) {
101
- case 'single_line_text':
102
- case 'email':
103
- case 'website_url':
104
- case 'multi_line_text':
105
- case 'select':
106
- case 'number':
107
- case 'scale':
108
- case 'title':
109
- return this.$input.val();
110
- break;
111
-
112
- case 'checkbox':
113
- case 'radio':
114
- case 'legal':
115
- return $( ':checked', this.$el ).val();
116
- break;
117
-
118
- case 'rating':
119
- return '0' !== $( ':checked', this.$el ).val();
120
- break;
121
-
122
- case 'phone':
123
- // Overwritten in phone.js
124
- break;
125
-
126
- case 'date':
127
- case 'address':
128
- var value = '';
129
-
130
- var components = $.map( this.$input, function( el ) {
131
- var componentValue = $( el ).val();
132
-
133
- if ( componentValue ) {
134
- return componentValue;
135
- }
136
- } );
137
-
138
- if ( components.length === this.$input.length ) {
139
- value = components.join( '-' );
140
- }
141
 
142
- return value;
143
- break;
 
 
 
144
 
145
- default:
146
- return;
147
- break;
148
  }
 
 
 
 
 
 
149
  },
150
 
151
- getConfirmationValue: function() {
152
- return $( '.happyforms-confirmation-input', this.$el ).val();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  },
154
 
155
  isValid: function() {
156
  var valid = true;
157
 
 
 
158
  if ( ! this.$input ) {
159
  return valid;
160
  }
161
 
162
  if ( this.$input.attr( 'readonly' ) ) {
163
- valid = valid && ! this.getValue();
164
  }
165
 
166
  if ( this.isRequired() ) {
167
- valid = valid && this.getValue();
168
  }
169
 
170
- if ( this.isRequired() &&
171
- this.$el.is( '[data-happyforms-require-confirmation]' ) ) {
172
-
173
- valid = valid && ( '' !== this.getConfirmationValue() );
174
  }
175
 
176
  return valid;
@@ -200,8 +135,6 @@
200
  this.$form = $( 'form', this.$el );
201
  this.$parts = $( '[data-happyforms-type]', this.$form );
202
  this.$submit = $( '[type="submit"]', this.$form );
203
- this.hasRecaptcha = false;
204
- this.recaptchaValid = false;
205
 
206
  this.init();
207
  }
@@ -209,13 +142,7 @@
209
  HappyForms.Form.prototype = {
210
  init: function() {
211
  var $form = this.$form;
212
- var $parts = $('[data-happyforms-type]', this.$form);
213
-
214
- this.$el.on( 'happyforms-change', this.validate.bind( this ) );
215
-
216
- if (this.$el.find('.happyforms-part--recaptcha').length) {
217
- this.hasRecaptcha = true;
218
- }
219
 
220
  $parts.each( function() {
221
  var $part = $( this );
@@ -224,18 +151,14 @@
224
  HappyForms.wrapPart( $part, $form );
225
  } );
226
 
 
227
  this.$el.trigger( 'happyforms-change' );
 
228
  },
229
 
230
  validate: function( e, data ) {
231
  var isValid = true;
232
 
233
- if ( 'undefined' !== typeof data ) {
234
- if ( data.recaptcha && data.response ) {
235
- this.recaptchaValid = true;
236
- }
237
- }
238
-
239
  if ( this.$form.is( '.happyforms-form--disable-until-valid' ) ) {
240
  // Check every part
241
  var $parts = $( '[data-happyforms-type]', this.$form );
@@ -244,20 +167,81 @@
244
  isValid = isValid && $( this ).happyFormPart( 'isValid' );
245
  } );
246
  } else {
247
- // Check only legal parts
248
- var $parts = $( '[data-happyforms-type=legal]', this.$form );
249
 
250
  $parts.each( function() {
251
  isValid = isValid && $( this ).happyFormPart( 'isValid' );
252
  } );
253
  }
254
 
255
- if (this.hasRecaptcha) {
256
- isValid = isValid && this.recaptchaValid;
257
- }
258
-
259
  this.$submit.attr( 'disabled', ! isValid );
260
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
 
263
  HappyForms.Part = function( el ) {
@@ -294,6 +278,8 @@
294
  }
295
  }
296
  } );
 
 
297
  }
298
 
299
  $( document ).ready( function() {
4
 
5
  HappyForms.parts.base = {
6
  init: function() {
7
+ this.type = this.$el.data( 'happyforms-type' );
8
+ this.$input = $( 'input, textarea, select', this.$el );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  this.$input.on( 'keyup change', this.triggerChange.bind( this ) );
11
+ this.$input.on( 'blur', this.onBlur.bind( this ) );
 
12
  },
13
 
14
+ getType: function() {
15
+ return this.type;
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  },
17
 
18
  onBlur: function() {
19
  if ( this.$el.is( '.happyforms-part--label-as_placeholder' ) ) {
20
+ if ( this.isFilled() ) {
21
  this.$el.addClass( 'happyforms-part--filled' );
22
  } else {
23
  this.$el.removeClass( 'happyforms-part--filled' );
26
  },
27
 
28
  triggerChange: function( data ) {
 
 
 
 
29
  this.$el.trigger( 'happyforms-change', data );
30
  },
31
 
33
  return this.$el.is( '[data-happyforms-required]' );
34
  },
35
 
36
+ isFilled: function() {
37
+ var filledInputs = this.$input.filter( function() {
38
+ var $input = $( this );
39
+ var hasValue = false;
40
 
41
+ if ( $input.is( '[type=checkbox]' ) || $input.is( '[type=radio]' ) ) {
42
+ hasValue = $input.is( ':checked' );
43
+ } else {
44
+ hasValue = '' !== $input.val();
45
+ }
46
+
47
+ return hasValue;
48
+ } );
49
+
50
+ return filledInputs.length > 0;
51
+ },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ confirmationMatches: function() {
54
+ var matches = false;
55
+ var values = this.$input.map( function() {
56
+ return $( this ).val();
57
+ } ).toArray();
58
 
59
+ if ( 2 === values.length ) {
60
+ matches = values[0] === values[1];
 
61
  }
62
+
63
+ return matches;
64
+ },
65
+
66
+ requiresConfirmation: function() {
67
+ return this.$el.is( '[data-happyforms-require-confirmation]' );
68
  },
69
 
70
+ serialize: function() {
71
+ var serialized = this.$input.map( function( i, input ) {
72
+ var $input = $( input );
73
+ var keyValue = {
74
+ name: $input.attr( 'name' ),
75
+ value: $input.val(),
76
+ };
77
+
78
+ if ( $input.is( '[type=checkbox]' ) || $input.is( '[type=radio]' ) ) {
79
+ if ( ! $input.is( ':checked' ) ) {
80
+ return;
81
+ }
82
+ }
83
+
84
+ return keyValue;
85
+ } ).toArray();
86
+
87
+ return serialized;
88
  },
89
 
90
  isValid: function() {
91
  var valid = true;
92
 
93
+ var type = this.$el.data( 'happyforms-type' );
94
+
95
  if ( ! this.$input ) {
96
  return valid;
97
  }
98
 
99
  if ( this.$input.attr( 'readonly' ) ) {
100
+ valid = valid && ! this.isFilled();
101
  }
102
 
103
  if ( this.isRequired() ) {
104
+ valid = valid && this.isFilled();
105
  }
106
 
107
+ if ( this.isRequired() && this.requiresConfirmation() ) {
108
+ valid = valid && this.confirmationMatches();
 
 
109
  }
110
 
111
  return valid;
135
  this.$form = $( 'form', this.$el );
136
  this.$parts = $( '[data-happyforms-type]', this.$form );
137
  this.$submit = $( '[type="submit"]', this.$form );
 
 
138
 
139
  this.init();
140
  }
142
  HappyForms.Form.prototype = {
143
  init: function() {
144
  var $form = this.$form;
145
+ var $parts = $( '[data-happyforms-type]', this.$form );
 
 
 
 
 
 
146
 
147
  $parts.each( function() {
148
  var $part = $( this );
151
  HappyForms.wrapPart( $part, $form );
152
  } );
153
 
154
+ this.$el.on( 'happyforms-change', this.validate.bind( this ) );
155
  this.$el.trigger( 'happyforms-change' );
156
+ this.$form.submit( this.submit.bind( this ) );
157
  },
158
 
159
  validate: function( e, data ) {
160
  var isValid = true;
161
 
 
 
 
 
 
 
162
  if ( this.$form.is( '.happyforms-form--disable-until-valid' ) ) {
163
  // Check every part
164
  var $parts = $( '[data-happyforms-type]', this.$form );
167
  isValid = isValid && $( this ).happyFormPart( 'isValid' );
168
  } );
169
  } else {
170
+ // Check only legal andr recaptcha parts
171
+ var $parts = $( '[data-happyforms-type=legal], [data-happyforms-type=recaptcha]', this.$form );
172
 
173
  $parts.each( function() {
174
  isValid = isValid && $( this ).happyFormPart( 'isValid' );
175
  } );
176
  }
177
 
 
 
 
 
178
  this.$submit.attr( 'disabled', ! isValid );
179
  },
180
+
181
+ serialize: function() {
182
+ var action = $( '[name=action]', this.$form ).val();
183
+ var form_id = $( '[name=happyforms_form_id]', this.$form ).val();
184
+ var nonce = $( '[name=happyforms_message_nonce]', this.$form ).val();
185
+
186
+ var formData = [
187
+ { name: 'action', value: action },
188
+ { name: 'happyforms_form_id', value: form_id },
189
+ { name: 'happyforms_message_nonce', value: nonce },
190
+ ];
191
+
192
+ var $parts = $( '[data-happyforms-type]', this.$form );
193
+ var partData = $parts.map( function( i, part ) {
194
+ return $( part ).happyFormPart( 'serialize' );
195
+ } ).toArray();
196
+
197
+ var data = formData.concat( partData );
198
+
199
+ console.log( data );
200
+
201
+ var querystring = data
202
+ .map( function( part ) {
203
+ return part.name + '=' + part.value;
204
+ } )
205
+ .join( '&' );
206
+
207
+ return querystring;
208
+ },
209
+
210
+ submit: function( e ) {
211
+ e.preventDefault();
212
+
213
+ this.$submit.attr('disabled', 'disabled');
214
+
215
+ $.ajax( {
216
+ type: 'post',
217
+ data: this.serialize(),
218
+ } ).done( this.onSubmitComplete.bind( this ) );
219
+ },
220
+
221
+ onSubmitComplete: function( response ) {
222
+ if ( ! response.data ) {
223
+ return false;
224
+ }
225
+
226
+ if ( response.data.redirect ) {
227
+ window.location.replace( response.data.redirect );
228
+
229
+ return false;
230
+ }
231
+
232
+ if ( response.data.html ) {
233
+ var $el = $( response.data.html );
234
+ this.$el.replaceWith( $el );
235
+
236
+ $el.happyForm();
237
+
238
+ var elTopOffset = $el.offset().top;
239
+
240
+ $('html, body').animate({
241
+ scrollTop: elTopOffset + 'px'
242
+ }, 500);
243
+ }
244
+ }
245
  }
246
 
247
  HappyForms.Part = function( el ) {
278
  }
279
  }
280
  } );
281
+
282
+ $( '[required]' ).removeAttr( 'required' );
283
  }
284
 
285
  $( document ).ready( function() {
assets/js/frontend/address.js CHANGED
@@ -26,6 +26,7 @@
26
 
27
  HappyForms.parts.address = {
28
  init: function() {
 
29
  this.$input = $( 'input', this.$el );
30
  this.$fullAddress = $( '.address-full', this.$el );
31
  this.$country = $( '.address-country', this.$el );
@@ -124,22 +125,19 @@
124
 
125
  $( 'span', this.$geolocation ).text( this.$geolocation.data( 'idle' ) );
126
  this.$geolocation.removeClass( 'disabled' );
127
- },
128
-
129
- getValue: function () {
130
- var value = this.$input.val();
131
-
132
- return value;
133
  },
134
-
135
- onBlur: function () {
136
- if (this.$el.is('.happyforms-part--label-as_placeholder')) {
137
- if (this.getValue()) {
138
- this.$el.addClass('happyforms-part--filled');
139
- } else {
140
- this.$el.removeClass('happyforms-part--filled');
 
141
  }
142
- }
 
 
143
  },
144
  }
145
 
26
 
27
  HappyForms.parts.address = {
28
  init: function() {
29
+ this.type = this.$el.data( 'happyforms-type' );
30
  this.$input = $( 'input', this.$el );
31
  this.$fullAddress = $( '.address-full', this.$el );
32
  this.$country = $( '.address-country', this.$el );
125
 
126
  $( 'span', this.$geolocation ).text( this.$geolocation.data( 'idle' ) );
127
  this.$geolocation.removeClass( 'disabled' );
 
 
 
 
 
 
128
  },
129
+
130
+ serialize: function() {
131
+ var serialized = $( 'input', this.$el ).map( function( i, input ) {
132
+ var $input = $( input );
133
+
134
+ return {
135
+ name: $input.attr( 'name' ),
136
+ value: $input.val(),
137
  }
138
+ } ).toArray();
139
+
140
+ return serialized;
141
  },
142
  }
143
 
assets/js/frontend/date.js CHANGED
@@ -1,169 +1,195 @@
1
  (function ($) {
2
 
3
- HappyForms.parts = HappyForms.parts || {};
4
-
5
- HappyForms.parts.date = {
6
- init: function () {
7
- this.spinnerInterval = '';
8
- this.spinnerIntervalLength = 50;
9
- this.$input = $('input', this.$el);
10
- this.$spinnerUpArrow = $('.happyforms-spinner-arrow--up', this.$el);
11
- this.$spinnerDownArrow = $('.happyforms-spinner-arrow--down', this.$el);
12
-
13
- this.$input.on('keydown', this.onKeyDown.bind(this));
14
- this.$input.on('change', this.onChange.bind(this));
15
-
16
- this.$spinnerUpArrow.on('mousedown touchstart', this.onSpinnerUpClick.bind(this));
17
- this.$spinnerUpArrow.on('mouseup mouseleave touchend', this.clearSpinnerInterval.bind(this));
18
- this.$spinnerDownArrow.on('mousedown touchstart', this.onSpinnerDownClick.bind(this));
19
- this.$spinnerDownArrow.on('mouseup mouseleave touchend', this.clearSpinnerInterval.bind(this));
20
- },
21
-
22
- clearSpinnerInterval: function() {
23
- clearInterval(this.spinnerInterval);
24
- },
25
-
26
- onSpinnerUpClick: function(e) {
27
- var self = this;
28
-
29
- this.clearSpinnerInterval();
30
-
31
- this.spinnerInterval = setInterval(function() {
32
- var $input = $(e.target).prev('input');
33
- var step = ($input.attr('step')) ? parseInt($input.attr('step'), 10) : 1;
34
-
35
- var value = self.getIncreasedValue(parseInt($input.val(), 10), step);
36
-
37
- self.setValue($input, value);
38
- }, this.spinnerIntervalLength);
39
- },
40
-
41
- onSpinnerDownClick: function (e) {
42
- var self = this;
43
-
44
- this.clearSpinnerInterval();
45
-
46
- this.spinnerInterval = setInterval(function() {
47
- var $input = $(e.target).prevAll('input');
48
- var step = ($input.attr('step')) ? parseInt($input.attr('step'), 10) : 1;
49
-
50
- var value = self.getDecreasedValue(parseInt($input.val(), 10), step);
51
-
52
- self.setValue($input, value);
53
- }, this.spinnerIntervalLength);
54
- },
55
-
56
- setValue: function($input, value) {
57
- if ( 'undefined' === typeof $input ) {
58
- return;
59
- }
60
-
61
- var pattern = $input.attr('pattern');
62
- var intNewValue = parseInt(value, 10);
63
- var intMin = parseInt($input.attr('min'), 10);
64
- var intMax = parseInt($input.attr('max'), 10);
65
- var step = ($input.attr('step')) ? parseInt( $input.attr('step'), 10 ) : 1;
66
-
67
- if (intNewValue > intMax) {
68
- intNewValue = intMin;
69
- }
70
-
71
- if (intNewValue < intMin) {
72
- if (step) {
73
- intNewValue = (intMax + 1 - step);
74
- } else {
75
- intNewValue = intMax;
76
- }
77
- }
78
-
79
- if (intNewValue !== 0 && intNewValue % step !== 0) {
80
- intNewValue = step;
81
- }
82
-
83
- var validatedValue = this.validateNumber(intNewValue, pattern);
84
-
85
- if (validatedValue) {
86
- $input.val(validatedValue);
87
- }
88
- },
89
-
90
- validateNumber: function (number, pattern) {
91
- if (isNaN(number) || !number) {
92
- return '00';
93
- }
94
-
95
- if (number.toString().match(pattern)) {
96
- return number.toString();
97
- } else {
98
- var leadingZeroValue = '0' + number;
99
-
100
- if (2 === leadingZeroValue.length && leadingZeroValue.match(pattern)) {
101
- return leadingZeroValue;
102
- }
103
- }
104
- },
105
-
106
- getIncreasedValue: function(value, step) {
107
- if ( 'undefined' === typeof value || !step ) {
108
- return;
109
- }
110
-
111
- var newValue = (value + step).toString();
112
-
113
- return newValue;
114
- },
115
-
116
- getDecreasedValue: function(value, step) {
117
- if ( 'undefined' === typeof value || !step ) {
118
- return;
119
- }
120
-
121
- var newValue = (value - step).toString();
122
-
123
- return newValue;
124
- },
125
-
126
- onKeyDown: function(e) {
127
- var $input = $(e.target);
128
- var intValue = (parseInt($input.val(), 10)) ? parseInt($input.val(), 10) : parseInt($input.attr('min'), 10);
129
- var newValue = '0';
130
- var max = $input.attr('max');
131
- var min = $input.attr('min');
132
- var step = parseInt($input.attr('step'), 10) ? parseInt($input.attr('step'), 10) : 1;
133
-
134
- if ( isNaN(intValue) && isNaN(parseInt(e.key, 10)) ) {
135
- return false;
136
- }
137
-
138
- if ( e.keyCode !== 38 && e.keyCode !== 40 ) {
139
- return;
140
- }
141
-
142
- if ( 38 === e.keyCode ) {
143
- newValue = this.getIncreasedValue(intValue, step);
144
-
145
- if ('undefined' === typeof newValue) {
146
- newValue = min;
147
- }
148
- }
149
-
150
- if (40 === e.keyCode) {
151
- newValue = this.getDecreasedValue(intValue, step);
152
-
153
- if ('undefined' === typeof newValue) {
154
- newValue = max;
155
- }
156
- }
157
-
158
- this.setValue($input, newValue);
159
- },
160
-
161
- onChange: function (e) {
162
- var $input = $(e.target);
163
- var value = $input.val();
164
-
165
- this.setValue($input, value);
166
- },
167
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  })(jQuery);
1
  (function ($) {
2
 
3
+ HappyForms.parts = HappyForms.parts || {};
4
+
5
+ HappyForms.parts.date = {
6
+ init: function () {
7
+ this.type = this.$el.data( 'happyforms-type' );
8
+ this.spinnerInterval = '';
9
+ this.spinnerIntervalLength = 50;
10
+ this.$input = $('input, select', this.$el);
11
+ this.$numbers = $('input', this.$el);
12
+ this.$spinnerUpArrow = $('.happyforms-spinner-arrow--up', this.$el);
13
+ this.$spinnerDownArrow = $('.happyforms-spinner-arrow--down', this.$el);
14
+
15
+ this.$numbers.on('keydown', this.onKeyDown.bind(this));
16
+ this.$numbers.on('change', this.onChange.bind(this));
17
+ this.$input.on( 'change', this.triggerChange.bind( this ) );
18
+
19
+ this.$spinnerUpArrow.on('mousedown touchstart', this.onSpinnerUpClick.bind(this));
20
+ this.$spinnerUpArrow.on('mouseup mouseleave touchend', this.clearSpinnerInterval.bind(this));
21
+ this.$spinnerDownArrow.on('mousedown touchstart', this.onSpinnerDownClick.bind(this));
22
+ this.$spinnerDownArrow.on('mouseup mouseleave touchend', this.clearSpinnerInterval.bind(this));
23
+ },
24
+
25
+ clearSpinnerInterval: function() {
26
+ clearInterval(this.spinnerInterval);
27
+ },
28
+
29
+ onSpinnerUpClick: function(e) {
30
+ var self = this;
31
+
32
+ this.clearSpinnerInterval();
33
+
34
+ this.spinnerInterval = setInterval(function() {
35
+ var $input = $(e.target).prev('input');
36
+ var step = ($input.attr('step')) ? parseInt($input.attr('step'), 10) : 1;
37
+
38
+ var value = self.getIncreasedValue(parseInt($input.val(), 10), step);
39
+
40
+ self.setValue($input, value);
41
+ }, this.spinnerIntervalLength);
42
+ },
43
+
44
+ onSpinnerDownClick: function (e) {
45
+ var self = this;
46
+
47
+ this.clearSpinnerInterval();
48
+
49
+ this.spinnerInterval = setInterval(function() {
50
+ var $input = $(e.target).prevAll('input');
51
+ var step = ($input.attr('step')) ? parseInt($input.attr('step'), 10) : 1;
52
+
53
+ var value = self.getDecreasedValue(parseInt($input.val(), 10), step);
54
+
55
+ self.setValue($input, value);
56
+ }, this.spinnerIntervalLength);
57
+ },
58
+
59
+ setValue: function($input, value) {
60
+ if ( 'undefined' === typeof $input ) {
61
+ return;
62
+ }
63
+
64
+ var pattern = $input.attr('pattern');
65
+ var intNewValue = parseInt(value, 10);
66
+ var intMin = parseInt($input.attr('min'), 10);
67
+ var intMax = parseInt($input.attr('max'), 10);
68
+ var step = ($input.attr('step')) ? parseInt( $input.attr('step'), 10 ) : 1;
69
+
70
+ if (intNewValue > intMax) {
71
+ intNewValue = intMin;
72
+ }
73
+
74
+ if (intNewValue < intMin) {
75
+ if (step) {
76
+ intNewValue = (intMax + 1 - step);
77
+ } else {
78
+ intNewValue = intMax;
79
+ }
80
+ }
81
+
82
+ if (intNewValue !== 0 && intNewValue % step !== 0) {
83
+ intNewValue = step;
84
+ }
85
+
86
+ var validatedValue = this.validateNumber(intNewValue, pattern);
87
+
88
+ if (validatedValue) {
89
+ $input.val(validatedValue);
90
+ }
91
+
92
+ this.$el.trigger( 'happyforms-change' );
93
+ },
94
+
95
+ isFilled: function() {
96
+ var filledInputs = this.$input.filter( function() {
97
+ return '' !== $( this ).val();
98
+ } );
99
+
100
+ return filledInputs.length === this.$input.length;
101
+ },
102
+
103
+ validateNumber: function (number, pattern) {
104
+ if (isNaN(number) || !number) {
105
+ return '00';
106
+ }
107
+
108
+ if (number.toString().match(pattern)) {
109
+ return number.toString();
110
+ } else {
111
+ var leadingZeroValue = '0' + number;
112
+
113
+ if (2 === leadingZeroValue.length && leadingZeroValue.match(pattern)) {
114
+ return leadingZeroValue;
115
+ }
116
+ }
117
+ },
118
+
119
+ getIncreasedValue: function(value, step) {
120
+ if ( 'undefined' === typeof value || !step ) {
121
+ return;
122
+ }
123
+
124
+ var newValue = (value + step).toString();
125
+
126
+ return newValue;
127
+ },
128
+
129
+ getDecreasedValue: function(value, step) {
130
+ if ( 'undefined' === typeof value || !step ) {
131
+ return;
132
+ }
133
+
134
+ var newValue = (value - step).toString();
135
+
136
+ return newValue;
137
+ },
138
+
139
+ onKeyDown: function(e) {
140
+ var $input = $(e.target);
141
+ var intValue = (parseInt($input.val(), 10)) ? parseInt($input.val(), 10) : parseInt($input.attr('min'), 10);
142
+ var newValue = '0';
143
+ var max = $input.attr('max');
144
+ var min = $input.attr('min');
145
+ var step = parseInt($input.attr('step'), 10) ? parseInt($input.attr('step'), 10) : 1;
146
+
147
+ if ( isNaN(intValue) && isNaN(parseInt(e.key, 10)) ) {
148
+ return false;
149
+ }
150
+
151
+ if ( e.keyCode !== 38 && e.keyCode !== 40 ) {
152
+ return;
153
+ }
154
+
155
+ if ( 38 === e.keyCode ) {
156
+ newValue = this.getIncreasedValue(intValue, step);
157
+
158
+ if ('undefined' === typeof newValue) {
159
+ newValue = min;
160
+ }
161
+ }
162
+
163
+ if (40 === e.keyCode) {
164
+ newValue = this.getDecreasedValue(intValue, step);
165
+
166
+ if ('undefined' === typeof newValue) {
167
+ newValue = max;
168
+ }
169
+ }
170
+
171
+ this.setValue($input, newValue);
172
+ },
173
+
174
+ onChange: function (e) {
175
+ var $input = $(e.target);
176
+ var value = $input.val();
177
+
178
+ this.setValue($input, value);
179
+ },
180
+
181
+ serialize: function() {
182
+ var serialized = $( 'input, select', this.$el ).map( function( i, input ) {
183
+ var $input = $( input );
184
+
185
+ return {
186
+ name: $input.attr( 'name' ),
187
+ value: $input.val(),
188
+ }
189
+ } ).toArray();
190
+
191
+ return serialized;
192
+ }
193
+ };
194
 
195
  })(jQuery);
assets/js/frontend/number.js CHANGED
@@ -4,6 +4,8 @@
4
 
5
  HappyForms.parts.number = {
6
  init: function() {
 
 
7
  var masked = this.$el.attr( 'data-mask' );
8
 
9
  this.$input = $( 'input', this.$el );
@@ -46,16 +48,6 @@
46
 
47
  this.init();
48
  },
49
-
50
- onBlur: function () {
51
- if (this.$el.is('.happyforms-part--label-as_placeholder')) {
52
- if (this.getValue()) {
53
- this.$el.addClass('happyforms-part--filled');
54
- } else {
55
- this.$el.removeClass('happyforms-part--filled');
56
- }
57
- }
58
- },
59
  };
60
 
61
  } )( jQuery );
4
 
5
  HappyForms.parts.number = {
6
  init: function() {
7
+ this.type = this.$el.data( 'happyforms-type' );
8
+
9
  var masked = this.$el.attr( 'data-mask' );
10
 
11
  this.$input = $( 'input', this.$el );
48
 
49
  this.init();
50
  },
 
 
 
 
 
 
 
 
 
 
51
  };
52
 
53
  } )( jQuery );
assets/js/frontend/phone.js CHANGED
@@ -1,36 +1,36 @@
1
- ( function( $ ) {
2
 
3
  HappyForms.parts = HappyForms.parts || {};
4
 
5
  HappyForms.parts.phone = {
6
  init: function() {
7
- var masked = this.$el.attr( 'data-mask' );
8
-
9
  this.$input = $( 'input', this.$el );
10
- this.cleaveInstances = [];
 
11
 
12
  this.$input.on( 'keyup', this.triggerChange.bind( this ) );
13
  this.$input.on( 'change', this.triggerChange.bind( this ) );
14
  this.$input.on( 'blur', this.onBlur.bind(this) );
15
 
16
- if ( masked ) {
17
- var regionCode = '+' + this.$el.attr( 'data-country' );
18
- var self = this;
 
 
19
 
20
- this.$input.each( function() {
21
- var $input = $( this );
22
 
23
  var cleave = new Cleave( $input, {
24
  phone: true,
 
 
25
  } );
26
 
27
- if ( regionCode ) {
28
- cleave.setPhoneRegionCode( regionCode );
29
- cleave.setRawValue( regionCode );
30
- };
31
 
32
- self.cleaveInstances.push( cleave );
33
- } );
34
  }
35
  },
36
 
@@ -42,38 +42,51 @@
42
  this.init();
43
  },
44
 
45
- onBlur: function () {
46
- if (this.$el.is('.happyforms-part--label-as_placeholder')) {
47
- if (this.getValue()) {
48
- this.$el.addClass('happyforms-part--filled');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  } else {
50
- this.$el.removeClass('happyforms-part--filled');
51
  }
52
  }
53
  },
54
 
55
- getValue: function() {
56
- var regionCode = this.$el.attr( 'data-country' );
57
- var value = this.$input.val();
58
-
59
- if ( regionCode ) {
60
- value = value.substring( regionCode.length + 1 ).trim();
61
- }
62
 
63
- return value;
64
- },
 
 
 
 
65
 
66
- getConfirmationValue: function() {
67
- var regionCode = this.$el.attr( 'data-country' );
68
- var $input = $( '.happyforms-confirmation-input', this.$el );
69
- var value = $input.val();
70
 
71
- if ( regionCode ) {
72
- value = value.substring( regionCode.length + 1 ).trim();
73
- }
74
 
75
- return value;
76
- }
77
  }
78
 
79
- } )( jQuery );
1
+ ( function( $, settings ) {
2
 
3
  HappyForms.parts = HappyForms.parts || {};
4
 
5
  HappyForms.parts.phone = {
6
  init: function() {
7
+ this.type = this.$el.data( 'happyforms-type' );
 
8
  this.$input = $( 'input', this.$el );
9
+ this.masked = this.$el.attr( 'data-mask' );
10
+ this.prefix = '';
11
 
12
  this.$input.on( 'keyup', this.triggerChange.bind( this ) );
13
  this.$input.on( 'change', this.triggerChange.bind( this ) );
14
  this.$input.on( 'blur', this.onBlur.bind(this) );
15
 
16
+ if ( this.masked ) {
17
+ this.cleaveInstances = this.$input.map( function( i, input ) {
18
+ var $input = $( input );
19
+ var code = this.$el.attr( 'data-country' );
20
+ var rawValue = $input.val();
21
 
22
+ this.prefix = '+' + code;
 
23
 
24
  var cleave = new Cleave( $input, {
25
  phone: true,
26
+ phoneRegionCode: settings.codes[code],
27
+ prefix: this.prefix,
28
  } );
29
 
30
+ cleave.setRawValue( rawValue );
 
 
 
31
 
32
+ return cleave;
33
+ }.bind( this ) );
34
  }
35
  },
36
 
42
  this.init();
43
  },
44
 
45
+ isFilled: function() {
46
+ var prefix = this.prefix;
47
+
48
+ var filledInputs = this.$input.filter( function() {
49
+ var value = $( this ).val().replace( prefix, '' ).trim();
50
+
51
+ return '' !== value;
52
+ } );
53
+
54
+ return filledInputs.length > 0;
55
+ },
56
+
57
+ onBlur: function() {
58
+ if ( '' !== this.prefix ) {
59
+ return;
60
+ }
61
+
62
+ if ( this.$el.is( '.happyforms-part--label-as_placeholder' ) ) {
63
+ if ( this.isFilled() ) {
64
+ this.$el.addClass( 'happyforms-part--filled' );
65
  } else {
66
+ this.$el.removeClass( 'happyforms-part--filled' );
67
  }
68
  }
69
  },
70
 
71
+ serialize: function() {
72
+ var self = this;
 
 
 
 
 
73
 
74
+ var serialized = this.$input.map( function( i, input ) {
75
+ var $input = $( input );
76
+ var keyValue = {
77
+ name: $input.attr( 'name' ),
78
+ value: $input.val(),
79
+ };
80
 
81
+ if ( self.masked ) {
82
+ keyValue.value = self.cleaveInstances[i].getRawValue();
83
+ }
 
84
 
85
+ return keyValue;
86
+ } ).toArray();
 
87
 
88
+ return serialized;
89
+ },
90
  }
91
 
92
+ } )( jQuery, HappyFormsPhoneSettings );
assets/js/frontend/rating.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ HappyForms.parts = HappyForms.parts || {};
4
+
5
+ HappyForms.parts.rating = {
6
+ init: function() {
7
+ this.type = this.$el.data( 'happyforms-type' );
8
+ this.$input = $( 'input', this.$el );
9
+
10
+ this.$input.on( 'change', this.triggerChange.bind( this ) );
11
+ this.$input.on( 'blur', this.onBlur.bind( this ) );
12
+ },
13
+
14
+ isFilled: function() {
15
+ return '0' !== $( ':checked', this.$el ).val();
16
+ },
17
+ };
18
+
19
+ } )( jQuery );
assets/js/frontend/recaptcha.js ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ HappyForms.parts = HappyForms.parts || {};
4
+
5
+ HappyForms.parts.recaptcha = {
6
+ init: function() {
7
+ this.type = this.$el.data( 'happyforms-type' );
8
+ this.$input = $( '> div', this.$el );
9
+ this.html = this.$el.html();
10
+ this.checked = false;
11
+ this.ready = false;
12
+ this.widgetID = false;
13
+
14
+ this.render();
15
+ },
16
+
17
+ onReady: function() {
18
+ this.ready = true;
19
+ this.render();
20
+ },
21
+
22
+ render: function() {
23
+ if ( ! this.ready ) {
24
+ grecaptcha.ready( this.onReady.bind( this ) );
25
+ return;
26
+ }
27
+
28
+ var id = this.$input.attr( 'id' );
29
+ var siteKey = this.$el.attr( 'data-sitekey' );
30
+ var self = this;
31
+
32
+ if ( ! siteKey ) {
33
+ return;
34
+ }
35
+
36
+ if ( false !== this.widgetID ) {
37
+ this.reset();
38
+ }
39
+
40
+ this.widgetID = grecaptcha.render( id, {
41
+ sitekey: siteKey,
42
+
43
+ callback: function( response ) {
44
+ self.checked = true;
45
+
46
+ self.triggerChange( {
47
+ recaptcha: true,
48
+ response: response
49
+ } );
50
+ },
51
+ } );
52
+ },
53
+
54
+ reset: function() {
55
+ this.$el.html( this.html );
56
+ this.widgetID = false;
57
+ },
58
+
59
+ isFilled: function() {
60
+ return this.checked;
61
+ },
62
+
63
+ isValid: function() {
64
+ return this.checked;
65
+ },
66
+
67
+ serialize: function() {
68
+ var serialized = [ {
69
+ name: 'g-recaptcha-response',
70
+ value: $( '[name=g-recaptcha-response]', this.$el ).val(),
71
+ } ];
72
+
73
+ return serialized;
74
+ },
75
+ };
76
+
77
+ } )( jQuery );
assets/js/frontend/scale.js CHANGED
@@ -1,40 +1,105 @@
1
  ( function( $ ) {
2
-
3
  HappyForms.parts = HappyForms.parts || {};
4
 
5
  HappyForms.parts.scale = {
6
  init: function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  this.$input = $( 'input', this.$el );
8
- this.$output = $( 'output', this.$el );
 
 
 
9
 
10
- this.$input.on( 'input', this.refreshOutput.bind( this ) );
11
- this.$input.on( 'input', this.updateTrackColor.bind( this ) );
12
-
13
  this.$input.trigger('input');
14
  },
15
 
16
- updateTrackColor: function() {
17
- var percentValue = 100 * ((this.$input.val() - this.$input.attr('min')) / (this.$input.attr('max') - this.$input.attr('min')));
 
 
 
18
 
19
- this.$input.css({
20
- 'background': 'linear-gradient(to right, var(--happyforms-color-part-value) 0%, var(--happyforms-color-part-value) ' + percentValue +'%, var(--happyforms-color-part-border) ' + percentValue +'%)'
21
- });
 
22
  },
23
 
24
- refreshOutput: function() {
25
- var min = parseFloat( this.$input.attr( 'min' ) );
26
- var max = parseFloat( this.$input.attr( 'max' ) );
27
- var step = parseFloat( this.$input.attr( 'step' ) );
28
 
29
- var rangeWidth = this.$el.width();
30
- var outputPosition = 100 * ((this.$input.val() - this.$input.attr('min')) / (this.$input.attr('max') - this.$input.attr('min')));
31
 
32
- outputPosition = outputPosition - outputPosition * 0.025;
 
 
33
 
34
- this.$output.find('span').text( this.$input.val() ).css({
35
- left: outputPosition + '%'
36
- });
37
  },
38
- };
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  } )( jQuery );
1
  ( function( $ ) {
 
2
  HappyForms.parts = HappyForms.parts || {};
3
 
4
  HappyForms.parts.scale = {
5
  init: function() {
6
+ this.type = this.$el.data( 'happyforms-type' );
7
+
8
+ if ( document.readyState != 'loading' ) {
9
+ if ( typeof multirange !== undefined ) {
10
+ multirange.init();
11
+ }
12
+ }
13
+
14
+ if ( $( 'input', this.$el ).length > 1 ) {
15
+ this.initRangeSlider();
16
+ } else {
17
+ this.initSingleSlider();
18
+ }
19
+ },
20
+
21
+ initSingleSlider: function() {
22
  this.$input = $( 'input', this.$el );
23
+ this.$output = $( 'output span', this.$el );
24
+
25
+ this.$input.on( 'input change', this.refreshSingleOutput.bind(this) );
26
+ this.$input.on( 'input change', this.updateTrackerColor.bind(this) );
27
 
 
 
 
28
  this.$input.trigger('input');
29
  },
30
 
31
+ initRangeSlider: function() {
32
+ this.$input = $( 'input:first', this.$el );
33
+ this.$output = $( 'output:first span', this.$el );
34
+ this.$ghostInput = $( 'input:last', this.$el );
35
+ this.$ghostOutput = $( 'output:last span', this.$el );
36
 
37
+ this.$ghostInput.on( 'input change', this.refreshMultiOutput.bind(this) );
38
+ this.$input.on( 'input change', this.refreshMultiOutput.bind(this) );
39
+
40
+ this.$input.trigger( 'input' );
41
  },
42
 
43
+ refreshSingleOutput: function( e ) {
44
+ var inputVal = this.$input.val();
45
+ var outputPosition = this.getOutputPosition();
 
46
 
47
+ this.$output.css( 'left', outputPosition + '%' ).text( inputVal );
48
+ },
49
 
50
+ refreshMultiOutput: function( e ) {
51
+ var inputVal = this.$input.val().split(',');
52
+ var outputPosition = this.getOutputPosition();
53
 
54
+ this.$output.css( 'left', outputPosition['original'] + '%' ).text( inputVal[0] );
55
+ this.$ghostOutput.css( 'left', outputPosition['ghost'] + '%' ).text( inputVal[1] );
 
56
  },
 
57
 
58
+ getOutputPosition: function() {
59
+ var value = this.$input.val();
60
+ var min = this.$input.attr( 'min' ) ? this.$input.attr( 'min' ) : 0;
61
+ var max = this.$input.attr( 'max' ) ? this.$input.attr( 'max' ) : 100;
62
+ var data;
63
+
64
+ if ( -1 !== value.indexOf( ',' ) ) {
65
+ value = value.split( ',' );
66
+
67
+ var originalOutputPosition = 100 * ( ( parseInt( value[0] ) - min ) / ( max - min ) );
68
+ var ghostOutputPosition = 100 * ( ( parseInt(value[1] ) - min ) / ( max - min ) );
69
+
70
+ originalOutputPosition = originalOutputPosition - originalOutputPosition * 0.025;
71
+ ghostOutputPosition = ghostOutputPosition - ghostOutputPosition * 0.025;
72
+
73
+ data = {
74
+ 'original': originalOutputPosition,
75
+ 'ghost': ghostOutputPosition
76
+ };
77
+ } else {
78
+ var outputPosition = 100 * ( ( parseInt( value ) - min ) / ( max - min ) );
79
+ var coefficient = 0.02;
80
+
81
+ if ( outputPosition > 50 ) {
82
+ coefficient = 0.025;
83
+ }
84
+
85
+ outputPosition -= outputPosition * coefficient;
86
+
87
+ data = outputPosition;
88
+ }
89
+
90
+ return data;
91
+ },
92
+
93
+ updateTrackerColor: function() {
94
+ var value = this.$input.val();
95
+ var min = this.$input.attr( 'min' ) ? this.$input.attr( 'min' ) : 0;
96
+ var max = this.$input.attr( 'max' ) ? this.$input.attr( 'max' ) : 100;
97
+
98
+ var percentValue = 100 * ( ( value - min ) / ( max - min ) );
99
+
100
+ this.$input.css( {
101
+ 'background': 'linear-gradient(to right, var(--happyforms-color-part-value) ' + percentValue + '%, var(--happyforms-color-part-border) ' + percentValue + '%, var(--happyforms-color-part-border) 100%)'
102
+ } );
103
+ }
104
+ };
105
  } )( jQuery );
assets/js/lib/multirange.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function() {
2
+ "use strict";
3
+
4
+ var supportsMultiple = self.HTMLInputElement && "valueLow" in HTMLInputElement.prototype;
5
+
6
+ var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
7
+
8
+ self.multirange = function(input) {
9
+ if (supportsMultiple || input.classList.contains("multirange")) {
10
+ return;
11
+ }
12
+
13
+ var value = input.getAttribute("value");
14
+ var values = value === null ? [] : value.split(",");
15
+ var min = +(input.min || 0);
16
+ var max = +(input.max || 100);
17
+ var ghost = input.cloneNode();
18
+ ghost.id = ghost.id + '_clone';
19
+
20
+ input.classList.add("multirange", "original");
21
+ ghost.classList.add("multirange", "ghost");
22
+
23
+ input.value = values[0] || min + (max - min) / 2;
24
+ ghost.value = values[1] || min + (max - min) / 2;
25
+
26
+ input.parentNode.insertBefore(ghost, input.nextSibling);
27
+
28
+ Object.defineProperty(input, "originalValue", descriptor.get ? descriptor : {
29
+ // Fuck you Safari >:(
30
+ get: function() { return this.value; },
31
+ set: function(v) { this.value = v; }
32
+ });
33
+
34
+ Object.defineProperties(input, {
35
+ valueLow: {
36
+ get: function() { return Math.min(this.originalValue, ghost.value); },
37
+ set: function(v) { this.originalValue = v; },
38
+ enumerable: true
39
+ },
40
+ valueHigh: {
41
+ get: function() { return Math.max(this.originalValue, ghost.value); },
42
+ set: function(v) { ghost.value = v; },
43
+ enumerable: true
44
+ }
45
+ });
46
+
47
+ if (descriptor.get) {
48
+ // Again, fuck you Safari
49
+ Object.defineProperty(input, "value", {
50
+ get: function() { return this.valueLow + "," + this.valueHigh; },
51
+ set: function(v) {
52
+ var values = v.split(",");
53
+ this.valueLow = values[0];
54
+ this.valueHigh = values[1];
55
+ update();
56
+ },
57
+ enumerable: true
58
+ });
59
+ }
60
+
61
+ if (typeof input.oninput === "function") {
62
+ ghost.oninput = input.oninput.bind(input);
63
+ }
64
+
65
+ function update() {
66
+ ghost.style.setProperty("--low", 100 * ((input.valueLow - min) / (max - min)) + 1 + "%");
67
+ ghost.style.setProperty("--high", 100 * ((input.valueHigh - min) / (max - min)) - 1 + "%");
68
+ }
69
+
70
+ input.addEventListener("input", update);
71
+ ghost.addEventListener("input", update);
72
+
73
+ update();
74
+ }
75
+
76
+ multirange.init = function() {
77
+ [].slice.call(document.querySelectorAll("input[type=range][multiple]:not(.multirange)")).forEach(multirange);
78
+ }
79
+
80
+ if (document.readyState == "loading") {
81
+ document.addEventListener("DOMContentLoaded", multirange.init);
82
+ }
83
+ else {
84
+ multirange.init();
85
+ }
86
+
87
+ })();
assets/js/parts/part-date.js CHANGED
@@ -23,6 +23,8 @@
23
  this.listenTo( this.model, 'change:min_hour', this.refreshDatePart );
24
  this.listenTo( this.model, 'change:max_hour', this.refreshDatePart );
25
  this.listenTo( this.model, 'change:default_datetime', this.refreshDatePart );
 
 
26
  },
27
 
28
  onDateTypeChange: function() {
@@ -91,6 +93,47 @@
91
  api.previewer.send('happyforms-form-part-refresh', data);
92
  });
93
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  } );
95
 
96
  happyForms.previewer = _.extend( happyForms.previewer, {
23
  this.listenTo( this.model, 'change:min_hour', this.refreshDatePart );
24
  this.listenTo( this.model, 'change:max_hour', this.refreshDatePart );
25
  this.listenTo( this.model, 'change:default_datetime', this.refreshDatePart );
26
+ this.listenTo( this.model, 'change:years_option', this.onYearsOptionChange );
27
+ this.listenTo( this.model, 'change:years_order', this.refreshDatePart );
28
  },
29
 
30
  onDateTypeChange: function() {
93
  api.previewer.send('happyforms-form-part-refresh', data);
94
  });
95
  },
96
+
97
+ onYearsOptionChange: function( model, value ) {
98
+ var $minYearInput = $('[data-bind=min_year]', this.$el);
99
+ var $maxYearInput = $('[data-bind=max_year]', this.$el);
100
+ var currentYear = (new Date()).getFullYear();
101
+
102
+ if ( 'all' === value ) {
103
+ $minYearInput.val(currentYear - 100);
104
+ $maxYearInput.val(currentYear + 20);
105
+ model.set('min_year', currentYear - 100, {
106
+ silent: true
107
+ });
108
+ model.set('max_year', currentYear + 20, {
109
+ silent: true
110
+ });
111
+ }
112
+
113
+ if ( 'past' === value ) {
114
+ $minYearInput.val(currentYear - 100);
115
+ $maxYearInput.val(currentYear - 1);
116
+ model.set('min_year', currentYear - 100, {
117
+ silent: true
118
+ });
119
+ model.set('max_year', currentYear - 1, {
120
+ silent: true
121
+ });
122
+ }
123
+
124
+ if ( 'future' === value ) {
125
+ $minYearInput.val(currentYear + 1);
126
+ $maxYearInput.val(currentYear + 100);
127
+ model.set('min_year', currentYear + 1, {
128
+ silent: true
129
+ });
130
+ model.set('max_year', currentYear + 100, {
131
+ silent: true
132
+ });
133
+ }
134
+
135
+ this.refreshDatePart();
136
+ }
137
  } );
138
 
139
  happyForms.previewer = _.extend( happyForms.previewer, {
assets/js/parts/part-scale.js CHANGED
@@ -16,48 +16,79 @@
16
  initialize: function() {
17
  happyForms.classes.views.Part.prototype.initialize.apply( this, arguments );
18
 
19
- this.listenTo( this.model, 'change:min_value', this.onMinValueChange );
20
- this.listenTo( this.model, 'change:max_value', this.onMaxValueChange );
21
- this.listenTo( this.model, 'change:default_value', this.onDefaultValueChange );
22
  this.listenTo( this.model, 'change:step', this.onStepChange );
23
  this.listenTo( this.model, 'change:min_label', this.onMinLabelChange );
24
  this.listenTo( this.model, 'change:max_label', this.onMaxLabelChange );
 
25
  },
26
 
27
- onMinValueChange: function( model, value ) {
28
- this.refreshValues();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- $( '[data-bind=default_value]', this.$el ).val( this.model.get( 'default_value' ) );
 
 
 
31
  },
32
 
33
- onMaxValueChange: function( model, value ) {
34
- this.refreshValues();
 
 
 
 
 
 
35
 
36
- $( '[data-bind=default_value]', this.$el ).val( this.model.get( 'default_value' ) );
 
 
 
 
 
 
 
37
  },
38
 
39
  onDefaultValueChange: function( model, value ) {
40
- this.refreshValues();
41
  },
42
 
43
- refreshValues: function() {
44
- var minValue = parseInt( this.model.get( 'min_value' ), 10 );
45
- var maxValue = parseInt( this.model.get( 'max_value' ), 10 );
46
- var defaultValue = parseInt( this.model.get( 'default_value' ), 10 );
47
 
48
- minValue = isNaN( minValue ) ? 0 : minValue;
49
- maxValue = isNaN( maxValue ) ? 0 : maxValue;
50
- defaultValue = isNaN( defaultValue ) ? 0 : defaultValue;
51
- defaultValue = Math.max( Math.min( defaultValue, maxValue ), minValue );
52
-
53
- this.model.set( 'default_value', defaultValue );
54
 
55
- var data = {
56
- id: this.model.get( 'id' ),
57
- callback: 'onScaleValuesChange',
58
- };
59
 
60
- api.previewer.send( 'happyforms-part-dom-update', data );
 
 
 
61
  },
62
 
63
  onStepChange: function( model, value ) {
@@ -85,25 +116,37 @@
85
  };
86
 
87
  api.previewer.send( 'happyforms-part-dom-update', data );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
  } );
90
 
91
  happyForms.previewer = _.extend( happyForms.previewer, {
92
- onScaleValuesChange: function( id, html, options ) {
93
- var part = this.getPartModel( id );
94
- var $part = this.getPartElement( html );
95
- var $input = this.$( 'input', $part );
96
- var $output = this.$( 'output', $part );
97
- var min = part.get( 'min_value' );
98
- var max = part.get( 'max_value' );
99
- var defaultValue = part.get( 'default_value' );
100
-
101
- $input.attr( 'min', min );
102
- $input.attr( 'max', max );
103
- $input.attr( 'value', defaultValue );
104
- $output.text( defaultValue );
105
- },
106
-
107
  onScaleStepChange: function( id, html, options ) {
108
  var part = this.getPartModel( id );
109
  var $part = this.getPartElement( html );
@@ -151,7 +194,7 @@
151
  return;
152
  }
153
 
154
- $( 'input', $el ).happyFormsScale();
155
  } );
156
 
157
  api.previewer.bind( 'happyforms-part-dom-updated', function ( $el ) {
16
  initialize: function() {
17
  happyForms.classes.views.Part.prototype.initialize.apply( this, arguments );
18
 
 
 
 
19
  this.listenTo( this.model, 'change:step', this.onStepChange );
20
  this.listenTo( this.model, 'change:min_label', this.onMinLabelChange );
21
  this.listenTo( this.model, 'change:max_label', this.onMaxLabelChange );
22
+ this.listenTo( this.model, 'change:multiple', this.onMultipleChange );
23
  },
24
 
25
+ events: function() {
26
+ return _.extend({}, happyForms.classes.views.Part.prototype.events, {
27
+ 'change [data-bind=default_value]': 'onDefaultValueChange',
28
+ 'change [data-bind=min_value]': 'onMinValueChange',
29
+ 'change [data-bind=max_value]': 'onMaxValueChange',
30
+ 'change [data-bind=default_range_from]': 'onDefaultRangeFromChange',
31
+ 'change [data-bind=default_range_to]': 'onDefaultRangeToChange'
32
+ });
33
+ },
34
+
35
+ onMinValueChange: function( e ) {
36
+ var model = this.model;
37
+ var value = $(e.target).val();
38
+
39
+ model.set('min_value', value);
40
+
41
+ if ( parseInt( value, 10 ) > parseInt( model.get( 'default_range_from' ), 10 ) ) {
42
+ model.set( 'default_range_from', value );
43
+ }
44
 
45
+ $( '[data-bind=default_value]', this.$el ).val( model.get( 'default_value' ) );
46
+ $( '[data-bind=default_range_from]', this.$el ).val( model.get( 'default_range_from' ) );
47
+
48
+ this.refreshScalePart();
49
  },
50
 
51
+ onMaxValueChange: function (e) {
52
+ var model = this.model;
53
+ var value = $(e.target).val();
54
+ var intValue = parseInt(value, 10);
55
+
56
+ if ( intValue < parseInt( model.get('default_value'), 10 ) ) {
57
+ model.set('default_value', value);
58
+ }
59
 
60
+ if ( intValue < parseInt( model.get('default_range_to'), 10 ) ) {
61
+ model.set('default_range_to', value );
62
+ }
63
+
64
+ $( '[data-bind=default_value]', this.$el ).val( model.get( 'default_value' ) );
65
+ $( '[data-bind=default_range_to]', this.$el ).val( model.get( 'default_range_to' ) );
66
+
67
+ this.refreshScalePart();
68
  },
69
 
70
  onDefaultValueChange: function( model, value ) {
71
+ this.refreshScalePart();
72
  },
73
 
74
+ onDefaultRangeFromChange: function( e ) {
75
+ var value = $(e.target).val();
76
+ var model = this.model;
 
77
 
78
+ if ( parseInt( value, 10 ) < parseInt( model.get('min_value'), 10 ) ) {
79
+ model.set('default_range_from', model.get('min_value'));
80
+ $('[data-bind=default_range_from]', this.$el).val(model.get('min_value'));
81
+ }
82
+ },
 
83
 
84
+ onDefaultRangeToChange: function( e ) {
85
+ var value = $(e.target).val();
86
+ var model = this.model;
 
87
 
88
+ if (parseInt(value, 10) > parseInt(model.get('max_value'), 10)) {
89
+ model.set('default_range_to', model.get('max_value'));
90
+ $('[data-bind=default_range_to]', this.$el).val(model.get('max_value'));
91
+ }
92
  },
93
 
94
  onStepChange: function( model, value ) {
116
  };
117
 
118
  api.previewer.send( 'happyforms-part-dom-update', data );
119
+ },
120
+
121
+ onMultipleChange: function ( model, value ) {
122
+ if ( 1 === value ) {
123
+ this.$el.find('.scale-multiple-options').css({
124
+ display: 'flex'
125
+ });
126
+ this.$el.find('.scale-single-options').hide();
127
+ } else {
128
+ this.$el.find('.scale-single-options').show();
129
+ this.$el.find('.scale-multiple-options').hide();
130
+ }
131
+
132
+ this.refreshScalePart();
133
+ },
134
+
135
+ refreshScalePart: function() {
136
+ var model = this.model;
137
+
138
+ model.fetchHtml(function (response) {
139
+ var data = {
140
+ id: model.get('id'),
141
+ html: response
142
+ };
143
+
144
+ api.previewer.send('happyforms-form-part-refresh', data);
145
+ });
146
  }
147
  } );
148
 
149
  happyForms.previewer = _.extend( happyForms.previewer, {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  onScaleStepChange: function( id, html, options ) {
151
  var part = this.getPartModel( id );
152
  var $part = this.getPartElement( html );
194
  return;
195
  }
196
 
197
+ $('input', $el).happyFormsScale();
198
  } );
199
 
200
  api.previewer.bind( 'happyforms-part-dom-updated', function ( $el ) {
assets/js/preview.js CHANGED
@@ -68,7 +68,11 @@
68
  } );
69
 
70
  $.each( $parts, function( i, $part ) {
71
- $submit.before( $part );
 
 
 
 
72
  } );
73
  }
74
 
@@ -108,6 +112,20 @@
108
  api.preview.send( 'happyforms-pencil-click-title' );
109
  }
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  handlers.silenceEvent = function( e ) {
112
  e.preventDefault();
113
  }
@@ -138,6 +156,8 @@
138
  api.preview.bind( 'happyforms-part-dom-update', handlers.partDomUpdate );
139
  api.preview.bind( 'happyforms-css-variable-update', handlers.cssVariableUpdate );
140
  api.preview.bind( 'happyforms-form-class-update', handlers.formClassUpdate );
 
 
141
 
142
  // Bind DOM handlers
143
  $( document.body ).on(
68
  } );
69
 
70
  $.each( $parts, function( i, $part ) {
71
+ if ( $recaptcha.length ) {
72
+ $recaptcha.before( $part );
73
+ } else {
74
+ $submit.before( $part );
75
+ }
76
  } );
77
  }
78
 
112
  api.preview.send( 'happyforms-pencil-click-title' );
113
  }
114
 
115
+ handlers.submitButtonTextUpdate = function ( text ) {
116
+ $( '.happyforms-button--submit' ).attr( 'value', text );
117
+ }
118
+
119
+ handlers.recaptchaUpdate = function( e ) {
120
+ var context = parent.happyForms.previewer;
121
+ var callback = context[e.callback];
122
+ var options = e.options || {}
123
+
124
+ if ( callback ) {
125
+ callback.call( context, $recaptcha, $ );
126
+ }
127
+ }
128
+
129
  handlers.silenceEvent = function( e ) {
130
  e.preventDefault();
131
  }
156
  api.preview.bind( 'happyforms-part-dom-update', handlers.partDomUpdate );
157
  api.preview.bind( 'happyforms-css-variable-update', handlers.cssVariableUpdate );
158
  api.preview.bind( 'happyforms-form-class-update', handlers.formClassUpdate );
159
+ api.preview.bind( 'happyforms-submit-button-text-update', handlers.submitButtonTextUpdate );
160
+ api.preview.bind( 'happyforms-form-recaptcha-update', handlers.recaptchaUpdate )
161
 
162
  // Bind DOM handlers
163
  $( document.body ).on(
happyforms.php CHANGED
@@ -5,7 +5,7 @@
5
  * Plugin URI: https://happyforms.me
6
  * Description: Your friendly drag and drop contact form builder for creating contact forms, lead generation forms, feedback forms, quote forms, survey forms and more!
7
  * Author: The Theme Foundry
8
- * Version: 1.4.6
9
  * Author URI: https://thethemefoundry.com
10
  * Upgrade URI: https://thethemefoundry.com
11
  */
@@ -13,7 +13,7 @@
13
  /**
14
  * The current version of the plugin.
15
  */
16
- define( 'HAPPYFORMS_VERSION', '1.4.6' );
17
 
18
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
19
  /**
5
  * Plugin URI: https://happyforms.me
6
  * Description: Your friendly drag and drop contact form builder for creating contact forms, lead generation forms, feedback forms, quote forms, survey forms and more!
7
  * Author: The Theme Foundry
8
+ * Version: 1.5.0
9
  * Author URI: https://thethemefoundry.com
10
  * Upgrade URI: https://thethemefoundry.com
11
  */
13
  /**
14
  * The current version of the plugin.
15
  */
16
+ define( 'HAPPYFORMS_VERSION', '1.5.0' );
17
 
18
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
19
  /**
inc/classes/class-email-message.php CHANGED
@@ -83,7 +83,7 @@ class HappyForms_Email_Message {
83
  $this->message = $message;
84
  }
85
 
86
- public function setSenders( $senders = array() ) {
87
  if ( is_string( $senders ) ) {
88
  $senders = array( $senders );
89
  }
@@ -109,7 +109,7 @@ class HappyForms_Email_Message {
109
  }
110
  }
111
 
112
- public function setRecipients( $recipients = array() ) {
113
  if ( is_string( $recipients ) ) {
114
  $recipients = array( $recipients );
115
  }
@@ -128,7 +128,7 @@ class HappyForms_Email_Message {
128
  $this->recipients = array_map( 'trim', $recipients );
129
  }
130
 
131
- public function setSubject( $subject = '' ) {
132
  $subject = trim( $subject );
133
 
134
  /**
@@ -137,14 +137,16 @@ class HappyForms_Email_Message {
137
  * @since 1.4.3
138
  *
139
  * @param string $subject Current subject.
 
 
140
  *
141
  * @return string
142
  */
143
- $subject = apply_filters( 'happyforms_email_subject', $subject, $this->message );
144
  $this->subject = $subject;
145
  }
146
 
147
- public function setContent( $content = '' ) {
148
  $content = trim( $content );
149
 
150
  /**
@@ -152,16 +154,18 @@ class HappyForms_Email_Message {
152
  *
153
  * @since 1.4.3
154
  *
155
- * @param string $content Current content.
156
- * @param array $message The submission this email was triggered from.
 
157
  *
158
  * @return string
159
  */
160
- $content = apply_filters( 'happyforms_email_content', $content, $this->message );
 
161
  $this->content = $content;
162
  }
163
 
164
- private function getHeaders() {
165
  $headers = array();
166
 
167
  array_push( $headers, 'From: ' . $this->from );
@@ -193,7 +197,7 @@ class HappyForms_Email_Message {
193
  public function send() {
194
  add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
195
 
196
- $headers = $this->getHeaders();
197
 
198
  foreach ( $this->recipients as $recipient ) {
199
  $result = wp_mail( $recipient, $this->subject, $this->content, $headers );
83
  $this->message = $message;
84
  }
85
 
86
+ public function set_senders( $senders = array() ) {
87
  if ( is_string( $senders ) ) {
88
  $senders = array( $senders );
89
  }
109
  }
110
  }
111
 
112
+ public function set_recipients( $recipients = array() ) {
113
  if ( is_string( $recipients ) ) {
114
  $recipients = array( $recipients );
115
  }
128
  $this->recipients = array_map( 'trim', $recipients );
129
  }
130
 
131
+ public function set_subject( $subject = '' ) {
132
  $subject = trim( $subject );
133
 
134
  /**
137
  * @since 1.4.3
138
  *
139
  * @param string $subject Current subject.
140
+ * @param array $message The submission this email was triggered from.
141
+ * @param array $recipients The address this email is being sent to.
142
  *
143
  * @return string
144
  */
145
+ $subject = apply_filters( 'happyforms_email_subject', $subject, $this->message, $this->recipients );
146
  $this->subject = $subject;
147
  }
148
 
149
+ public function set_content( $content = '' ) {
150
  $content = trim( $content );
151
 
152
  /**
154
  *
155
  * @since 1.4.3
156
  *
157
+ * @param string $content Current content.
158
+ * @param array $message The submission this email was triggered from.
159
+ * @param array $recipients The address this email is being sent to.
160
  *
161
  * @return string
162
  */
163
+ $content = apply_filters( 'happyforms_email_content', $content, $this->message, $this->recipients );
164
+
165
  $this->content = $content;
166
  }
167
 
168
+ private function get_headers() {
169
  $headers = array();
170
 
171
  array_push( $headers, 'From: ' . $this->from );
197
  public function send() {
198
  add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
199
 
200
+ $headers = $this->get_headers();
201
 
202
  foreach ( $this->recipients as $recipient ) {
203
  $result = wp_mail( $recipient, $this->subject, $this->content, $headers );
inc/classes/class-form-admin.php CHANGED
@@ -39,6 +39,7 @@ class HappyForms_Form_Admin {
39
  $post_type = happyforms_get_form_controller()->post_type;
40
 
41
  add_action( 'admin_head', array( $this, 'admin_head' ) );
 
42
  add_filter( "views_edit-{$post_type}", array( $this, 'table_view_links' ) );
43
  add_filter( 'get_edit_post_link', array( $this, 'get_edit_post_link' ), 10, 3 );
44
  add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
@@ -75,6 +76,29 @@ class HappyForms_Form_Admin {
75
  <?php endif;
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  /**
79
  * Filter: filter the row actions links
80
  * below entries in the All Forms admin table.
@@ -444,10 +468,6 @@ class HappyForms_Form_Admin {
444
 
445
  if ( 'edit.php' === $pagenow && $post_type === get_post_type() ) : ?>
446
  <script type="text/javascript">
447
- // Add New button
448
- var addNewElement = document.getElementsByClassName( 'page-title-action' )[0];
449
- addNewElement.setAttribute( 'href', '<?php echo happyforms_get_form_edit_link( 0 ); ?>' );
450
-
451
  // Shortcode copy-to-clipboard
452
  ( function ( $ ) {
453
  $( document ).on( 'click', 'a.happyforms-shortcode-clipboard', function( e ) {
39
  $post_type = happyforms_get_form_controller()->post_type;
40
 
41
  add_action( 'admin_head', array( $this, 'admin_head' ) );
42
+ add_filter( 'admin_url', array( $this, 'admin_url' ), 10, 2 );
43
  add_filter( "views_edit-{$post_type}", array( $this, 'table_view_links' ) );
44
  add_filter( 'get_edit_post_link', array( $this, 'get_edit_post_link' ), 10, 3 );
45
  add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
76
  <?php endif;
77
  }
78
 
79
+ /**
80
+ * Filter: filter the Add New link url
81
+ *
82
+ * @since 1.5
83
+ *
84
+ * @hooked filter admin_url
85
+ *
86
+ * @param string $url The current url
87
+ * @param string $path The current path
88
+ *
89
+ * @return array
90
+ */
91
+ public function admin_url( $url, $path ) {
92
+ $post_type = happyforms_get_form_controller()->post_type;
93
+ $new_form_url = 'post-new.php?post_type=' . $post_type;
94
+
95
+ if ( $new_form_url === $path ) {
96
+ $url = happyforms_get_form_edit_link( 0 );
97
+ }
98
+
99
+ return $url;
100
+ }
101
+
102
  /**
103
  * Filter: filter the row actions links
104
  * below entries in the All Forms admin table.
468
 
469
  if ( 'edit.php' === $pagenow && $post_type === get_post_type() ) : ?>
470
  <script type="text/javascript">
 
 
 
 
471
  // Shortcode copy-to-clipboard
472
  ( function ( $ ) {
473
  $( document ).on( 'click', 'a.happyforms-shortcode-clipboard', function( e ) {
inc/classes/class-form-controller.php CHANGED
@@ -51,7 +51,8 @@ class HappyForms_Form_Controller {
51
  add_action( 'trashed_post', array( $this, 'trashed_post' ) );
52
  add_action( 'delete_post', array( $this, 'delete_post' ) );
53
  add_action( 'untrashed_post', array( $this, 'untrashed_post' ) );
54
- add_action( 'happyforms_footer', array( $this, 'happyforms_footer' ) );
 
55
  }
56
 
57
  /**
@@ -91,6 +92,12 @@ class HappyForms_Form_Controller {
91
  );
92
 
93
  register_post_type( $this->post_type, $args );
 
 
 
 
 
 
94
  }
95
 
96
  /**
@@ -144,6 +151,9 @@ class HappyForms_Form_Controller {
144
 
145
  if ( $post->post_type == happyforms_get_form_controller()->post_type ) {
146
  if ( is_customize_preview() ) {
 
 
 
147
  $single_template = happyforms_get_include_folder() . '/templates/preview-form-edit.php';
148
  } else {
149
  $single_template = happyforms_get_include_folder() . '/templates/single-form.php';
@@ -743,7 +753,7 @@ class HappyForms_Form_Controller {
743
  *
744
  * @return string
745
  */
746
- public function render( $form = array() ) {
747
  $form_markup = '';
748
 
749
  if ( empty( $form ) ) {
@@ -751,13 +761,47 @@ class HappyForms_Form_Controller {
751
  }
752
 
753
  ob_start();
 
 
 
 
 
754
  require( happyforms_get_include_folder() . '/templates/single-form.php' );
755
  $form_markup = ob_get_clean();
756
 
757
  return $form_markup;
758
  }
759
 
760
- public function happyforms_footer( $forms ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761
  $has_captcha = false;
762
 
763
  foreach ( $forms as $form ) {
@@ -767,9 +811,25 @@ class HappyForms_Form_Controller {
767
  }
768
  }
769
 
770
- if ( $has_captcha ) : ?>
771
- <script src="https://www.google.com/recaptcha/api.js"></script>
772
- <?php endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773
  }
774
 
775
  }
51
  add_action( 'trashed_post', array( $this, 'trashed_post' ) );
52
  add_action( 'delete_post', array( $this, 'delete_post' ) );
53
  add_action( 'untrashed_post', array( $this, 'untrashed_post' ) );
54
+ add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
55
+ add_filter( 'happyforms_form_has_captcha', array( $this, 'has_captcha' ), 10, 2 );
56
  }
57
 
58
  /**
92
  );
93
 
94
  register_post_type( $this->post_type, $args );
95
+
96
+ $tracking_status = happyforms_get_tracking()->get_status();
97
+
98
+ if ( 1 === intval( $tracking_status['status'] ) ) {
99
+ flush_rewrite_rules();
100
+ }
101
  }
102
 
103
  /**
151
 
152
  if ( $post->post_type == happyforms_get_form_controller()->post_type ) {
153
  if ( is_customize_preview() ) {
154
+ add_filter( 'happyforms_part_class', array( $this, 'part_class' ) );
155
+ add_filter( 'happyforms_the_form_title', array( $this, 'form_title' ) );
156
+
157
  $single_template = happyforms_get_include_folder() . '/templates/preview-form-edit.php';
158
  } else {
159
  $single_template = happyforms_get_include_folder() . '/templates/single-form.php';
753
  *
754
  * @return string
755
  */
756
+ public function render( $form = array(), $render_styles = false ) {
757
  $form_markup = '';
758
 
759
  if ( empty( $form ) ) {
761
  }
762
 
763
  ob_start();
764
+
765
+ if ( $render_styles ) {
766
+ happyforms_the_form_styles( $form );
767
+ }
768
+
769
  require( happyforms_get_include_folder() . '/templates/single-form.php' );
770
  $form_markup = ob_get_clean();
771
 
772
  return $form_markup;
773
  }
774
 
775
+ public function has_captcha( $has_captcha, $form ) {
776
+ $has_captcha = $form['captcha'] || happyforms_is_preview();
777
+
778
+ return $has_captcha;
779
+ }
780
+
781
+ /**
782
+ * Filter: append -editable class to part templates.
783
+ *
784
+ * @since 1.0
785
+ *
786
+ * @hooked filter happyforms_part_class
787
+ *
788
+ * @return void
789
+ */
790
+ public function part_class( $classes ) {
791
+ $classes[] = 'happyforms-block-editable happyforms-block-editable--part';
792
+
793
+ return $classes;
794
+ }
795
+
796
+ public function form_title( $title ) {
797
+ $before = '<div class="happyforms-block-editable happyforms-block-editable--title">';
798
+ $after = '</div>';
799
+ $title = "{$before}{$title}{$after}";
800
+
801
+ return $title;
802
+ }
803
+
804
+ public function script_dependencies( $deps, $forms ) {
805
  $has_captcha = false;
806
 
807
  foreach ( $forms as $form ) {
811
  }
812
  }
813
 
814
+ if ( ! happyforms_is_preview() && ! $has_captcha ) {
815
+ return $deps;
816
+ }
817
+
818
+ wp_register_script(
819
+ 'google-recaptcha',
820
+ 'https://www.google.com/recaptcha/api.js',
821
+ array(), false, true
822
+ );
823
+
824
+ wp_register_script(
825
+ 'recaptcha',
826
+ happyforms_get_plugin_url() . 'assets/js/frontend/recaptcha.js',
827
+ array( 'google-recaptcha' ), false, true
828
+ );
829
+
830
+ $deps[] = 'recaptcha';
831
+
832
+ return $deps;
833
  }
834
 
835
  }
inc/classes/class-form-part.php CHANGED
@@ -26,12 +26,6 @@ class HappyForms_Form_Part {
26
 
27
  public function customize_enqueue_scripts( $deps = array() ) {}
28
 
29
- public function get_name( $id ) {
30
- return $this->type . '-' . $id;
31
- }
32
-
33
- public function get_message_definitions() {}
34
-
35
  public function get_default_value() {
36
  return '';
37
  }
26
 
27
  public function customize_enqueue_scripts( $deps = array() ) {}
28
 
 
 
 
 
 
 
29
  public function get_default_value() {
30
  return '';
31
  }
inc/classes/class-happyforms-plugin.php CHANGED
@@ -54,15 +54,15 @@ class HappyForms_Plugin {
54
 
55
  if ( is_admin() ) {
56
  require_once( happyforms_get_include_folder() . '/classes/class-admin-notices.php' );
57
- require_once( happyforms_get_include_folder() . '/classes/class-tracking.php' );
58
  }
59
 
 
60
  require_once( happyforms_get_include_folder() . '/classes/class-form-controller.php' );
61
  require_once( happyforms_get_include_folder() . '/classes/class-message-controller.php' );
62
  require_once( happyforms_get_include_folder() . '/classes/class-email-message.php' );
63
  require_once( happyforms_get_include_folder() . '/classes/class-form-part-library.php' );
64
  require_once( happyforms_get_include_folder() . '/classes/class-form-styles.php' );
65
- require_once( happyforms_get_include_folder() . '/classes/class-message-notices.php' );
66
  require_once( happyforms_get_include_folder() . '/classes/class-happyforms-widget.php' );
67
  require_once( happyforms_get_include_folder() . '/helpers/helper-form-templates.php' );
68
 
@@ -336,7 +336,7 @@ class HappyForms_Plugin {
336
  $form_id = intval( $attrs['id'] );
337
  $form_controller = happyforms_get_form_controller();
338
  $form = $form_controller->get( $form_id );
339
- $output = $form_controller->render( $form );
340
  $this->enqueue_form( $form );
341
 
342
  return $output;
54
 
55
  if ( is_admin() ) {
56
  require_once( happyforms_get_include_folder() . '/classes/class-admin-notices.php' );
 
57
  }
58
 
59
+ require_once( happyforms_get_include_folder() . '/classes/class-tracking.php' );
60
  require_once( happyforms_get_include_folder() . '/classes/class-form-controller.php' );
61
  require_once( happyforms_get_include_folder() . '/classes/class-message-controller.php' );
62
  require_once( happyforms_get_include_folder() . '/classes/class-email-message.php' );
63
  require_once( happyforms_get_include_folder() . '/classes/class-form-part-library.php' );
64
  require_once( happyforms_get_include_folder() . '/classes/class-form-styles.php' );
65
+ require_once( happyforms_get_include_folder() . '/classes/class-session.php' );
66
  require_once( happyforms_get_include_folder() . '/classes/class-happyforms-widget.php' );
67
  require_once( happyforms_get_include_folder() . '/helpers/helper-form-templates.php' );
68
 
336
  $form_id = intval( $attrs['id'] );
337
  $form_controller = happyforms_get_form_controller();
338
  $form = $form_controller->get( $form_id );
339
+ $output = $form_controller->render( $form, true );
340
  $this->enqueue_form( $form );
341
 
342
  return $output;
inc/classes/class-message-controller.php CHANGED
@@ -190,84 +190,97 @@ class HappyForms_Message_Controller {
190
  return;
191
  }
192
 
193
- $bad_request_error = __( 'Bad request.', 'happyforms' );
194
-
195
  if ( ! isset ( $_REQUEST[$this->submit_parameter] ) ) {
196
- wp_die( $bad_request_error );
197
- }
198
-
199
- if ( ! isset( $_REQUEST[$this->nonce_name] ) ) {
200
- wp_die( $bad_request_error );
201
  }
202
 
203
- $nonce = $_REQUEST[$this->nonce_name];
204
  $form_id = intval( $_REQUEST[$this->submit_parameter] );
205
 
206
- if ( ! $this->verify_nonce( $nonce, $form_id ) ) {
207
- wp_die( $bad_request_error );
 
 
 
208
  }
209
 
210
- $form = happyforms_get_form_controller()->get( $form_id );
 
 
 
 
 
 
211
 
 
212
  if ( happyforms_get_form_controller()->has_spam_protection( $form ) ) {
213
  if ( ! $this->validate_honeypot( $form ) ) {
214
- $redirect_url = home_url( wp_get_raw_referer() );
215
-
216
- // Redirect silently, like everything's good.
217
- wp_safe_redirect( $redirect_url );
218
- exit;
219
  }
220
  }
221
 
 
222
  if ( happyforms_get_form_controller()->has_recaptcha_protection( $form ) ) {
223
  $captcha_value = $this->validate_captcha( $form );
224
 
225
  if ( is_wp_error( $captcha_value ) ) {
226
- $redirect_url = home_url( wp_get_raw_referer() );
227
-
228
- // Redirect silently, like everything's good.
229
- wp_safe_redirect( $redirect_url );
230
- exit;
231
  }
232
  }
233
 
234
- if ( is_wp_error( $form ) ) {
235
- wp_die( $bad_request_error );
236
- }
237
-
238
  $result = $this->create( $form );
239
- $message_notices = happyforms_get_message_notices();
240
- $redirect_url = home_url( wp_get_raw_referer() );
241
-
242
- if ( is_wp_error( $result ) ) {
243
- $part_ids = $result->get_error_codes();
244
-
245
- foreach( $part_ids as $part_id ) {
246
- $error_messages = $result->get_error_messages( $part_id );
247
-
248
- foreach( $error_messages as $error_message ) {
249
- $message_notices->add_message( $error_message, $form_id, $part_id );
250
- }
251
- }
252
 
 
253
  // Add a general error notice at the top
254
- $message_notices->add_message( 'form_error', $form_id );
 
 
 
 
 
 
 
 
 
 
 
 
255
  } else {
256
  // Add a general success notice at the top
257
- $message_notices->add_message( 'form_success', $form_id );
 
 
 
258
 
259
  // Update the unread badge
260
  $this->update_badge_transient();
261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  if ( ! empty( $form['redirect_url'] ) ) {
263
- $redirect_url = $form['redirect_url'];
264
  }
 
 
265
  }
266
 
267
- // Write the session cookie
268
- $message_notices->write();
269
- wp_safe_redirect( $redirect_url );
270
- exit;
271
  }
272
 
273
  /**
@@ -372,32 +385,32 @@ class HappyForms_Message_Controller {
372
  'form_id' => $form['ID'],
373
  ), $defaults['meta'] );
374
  $message_parts = array();
375
- $error = null;
 
376
 
377
- foreach( $form['parts'] as $part_data ) {
378
- $part = happyforms_get_part_library()->get_part( $part_data['type'] );
379
 
380
- if ( false !== $part ) {
381
- $part_value = $part->sanitize_value( $part_data, $form );
382
- $part_value = $part->validate_value( $part_data, $part_value );
383
- $part_id = $part_data['id'];
384
- $part_name = happyforms_get_part_name( $part_data, $form );
385
 
386
- if ( ! is_wp_error( $part_value ) ) {
387
- $message_meta[$part_id] = $part_value;
388
- } else {
389
- $error = null === $error ? new WP_Error(): $error;
390
- $messages = $part_value->get_error_codes();
391
 
392
- foreach ( $messages as $message ) {
393
- $error->add( $part_name, $message );
394
- }
 
 
 
395
  }
396
  }
397
  }
398
 
399
- if ( is_wp_error( $error ) ) {
400
- return $error;
401
  }
402
 
403
  $attrs = $defaults['post'] + array( 'meta_input' => $message_meta );
@@ -412,6 +425,8 @@ class HappyForms_Message_Controller {
412
  wp_delete_post( $message_id, true);
413
  }
414
  }
 
 
415
  }
416
 
417
  /**
@@ -526,13 +541,19 @@ class HappyForms_Message_Controller {
526
  // Compose an email message
527
  $email_message = new HappyForms_Email_Message( $message );
528
  $recipients = explode( ',', $form['email_recipient'] );
529
- $email_message->setRecipients( $recipients );
530
- $email_message->setSubject( $form['alert_email_subject'] );
531
 
532
  // Compose content with submit data
533
  $content_lines = array();
534
 
535
  foreach ( $form['parts'] as $part_data ) {
 
 
 
 
 
 
536
  $part_id = $part_data['id'];
537
  $label = happyforms_get_part_label( $part_data );
538
  $value = happyforms_get_message_part_value( $message['parts'][$part_id] );
@@ -540,7 +561,7 @@ class HappyForms_Message_Controller {
540
  }
541
 
542
  $content = implode( '<br>', $content_lines );
543
- $email_message->setContent( $content );
544
 
545
  // Add a From header it the form includes an email part
546
  $email_part = happyforms_get_form_controller()->get_first_part_by_type( $form, 'email' );
@@ -548,7 +569,7 @@ class HappyForms_Message_Controller {
548
  if ( false !== $email_part ) {
549
  $part_id = $email_part['id'];
550
  $sender = happyforms_get_message_part_value( $message['parts'][$part_id] );
551
- $email_message->setSenders( $sender );
552
  }
553
 
554
  $email_message->send();
@@ -575,12 +596,12 @@ class HappyForms_Message_Controller {
575
  // Compose an email message
576
  $email_message = new HappyForms_Email_Message( $message );
577
  $senders = explode( ',', $form['email_recipient'] );
578
- $email_message->setSenders( $senders );
579
- $email_message->setSubject( $form['confirmation_email_subject'] );
580
  $part_id = $email_part['id'];
581
  $recipient = happyforms_get_message_part_value( $message['parts'][$part_id] );
582
- $email_message->setRecipients( $recipient );
583
- $email_message->setContent( $form['confirmation_email_content'] );
584
 
585
  $email_message->send();
586
  }
190
  return;
191
  }
192
 
193
+ // Check form_id parameter
 
194
  if ( ! isset ( $_REQUEST[$this->submit_parameter] ) ) {
195
+ wp_send_json_error();
 
 
 
 
196
  }
197
 
 
198
  $form_id = intval( $_REQUEST[$this->submit_parameter] );
199
 
200
+ // Validate nonce
201
+ if ( ! isset( $_REQUEST[$this->nonce_name] )
202
+ || ! $this->verify_nonce( $_REQUEST[$this->nonce_name], $form_id ) ) {
203
+
204
+ wp_send_json_error();
205
  }
206
 
207
+ $form_controller = happyforms_get_form_controller();
208
+ $form = $form_controller->get( $form_id );
209
+
210
+ // Check if form found
211
+ if ( ! $form || is_wp_error( $form ) ) {
212
+ wp_send_json_error();
213
+ }
214
 
215
+ // Validate honeypot
216
  if ( happyforms_get_form_controller()->has_spam_protection( $form ) ) {
217
  if ( ! $this->validate_honeypot( $form ) ) {
218
+ wp_send_json_error();
 
 
 
 
219
  }
220
  }
221
 
222
+ // Validate ReCaptcha
223
  if ( happyforms_get_form_controller()->has_recaptcha_protection( $form ) ) {
224
  $captcha_value = $this->validate_captcha( $form );
225
 
226
  if ( is_wp_error( $captcha_value ) ) {
227
+ wp_send_json_error();
 
 
 
 
228
  }
229
  }
230
 
 
 
 
 
231
  $result = $this->create( $form );
232
+ $session = happyforms_get_session();
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
+ if ( ! $result ) {
235
  // Add a general error notice at the top
236
+ $session->add_error( $form_id, __( 'Your submission contains errors.', 'happyforms' ) );
237
+
238
+ /**
239
+ * This action fires upon an invalid submission.
240
+ *
241
+ * @since 1.4
242
+ *
243
+ * @param WP_Error $result Error data.
244
+ * @param array $form Current form data.
245
+ *
246
+ * @return void
247
+ */
248
+ do_action( 'happyforms_submission_error', $result, $form );
249
  } else {
250
  // Add a general success notice at the top
251
+ $session->add_notice( $form_id, $form['confirmation_message'] );
252
+
253
+ // Empty submitted values
254
+ $session->clear_values();
255
 
256
  // Update the unread badge
257
  $this->update_badge_transient();
258
 
259
+ /**
260
+ * This action fires once a message is succesfully submitted.
261
+ *
262
+ * @since 1.4
263
+ *
264
+ * @param array $result Submission data.
265
+ * @param array $form Current form data.
266
+ *
267
+ * @return void
268
+ */
269
+ do_action( 'happyforms_submission_success', $result, $form );
270
+ }
271
+
272
+ $response = array();
273
+ $response['html'] = $form_controller->render( $form );
274
+
275
+ if ( ! is_wp_error( $result ) ) {
276
  if ( ! empty( $form['redirect_url'] ) ) {
277
+ $response['redirect'] = $form['redirect_url'];
278
  }
279
+
280
+ wp_send_json_success( $response );
281
  }
282
 
283
+ wp_send_json_error( $response );
 
 
 
284
  }
285
 
286
  /**
385
  'form_id' => $form['ID'],
386
  ), $defaults['meta'] );
387
  $message_parts = array();
388
+ $success = true;
389
+ $session = happyforms_get_session();
390
 
391
+ foreach( $form['parts'] as $part ) {
392
+ $part_class = happyforms_get_part_library()->get_part( $part['type'] );
393
 
394
+ if ( false !== $part_class ) {
395
+ $part_id = $part['id'];
396
+ $part_name = happyforms_get_part_name( $part, $form );
397
+ $sanitized_value = $part_class->sanitize_value( $part, $form );
398
+ $validated_value = $part_class->validate_value( $sanitized_value, $part, $form );
399
 
400
+ $session->add_value( $part_name, $sanitized_value );
 
 
 
 
401
 
402
+ if ( ! is_wp_error( $validated_value ) ) {
403
+ $string_value = happyforms_stringify_part_value( $validated_value, $part, $form );
404
+ $message_meta[$part_id] = $string_value;
405
+ } else {
406
+ $success = false;
407
+ $session->add_error( $part_name, $validated_value->get_error_message() );
408
  }
409
  }
410
  }
411
 
412
+ if ( ! $success ) {
413
+ return false;
414
  }
415
 
416
  $attrs = $defaults['post'] + array( 'meta_input' => $message_meta );
425
  wp_delete_post( $message_id, true);
426
  }
427
  }
428
+
429
+ return true;
430
  }
431
 
432
  /**
541
  // Compose an email message
542
  $email_message = new HappyForms_Email_Message( $message );
543
  $recipients = explode( ',', $form['email_recipient'] );
544
+ $email_message->set_recipients( $recipients );
545
+ $email_message->set_subject( $form['alert_email_subject'] );
546
 
547
  // Compose content with submit data
548
  $content_lines = array();
549
 
550
  foreach ( $form['parts'] as $part_data ) {
551
+ $visible = apply_filters( 'happyforms_message_part_visible', true, $part_data );
552
+
553
+ if ( ! $visible ) {
554
+ continue;
555
+ }
556
+
557
  $part_id = $part_data['id'];
558
  $label = happyforms_get_part_label( $part_data );
559
  $value = happyforms_get_message_part_value( $message['parts'][$part_id] );
561
  }
562
 
563
  $content = implode( '<br>', $content_lines );
564
+ $email_message->set_content( $content );
565
 
566
  // Add a From header it the form includes an email part
567
  $email_part = happyforms_get_form_controller()->get_first_part_by_type( $form, 'email' );
569
  if ( false !== $email_part ) {
570
  $part_id = $email_part['id'];
571
  $sender = happyforms_get_message_part_value( $message['parts'][$part_id] );
572
+ $email_message->set_senders( $sender );
573
  }
574
 
575
  $email_message->send();
596
  // Compose an email message
597
  $email_message = new HappyForms_Email_Message( $message );
598
  $senders = explode( ',', $form['email_recipient'] );
599
+ $email_message->set_senders( $senders );
600
+ $email_message->set_subject( $form['confirmation_email_subject'] );
601
  $part_id = $email_part['id'];
602
  $recipient = happyforms_get_message_part_value( $message['parts'][$part_id] );
603
+ $email_message->set_recipients( $recipient );
604
+ $email_message->set_content( $form['confirmation_email_content'] );
605
 
606
  $email_message->send();
607
  }
inc/classes/class-message-notices.php DELETED
@@ -1,191 +0,0 @@
1
- <?php
2
-
3
- class HappyForms_Message_Notices {
4
-
5
- /**
6
- * The singleton instance.
7
- *
8
- * @since 1.0
9
- *
10
- * @var HappyForms_Message_Notices
11
- */
12
- private static $instance;
13
-
14
- /**
15
- * The name of the cookie used to store
16
- * session notices.
17
- *
18
- * @since 1.0
19
- *
20
- * @var string
21
- */
22
- private $cookie_name = 'happyforms-message-notices';
23
-
24
- /**
25
- * The list of notices registered for this session.
26
- *
27
- * @since 1.0
28
- *
29
- * @var array
30
- */
31
- private $session = array();
32
-
33
- /**
34
- * The list of registered notice messages.
35
- *
36
- * @since 1.0
37
- *
38
- * @var array
39
- */
40
- private $messages = array();
41
-
42
- /**
43
- * The singleton constructor.
44
- *
45
- * @since 1.0
46
- *
47
- * @return HappyForms_Message_Admin
48
- */
49
- public static function instance() {
50
- if ( is_null( self::$instance ) ) {
51
- self::$instance = new self();
52
- }
53
-
54
- self::$instance->hook();
55
-
56
- return self::$instance;
57
- }
58
-
59
- /**
60
- * Register hooks.
61
- *
62
- * @since 1.0
63
- *
64
- * @return void
65
- */
66
- public function hook() {
67
- if ( ! is_admin() ) {
68
- add_action( 'send_headers', array( $this, 'read' ) );
69
- }
70
- }
71
-
72
- /**
73
- * Add a notice to be displayed on the next refresh.
74
- *
75
- * @since 1.0
76
- *
77
- * @return void
78
- */
79
- public function add_message( $key, $form_id, $location = 'top' ) {
80
- $this->session[] = array(
81
- 'key' => $key,
82
- 'form_id' => $form_id,
83
- 'location' => $location,
84
- );
85
- }
86
-
87
- /**
88
- * Write the notices registered for this session
89
- * in the session cookie.
90
- *
91
- * @since 1.0
92
- *
93
- * @return void
94
- */
95
- public function write() {
96
- $session_data = json_encode( $this->session );
97
- setcookie( $this->cookie_name, $session_data, 0, '/' );
98
- }
99
-
100
- /**
101
- * Read the notices registered for this session
102
- * from the session cookie.
103
- *
104
- * @since 1.0
105
- *
106
- * @return void
107
- */
108
- public function read() {
109
- $this->messages = array();
110
-
111
- if ( isset( $_COOKIE[ $this->cookie_name ] ) && ! empty( $_COOKIE[ $this->cookie_name ] ) ) {
112
- $this->messages = json_decode( stripslashes( $_COOKIE[ $this->cookie_name ] ), true );
113
- unset( $_COOKIE[ $this->cookie_name ] );
114
- setcookie( $this->cookie_name, '', time() - 3600, '/' );
115
- }
116
- }
117
-
118
- /**
119
- * Get the messages for the given form and location.
120
- *
121
- * @since 1.0
122
- *
123
- * @param array $form_data The current form data.
124
- * @param string $location The location to fetch messages for.
125
- *
126
- * @return array
127
- */
128
- public function get_messages( $form_data, $location = 'top' ) {
129
- $messages = array();
130
- $location = is_numeric( $location ) ? intval( $location ) : $location;
131
-
132
- foreach( $this->messages as $message ) {
133
- $message_key = $message['key'];
134
- $message_form_id = $message['form_id'];
135
- $message_location = $message['location'];
136
- $message_definition = null;
137
-
138
- if ( $form_data['ID'] === $message_form_id && $location === $message_location ) {
139
- $part_library = happyforms_get_part_library();
140
- $is_part_notice = false;
141
-
142
- foreach( $form_data['parts'] as $part_data ) {
143
- $part_name = happyforms_get_part_name( $part_data, $form_data );
144
-
145
- if ( $location === $part_name ) {
146
- $part = $part_library->get_part( $part_data['type'] );
147
- $message_definitions = $part->get_message_definitions();
148
- $message_definition = $message_definitions[$message_key];
149
- $is_part_notice = true;
150
- break;
151
- }
152
- }
153
-
154
- if ( ! $is_part_notice ) {
155
- $form_controller = happyforms_get_form_controller();
156
- $message_definitions = $form_controller->get_message_definitions( $form_data );
157
- $message_definition = $message_definitions[$message_key];
158
- }
159
- }
160
-
161
- if ( null !== $message_definition ) {
162
- $messages[] = array(
163
- 'type' => $message_definition['type'],
164
- 'message' => $message_definition['message'],
165
- );
166
- }
167
- }
168
-
169
- return $messages;
170
- }
171
-
172
- }
173
-
174
- if ( ! function_exists( 'happyforms_get_message_notices' ) ):
175
- /**
176
- * Get the HappyForms_Message_Notices class instance.
177
- *
178
- * @since 1.0
179
- *
180
- * @return HappyForms_Message_Notices
181
- */
182
- function happyforms_get_message_notices() {
183
- return HappyForms_Message_Notices::instance();
184
- }
185
-
186
- endif;
187
-
188
- /**
189
- * Initialize the HappyForms_Message_Admin class immediately.
190
- */
191
- happyforms_get_message_notices();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/classes/class-session.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class HappyForms_Session {
4
+
5
+ /**
6
+ * The singleton instance.
7
+ *
8
+ * @since 1.0
9
+ *
10
+ * @var HappyForms_Session
11
+ */
12
+ private static $instance;
13
+
14
+ /**
15
+ * The list of registered errors.
16
+ *
17
+ * @since 1.4.6
18
+ *
19
+ * @var array
20
+ */
21
+ private $errors = array();
22
+
23
+ /**
24
+ * The list of registered notices.
25
+ *
26
+ * @since 1.4.6
27
+ *
28
+ * @var array
29
+ */
30
+ private $notices = array();
31
+
32
+ /**
33
+ * A list of submit values.
34
+ *
35
+ * @since 1.4.6
36
+ *
37
+ * @var array
38
+ */
39
+ private $values = array();
40
+
41
+ /**
42
+ * The singleton constructor.
43
+ *
44
+ * @since 1.0
45
+ *
46
+ * @return HappyForms_Message_Admin
47
+ */
48
+ public static function instance() {
49
+ if ( is_null( self::$instance ) ) {
50
+ self::$instance = new self();
51
+ }
52
+
53
+ return self::$instance;
54
+ }
55
+
56
+ public function add_error( $key, $message ) {
57
+ $this->errors[$key] = $message;
58
+ }
59
+
60
+ /**
61
+ * Add a notice to be displayed on the next refresh.
62
+ *
63
+ * @since 1.0
64
+ *
65
+ * @return void
66
+ */
67
+ public function add_notice( $key, $message ) {
68
+ $this->notices[$key] = $message;
69
+ }
70
+
71
+ public function add_value( $key, $value ) {
72
+ $this->values[$key] = $value;
73
+ }
74
+
75
+ /**
76
+ * Get the messages for the given form and location.
77
+ *
78
+ * @since 1.0
79
+ *
80
+ * @param string $location The location to fetch messages for.
81
+ *
82
+ * @return array
83
+ */
84
+ public function get_messages( $location = '' ) {
85
+ $messages = array();
86
+
87
+ if ( isset( $this->notices[$location] ) ) {
88
+ $messages[] = array(
89
+ 'type' => 'success',
90
+ 'message' => $this->notices[$location],
91
+ );
92
+ }
93
+
94
+ if ( isset( $this->errors[$location] ) ) {
95
+ $messages[] = array(
96
+ 'type' => 'error',
97
+ 'message' => $this->errors[$location],
98
+ );
99
+ }
100
+
101
+ return $messages;
102
+ }
103
+
104
+ public function get_values() {
105
+ return $this->values;
106
+ }
107
+
108
+ public function get_value( $location = '', $component = false ) {
109
+ $value = '';
110
+
111
+ if ( isset( $this->values[$location] ) ) {
112
+ $value = $this->values[$location];
113
+
114
+ if ( false !== $component ) {
115
+ $value = isset( $value[$component] ) ? $value[$component] : '';
116
+ }
117
+ }
118
+
119
+ return $value;
120
+ }
121
+
122
+ public function clear_values() {
123
+ $this->values = array();
124
+ }
125
+
126
+ }
127
+
128
+ if ( ! function_exists( 'happyforms_get_session' ) ):
129
+ /**
130
+ * Get the HappyForms_Session class instance.
131
+ *
132
+ * @since 1.0
133
+ *
134
+ * @return HappyForms_Session
135
+ */
136
+ function happyforms_get_session() {
137
+ return HappyForms_Session::instance();
138
+ }
139
+
140
+ endif;
inc/classes/class-wp-customize-form-manager.php CHANGED
@@ -27,8 +27,6 @@ class HappyForms_WP_Customize_Form_Manager {
27
  // Ajax callbacks.
28
  add_action( 'wp_ajax_happyforms-update-form', array( $this, 'ajax_update_form' ) );
29
  add_action( 'wp_ajax_happyforms-form-part-add', array( $this, 'ajax_form_part_add' ) );
30
-
31
- add_filter( 'happyforms_part_class', array( $this, 'happyforms_part_class' ) );
32
  }
33
 
34
  /**
@@ -237,21 +235,6 @@ class HappyForms_WP_Customize_Form_Manager {
237
  exit();
238
  }
239
 
240
- /**
241
- * Filter: append -editable class to part templates.
242
- *
243
- * @since 1.0
244
- *
245
- * @hooked filter happyforms_part_class
246
- *
247
- * @return void
248
- */
249
- public function happyforms_part_class( $classes ) {
250
- $classes[] = 'happyforms-block-editable happyforms-block-editable--part';
251
-
252
- return $classes;
253
- }
254
-
255
  /**
256
  * Action: output styles for the Customize screen.
257
  *
27
  // Ajax callbacks.
28
  add_action( 'wp_ajax_happyforms-update-form', array( $this, 'ajax_update_form' ) );
29
  add_action( 'wp_ajax_happyforms-form-part-add', array( $this, 'ajax_form_part_add' ) );
 
 
30
  }
31
 
32
  /**
235
  exit();
236
  }
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  /**
239
  * Action: output styles for the Customize screen.
240
  *
inc/classes/parts/class-part-address.php CHANGED
@@ -15,7 +15,10 @@ class HappyForms_Part_Address extends HappyForms_Form_Part {
15
 
16
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
17
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
 
 
18
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
 
19
  add_action( 'wp_ajax_' . $this->ajax_action_autocomplete, array( $this, 'ajax_autocomplete' ) );
20
  add_action( 'wp_ajax_nopriv_' . $this->ajax_action_autocomplete, array( $this, 'ajax_autocomplete' ) );
21
  add_action( 'wp_ajax_' . $this->ajax_action_geocode, array( $this, 'ajax_geocode' ) );
@@ -113,22 +116,6 @@ class HappyForms_Part_Address extends HappyForms_Form_Part {
113
  include( happyforms_get_include_folder() . '/templates/parts/frontend-address.php' );
114
  }
115
 
116
- /**
117
- * Get all possible messages definitions.
118
- *
119
- * @since 1.0.0.
120
- *
121
- * @return array Associative array, specifying message type and copy.
122
- */
123
- public function get_message_definitions() {
124
- return array(
125
- 'missing_required_field' => array(
126
- 'type' => 'error',
127
- 'message' => __( 'This field is required.', 'happyforms' ),
128
- ),
129
- );
130
- }
131
-
132
  public function get_default_value() {
133
  return array(
134
  'full' => '',
@@ -172,22 +159,23 @@ class HappyForms_Part_Address extends HappyForms_Form_Part {
172
  }
173
 
174
  /**
175
- * Validate value before submitting it. If it fails validation, return WP_Error object, showing respective error message.
 
176
  *
177
  * @since 1.0.0.
178
  *
179
- * @param array $part_data Form part data.
180
  * @param string $value Submitted value.
181
  *
182
  * @return string|object
183
  */
184
- public function validate_value( $part_data, $value ) {
185
  $validated_value = $value;
186
 
187
- if ( 1 === $part_data['required'] ) {
188
  $is_empty = false;
189
 
190
- switch ( $part_data['mode'] ) {
191
  case 'simple':
192
  case 'autocomplete':
193
  $is_empty = empty( $validated_value['full'] );
@@ -201,8 +189,7 @@ class HappyForms_Part_Address extends HappyForms_Form_Part {
201
  }
202
 
203
  if ( $is_empty ) {
204
- $validated_value = new WP_Error( 'missing_required_field' );
205
- return $validated_value;
206
  }
207
  }
208
 
@@ -264,18 +251,57 @@ class HappyForms_Part_Address extends HappyForms_Form_Part {
264
  wp_send_json( $results );
265
  }
266
 
267
- public function html_part_class( $class, $part_data, $form_data ) {
268
- if ( isset( $part_data['mode'] ) && 'country-city' === $part_data['mode'] ) {
269
- $class[] = 'happyforms-part--address-country-city';
270
- }
 
 
 
 
 
 
 
271
 
272
- if ( isset( $part_data['has_geolocation'] ) && $part_data['has_geolocation'] ) {
273
- $class[] = 'happyforms-part--address-has-geolocation';
 
274
  }
275
 
276
  return $class;
277
  }
278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  public function html_part_data_attributes( $attributes, $part, $form ) {
280
  if ( $this->type !== $part['type'] ) {
281
  return $attributes;
15
 
16
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
17
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
18
+ add_filter( 'happyforms_part_value', array( $this, 'get_part_value' ), 10, 4 );
19
+ add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
20
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
21
+
22
  add_action( 'wp_ajax_' . $this->ajax_action_autocomplete, array( $this, 'ajax_autocomplete' ) );
23
  add_action( 'wp_ajax_nopriv_' . $this->ajax_action_autocomplete, array( $this, 'ajax_autocomplete' ) );
24
  add_action( 'wp_ajax_' . $this->ajax_action_geocode, array( $this, 'ajax_geocode' ) );
116
  include( happyforms_get_include_folder() . '/templates/parts/frontend-address.php' );
117
  }
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  public function get_default_value() {
120
  return array(
121
  'full' => '',
159
  }
160
 
161
  /**
162
+ * Validate value before submitting it. If it fails validation,
163
+ * return WP_Error object, showing respective error message.
164
  *
165
  * @since 1.0.0.
166
  *
167
+ * @param array $part Form part data.
168
  * @param string $value Submitted value.
169
  *
170
  * @return string|object
171
  */
172
+ public function validate_value( $value, $part = array(), $form = array() ) {
173
  $validated_value = $value;
174
 
175
+ if ( 1 === $part['required'] ) {
176
  $is_empty = false;
177
 
178
+ switch ( $part['mode'] ) {
179
  case 'simple':
180
  case 'autocomplete':
181
  $is_empty = empty( $validated_value['full'] );
189
  }
190
 
191
  if ( $is_empty ) {
192
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
193
  }
194
  }
195
 
251
  wp_send_json( $results );
252
  }
253
 
254
+ public function html_part_class( $class, $part, $form ) {
255
+ if ( $this->type === $part['type'] ) {
256
+ if ( happyforms_get_part_value( $part, $form, 'full' )
257
+ || happyforms_get_part_value( $part, $form, 'country' )
258
+ || happyforms_get_part_value( $part, $form, 'city' ) ) {
259
+ $class[] = 'happyforms-part--filled';
260
+ }
261
+
262
+ if ( isset( $part['mode'] ) && 'country-city' === $part['mode'] ) {
263
+ $class[] = 'happyforms-part--address-country-city';
264
+ }
265
 
266
+ if ( isset( $part['has_geolocation'] ) && $part['has_geolocation'] ) {
267
+ $class[] = 'happyforms-part--address-has-geolocation';
268
+ }
269
  }
270
 
271
  return $class;
272
  }
273
 
274
+ public function get_part_value( $value, $part, $form, $component ) {
275
+ if ( $this->type === $part['type'] ) {
276
+ if ( false !== $component ) {
277
+ $value = isset( $value[$component] ) ? $value[$component] : '';
278
+ }
279
+ }
280
+
281
+ return $value;
282
+ }
283
+
284
+ public function stringify_value( $value, $part, $form ) {
285
+ if ( $this->type === $part['type'] ) {
286
+ extract( $value );
287
+
288
+ switch ( $part['mode'] ) {
289
+ case 'simple':
290
+ case 'autocomplete':
291
+ $value = $full;
292
+ break;
293
+ case 'country':
294
+ $value = $city;
295
+ break;
296
+ case 'country-city':
297
+ $value = "{$city}, {$country}";
298
+ break;
299
+ }
300
+ }
301
+
302
+ return $value;
303
+ }
304
+
305
  public function html_part_data_attributes( $attributes, $part, $form ) {
306
  if ( $this->type !== $part['type'] ) {
307
  return $attributes;
inc/classes/parts/class-part-checkbox.php CHANGED
@@ -9,6 +9,7 @@ class HappyForms_Part_Checkbox extends HappyForms_Form_Part {
9
  $this->description = __( 'For checkboxes allowing multiple selections.', 'happyforms' );
10
 
11
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
 
12
  }
13
 
14
  /**
@@ -119,26 +120,6 @@ class HappyForms_Part_Checkbox extends HappyForms_Form_Part {
119
  );
120
  }
121
 
122
- /**
123
- * Get all possible messages definitions.
124
- *
125
- * @since 1.0.0.
126
- *
127
- * @return array Associative array, specifying message type and copy.
128
- */
129
- public function get_message_definitions() {
130
- return array(
131
- 'missing_required_field' => array(
132
- 'type' => 'error',
133
- 'message' => __( 'This field is required.', 'happyforms' ),
134
- ),
135
- 'not_valid_value' => array(
136
- 'type' => 'error',
137
- 'message' => __( 'Checkbox values are not valid.', 'happyforms' )
138
- )
139
- );
140
- }
141
-
142
  public function get_default_value() {
143
  return array();
144
  }
@@ -172,32 +153,44 @@ class HappyForms_Part_Checkbox extends HappyForms_Form_Part {
172
  *
173
  * @since 1.0.0.
174
  *
175
- * @param array $part_data Form part data.
176
  * @param string $value Submitted value.
177
  *
178
  * @return string|object
179
  */
180
- public function validate_value( $part_data, $value ) {
181
  $validated_value = $value;
182
 
183
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
184
- $validated_value = new WP_Error( 'missing_required_field' );
185
  return $validated_value;
186
  }
187
 
188
- $options = wp_list_pluck( $part_data['options'], 'label' );
 
189
  $intersection = array_intersect( $options, $validated_value );
190
 
191
  if ( ! count( $intersection ) ) {
192
- $validated_value = new WP_Error( 'not_valid_value' );
193
  return $validated_value;
194
  }
195
 
196
  return $validated_value;
197
  }
198
 
199
- public function html_part_class( $class, $part_data, $form_data ) {
200
- if ( isset( $part_data['display_type'] ) && 'block' === $part_data['display_type'] ) {
 
 
 
 
 
 
 
 
 
 
 
201
  $class[] = 'display-type--block';
202
  }
203
 
9
  $this->description = __( 'For checkboxes allowing multiple selections.', 'happyforms' );
10
 
11
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
+ add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
13
  }
14
 
15
  /**
120
  );
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  public function get_default_value() {
124
  return array();
125
  }
153
  *
154
  * @since 1.0.0.
155
  *
156
+ * @param array $part Form part data.
157
  * @param string $value Submitted value.
158
  *
159
  * @return string|object
160
  */
161
+ public function validate_value( $value, $part = array(), $form = array() ) {
162
  $validated_value = $value;
163
 
164
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
165
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
166
  return $validated_value;
167
  }
168
 
169
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
170
+ $options = wp_list_pluck( $options, 'label' );
171
  $intersection = array_intersect( $options, $validated_value );
172
 
173
  if ( ! count( $intersection ) ) {
174
+ $validated_value = new WP_Error( 'error', __( 'Checkbox values are not valid.', 'happyforms' ) );
175
  return $validated_value;
176
  }
177
 
178
  return $validated_value;
179
  }
180
 
181
+ public function stringify_value( $value, $part, $form ) {
182
+ if ( $this->type === $part['type'] ) {
183
+ $value = implode( ', ', $value );
184
+ }
185
+
186
+ return $value;
187
+ }
188
+
189
+ public function html_part_class( $class, $part, $form ) {
190
+ if ( $this->type === $part['type']
191
+ && isset( $part['display_type'] )
192
+ && 'block' === $part['display_type'] ) {
193
+
194
  $class[] = 'display-type--block';
195
  }
196
 
inc/classes/parts/class-part-date.php CHANGED
@@ -9,6 +9,8 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
9
  $this->description = __( 'For formatted day, month, year and or time fields.', 'happyforms' );
10
 
11
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
 
 
12
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
13
  }
14
 
@@ -61,6 +63,14 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
61
  'default' => date( 'Y' ),
62
  'sanitize' => 'intval'
63
  ),
 
 
 
 
 
 
 
 
64
  'min_hour' => array(
65
  'default' => 1,
66
  'sanitize' => 'sanitize_text_field'
@@ -116,38 +126,17 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
116
  include( happyforms_get_include_folder() . '/templates/parts/frontend-date.php' );
117
  }
118
 
119
- /**
120
- * Get all possible messages definitions.
121
- *
122
- * @since 1.0.0.
123
- *
124
- * @return array Associative array, specifying message type and copy.
125
- */
126
- public function get_message_definitions() {
127
  return array(
128
- 'missing_required_field' => array(
129
- 'type' => 'error',
130
- 'message' => __( 'This field is required.', 'happyforms' ),
131
- ),
132
- 'not_valid_date' => array(
133
- 'type' => 'error',
134
- 'message' => __( 'Not a valid date.', 'happyforms' )
135
- ),
136
- 'invalid_hour' => array(
137
- 'type' => 'error',
138
- 'message' => __( 'Hour input does not match minimum and maximum value allowed.', 'happyforms' )
139
- ),
140
- 'invalid_year' => array(
141
- 'type' => 'error',
142
- 'message' => __( 'Year input does not match maximum value allowed.', 'happyforms' )
143
- )
144
  );
145
  }
146
 
147
- public function get_default_value() {
148
- return array();
149
- }
150
-
151
  /**
152
  * Sanitize submitted value before storing it.
153
  *
@@ -158,41 +147,30 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
158
  * @return string
159
  */
160
  public function sanitize_value( $part_data = array(), $form_data = array() ) {
161
- $original_value = $this->get_default_value();
162
  $part_name = happyforms_get_part_name( $part_data, $form_data );
163
 
164
  if ( isset( $_REQUEST[$part_name] ) ) {
165
- $data = $_REQUEST[$part_name];
166
-
167
- if ( is_array( $data ) ) {
168
- foreach( $data as $key => $date_part ) {
169
- if ( $key === 'period' ) {
170
- $original_value[$key] = sanitize_text_field( $date_part );
171
- } else {
172
- $original_value[$key] = intval( $date_part );
 
 
 
 
 
 
 
 
 
173
  }
174
  }
175
  }
176
-
177
- if ( $part_data['date_type'] === 'date' ) {
178
- $sanitized_value = $original_value['year'] . '-' . sprintf( '%02d', $original_value['month'] ) . '-' . sprintf( '%02d', $original_value['day'] );
179
- }
180
-
181
- if ( $part_data['date_type'] === 'datetime' ) {
182
- $sanitized_value = $original_value['year'] . '-' . sprintf( '%02d', $original_value['month'] ) . '-' . sprintf( '%02d', $original_value['day'] ) . ' ' . sprintf( '%02d', $original_value['hour'] ) . ':' . sprintf( '%02d', $original_value['minute'] );
183
-
184
- if ( 12 == $part_data['time_format'] ) {
185
- $sanitized_value .= ' ' . $original_value['period'];
186
- }
187
- }
188
-
189
- if ( $part_data['date_type'] === 'time' ) {
190
- $sanitized_value = sprintf( '%02d', $original_value['hour'] ) . ':' . sprintf( '%02d', $original_value['minute'] );
191
-
192
- if ( 12 == $part_data['time_format'] ) {
193
- $sanitized_value .= ' ' . $original_value['period'];
194
- }
195
- }
196
  }
197
 
198
  return $sanitized_value;
@@ -203,58 +181,74 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
203
  *
204
  * @since 1.0.0.
205
  *
206
- * @param array $part_data Form part data.
207
  * @param string $value Submitted value.
208
  *
209
  * @return string|object
210
  */
211
- public function validate_value( $part_data, $value ) {
212
- $part_id = $part_data['id'];
213
  $validated_value = $value;
214
 
215
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
216
- $validated_value = new WP_Error( $part_id, 'missing_required_field' );
217
  }
218
 
219
- if ( $part_data['date_type'] === 'date' ) {
 
 
 
 
220
  $date_format = 'Y-m-d';
221
- } elseif ( $part_data['date_type'] === 'datetime' ) {
222
- if ( 12 == $part_data['time_format'] ) {
 
 
223
  $date_format = 'Y-m-d h:i A';
224
  } else {
 
 
225
  $date_format = 'Y-m-d H:i';
226
  }
227
  } else {
228
- if ( 12 == $part_data['time_format'] ) {
 
 
229
  $date_format = 'h:i A';
230
  } else {
 
 
231
  $date_format = 'H:i';
232
  }
233
  }
234
 
235
- if ( !date_create_from_format( $date_format, $validated_value ) ) {
236
- $validated_value = new WP_Error( 'not_valid_date' );
237
  } else {
238
- $date = strtotime( $validated_value );
239
 
240
- if ( 'date' !== $part_data['date_type'] && isset( $part_data['min_hour'] ) && isset( $part_data['max_hour'] ) ) {
241
- $hour = (12 === $part_data['time_format']) ? intval( date( 'g', $date ) ) : intval( date( 'G', $date ) );
242
-
243
- $min_hour = intval( $part_data['min_hour'] );
244
- $max_hour = intval( $part_data['max_hour'] );
245
 
246
  if ( $hour > $max_hour || $hour < $min_hour ) {
247
- $validated_value = new WP_Error( 'invalid_hour' );
 
 
 
248
  }
249
  }
250
 
251
- if ( 'time' !== $part_data['date_type'] && isset( $part_data['min_year'] ) && isset( $part_data['max_year'] ) ) {
252
  $year = intval( date( 'Y', $date ) );
253
- $min_year = intval( $part_data['min_year'] );
254
- $max_year = intval( $part_data['max_year'] );
255
 
256
  if ( $year > $max_year || $year < $min_year ) {
257
- $validated_value = new WP_Error( 'invalid_year' );
 
 
 
258
  }
259
  }
260
  }
@@ -262,13 +256,55 @@ class HappyForms_Part_Date extends HappyForms_Form_Part {
262
  return $validated_value;
263
  }
264
 
265
- public function html_part_class( $class, $part_data, $form_data ) {
266
- if ( isset( $part_data['date_type'] ) ) {
267
- $class[] = 'happyforms-part-date--' . $part_data['date_type'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
269
 
270
- if ( isset( $part_data['time_format'] ) ) {
271
- $class[] = 'happyforms-part-date--' . $part_data['time_format'];
 
 
 
 
 
 
 
 
 
 
272
  }
273
 
274
  return $class;
9
  $this->description = __( 'For formatted day, month, year and or time fields.', 'happyforms' );
10
 
11
  add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
+ add_filter( 'happyforms_part_value', array( $this, 'get_part_value' ), 10, 4 );
13
+ add_filter( 'happyforms_stringify_part_value', array( $this, 'stringify_value' ), 10, 3 );
14
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
15
  }
16
 
63
  'default' => date( 'Y' ),
64
  'sanitize' => 'intval'
65
  ),
66
+ 'years_option' => array(
67
+ 'default' => 'all',
68
+ 'sanitize' => 'sanitize_text_field'
69
+ ),
70
+ 'years_order' => array(
71
+ 'default' => 'desc',
72
+ 'sanitize' => 'sanitize_text_field'
73
+ ),
74
  'min_hour' => array(
75
  'default' => 1,
76
  'sanitize' => 'sanitize_text_field'
126
  include( happyforms_get_include_folder() . '/templates/parts/frontend-date.php' );
127
  }
128
 
129
+ public function get_default_value() {
 
 
 
 
 
 
 
130
  return array(
131
+ 'year' => '',
132
+ 'month' => '',
133
+ 'day' => '',
134
+ 'hour' => '',
135
+ 'minute' => '',
136
+ 'period' => '',
 
 
 
 
 
 
 
 
 
 
137
  );
138
  }
139
 
 
 
 
 
140
  /**
141
  * Sanitize submitted value before storing it.
142
  *
147
  * @return string
148
  */
149
  public function sanitize_value( $part_data = array(), $form_data = array() ) {
150
+ $sanitized_value = $this->get_default_value();
151
  $part_name = happyforms_get_part_name( $part_data, $form_data );
152
 
153
  if ( isset( $_REQUEST[$part_name] ) ) {
154
+ $sanitized_value = wp_parse_args( $_REQUEST[$part_name], $sanitized_value );
155
+
156
+ if ( '' !== implode( '', array_values( $sanitized_value ) ) ) {
157
+ foreach( $sanitized_value as $component => $value ) {
158
+ switch( $component ) {
159
+ case 'year':
160
+ $sanitized_value[$component] = sprintf( '%04d', intval( $value ) );
161
+ break;
162
+ case 'month':
163
+ case 'day':
164
+ case 'hour':
165
+ case 'minute':
166
+ $sanitized_value[$component] = sprintf( '%02d', intval( $value ) );
167
+ break;
168
+ case 'period':
169
+ $sanitized_value[$component] = sanitize_text_field( $value );
170
+ break;
171
  }
172
  }
173
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
 
176
  return $sanitized_value;
181
  *
182
  * @since 1.0.0.
183
  *
184
+ * @param array $part Form part data.
185
  * @param string $value Submitted value.
186
  *
187
  * @return string|object
188
  */
189
+ public function validate_value( $value, $part = array(), $form = array() ) {
 
190
  $validated_value = $value;
191
 
192
+ if ( 1 === $part['required'] && '' === implode( '', array_values( $validated_value ) ) ) {
193
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
194
  }
195
 
196
+ $string_value = '';
197
+
198
+ if ( $part['date_type'] === 'date' ) {
199
+ $validated_value = array_slice( $validated_value, 0, 3, true );
200
+ $string_value = vsprintf( '%s-%s-%s', array_values( $validated_value ) );
201
  $date_format = 'Y-m-d';
202
+ } elseif ( $part['date_type'] === 'datetime' ) {
203
+ if ( 12 == $part['time_format'] ) {
204
+ $validated_value = array_slice( $validated_value, 0, 6, true );
205
+ $string_value = vsprintf( '%s-%s-%s %s:%s %s', array_values( $validated_value ) );
206
  $date_format = 'Y-m-d h:i A';
207
  } else {
208
+ $validated_value = array_slice( $validated_value, 0, 5, true );
209
+ $string_value = vsprintf( '%04d-%s-%s %s:%s', array_values( $validated_value ) );
210
  $date_format = 'Y-m-d H:i';
211
  }
212
  } else {
213
+ if ( 12 == $part['time_format'] ) {
214
+ $validated_value = array_slice( $validated_value, 3, 3, true );
215
+ $string_value = vsprintf( '%s:%s %s', array_values( $validated_value ) );
216
  $date_format = 'h:i A';
217
  } else {
218
+ $validated_value = array_slice( $validated_value, 3, 2, true );
219
+ $string_value = vsprintf( '%s:%s', array_values( $validated_value ) );
220
  $date_format = 'H:i';
221
  }
222
  }
223
 
224
+ if ( ! date_create_from_format( $date_format, $string_value ) ) {
225
+ return new WP_Error( 'error', __( 'Not a valid date.', 'happyforms' ) );
226
  } else {
227
+ $date = strtotime( $string_value );
228
 
229
+ if ( 'date' !== $part['date_type'] && isset( $part['min_hour'] ) && isset( $part['max_hour'] ) ) {
230
+ $hour = (12 === $part['time_format']) ? intval( date( 'g', $date ) ) : intval( date( 'G', $date ) );
231
+ $min_hour = intval( $part['min_hour'] );
232
+ $max_hour = intval( $part['max_hour'] );
 
233
 
234
  if ( $hour > $max_hour || $hour < $min_hour ) {
235
+ return new WP_Error(
236
+ 'error',
237
+ __( 'Hour input does not match minimum and maximum value allowed.', 'happyforms' )
238
+ );
239
  }
240
  }
241
 
242
+ if ( 'time' !== $part['date_type'] && isset( $part['min_year'] ) && isset( $part['max_year'] ) ) {
243
  $year = intval( date( 'Y', $date ) );
244
+ $min_year = intval( $part['min_year'] );
245
+ $max_year = intval( $part['max_year'] );
246
 
247
  if ( $year > $max_year || $year < $min_year ) {
248
+ return new WP_Error(
249
+ 'error',
250
+ __( 'Year input does not match maximum value allowed.', 'happyforms' )
251
+ );
252
  }
253
  }
254
  }
256
  return $validated_value;
257
  }
258
 
259
+ public function get_part_value( $value, $part, $form, $component ) {
260
+ if ( $this->type === $part['type'] ) {
261
+ if ( false !== $component ) {
262
+ $value = isset( $value[$component] ) ? $value[$component] : '';
263
+ }
264
+ }
265
+
266
+ return $value;
267
+ }
268
+
269
+ public function stringify_value( $value, $part, $form ) {
270
+ if ( $this->type === $part['type'] ) {
271
+ extract( $value );
272
+
273
+ $months = happyforms_get_months();
274
+ $month = $months[intval( $month )];
275
+ $day = intval( $day );
276
+
277
+ if ( ! isset( $period ) ) {
278
+ $period = '';
279
+ }
280
+
281
+ switch ( $part['date_type'] ) {
282
+ case 'date':
283
+ $value = "{$month} {$day}, {$year}";
284
+ break;
285
+ case 'time':
286
+ $value = "{$hour}:{$minute}";
287
+ case 'datetime':
288
+ $value = "{$month} {$day}, {$year} at {$hour}:{$minute} {$period}";
289
+ break;
290
+ default:
291
+ $value = '';
292
+ break;
293
+ }
294
  }
295
 
296
+ return $value;
297
+ }
298
+
299
+ public function html_part_class( $class, $part, $form ) {
300
+ if ( $this->type === $part['type'] ) {
301
+ if ( isset( $part['date_type'] ) ) {
302
+ $class[] = 'happyforms-part-date--' . $part['date_type'];
303
+ }
304
+
305
+ if ( isset( $part['time_format'] ) ) {
306
+ $class[] = 'happyforms-part-date--' . $part['time_format'];
307
+ }
308
  }
309
 
310
  return $class;
inc/classes/parts/class-part-email.php CHANGED
@@ -8,7 +8,9 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
8
  $this->label = __( 'Email', 'happyforms' );
9
  $this->description = __( 'For formatted email addresses. The \'@\' symbol is required.', 'happyforms' );
10
 
 
11
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
 
12
  }
13
 
14
  /**
@@ -95,32 +97,8 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
95
  include( happyforms_get_include_folder() . '/templates/parts/frontend-email.php' );
96
  }
97
 
98
- /**
99
- * Get all possible messages definitions.
100
- *
101
- * @since 1.0.0.
102
- *
103
- * @return array Associative array, specifying message type and copy.
104
- */
105
- public function get_message_definitions() {
106
- return array(
107
- 'missing_required_field' => array(
108
- 'type' => 'error',
109
- 'message' => __( 'This field is required.', 'happyforms' ),
110
- ),
111
- 'not_valid_email' => array(
112
- 'type' => 'error',
113
- 'message' => __( 'Not a valid e-mail address.', 'happyforms' )
114
- ),
115
- 'missing_required_confirmation_field' => array(
116
- 'type' => 'error',
117
- 'message' => __( 'Confirmation field is required.', 'happyforms' )
118
- ),
119
- 'emails_not_matching' => array(
120
- 'type' => 'error',
121
- 'message' => __( 'Email and confirmation email are not matching.', 'happyforms' )
122
- ),
123
- );
124
  }
125
 
126
  /**
@@ -137,14 +115,11 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
137
  $part_name = happyforms_get_part_name( $part_data, $form_data );
138
 
139
  if ( isset( $_REQUEST[$part_name] ) ) {
140
- $sanitized_value = sanitize_text_field( $_REQUEST[$part_name] );
141
  }
142
 
143
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
144
- $sanitized_value = array(
145
- $sanitized_value,
146
- sanitize_text_field( $_REQUEST[$part_name . '_confirmation'] )
147
- );
148
  }
149
 
150
  return $sanitized_value;
@@ -155,47 +130,65 @@ class HappyForms_Part_Email extends HappyForms_Form_Part {
155
  *
156
  * @since 1.0.0.
157
  *
158
- * @param array $part_data Form part data.
159
  * @param string $value Submitted value.
160
  *
161
  * @return string|object
162
  */
163
- public function validate_value( $part_data, $value ) {
164
- $has_confirmation_value = is_array( $value );
165
- $validated_value = $has_confirmation_value ? $value[0] : $value;
166
 
167
- if ( $part_data['required'] && '' === $validated_value ) {
168
- $validated_value = new WP_Error( 'missing_required_field' );
169
- return $validated_value;
170
  }
171
 
172
- if ( ! is_email( $validated_value ) ) {
173
- $validated_value = new WP_error( 'not_valid_email' );
174
- return $validated_value;
175
  }
176
 
177
- if ( $has_confirmation_value && $value[0] !== $value[1] ) {
178
- $validated_value = new WP_Error( 'emails_not_matching' );
179
- return $validated_value;
180
  }
181
 
182
- $validated_value = sanitize_email( $validated_value );
 
 
183
 
184
- return $validated_value;
185
  }
186
 
187
- public function html_part_data_attributes( $attributes, $part, $form ) {
188
- if ( $this->type !== $part['type'] ) {
189
- return $attributes;
 
 
190
  }
191
 
192
- if ( $part['confirmation_field'] ) {
193
- $attributes['happyforms-require-confirmation'] = '';
 
 
 
 
 
 
 
194
  }
195
 
196
  return $attributes;
197
  }
198
 
 
 
 
 
 
 
 
 
 
 
 
199
  /**
200
  * Enqueue scripts in customizer area.
201
  *
8
  $this->label = __( 'Email', 'happyforms' );
9
  $this->description = __( 'For formatted email addresses. The \'@\' symbol is required.', 'happyforms' );
10
 
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
13
+ add_filter( 'happyforms_part_value', array( $this, 'get_part_value' ), 10, 4 );
14
  }
15
 
16
  /**
97
  include( happyforms_get_include_folder() . '/templates/parts/frontend-email.php' );
98
  }
99
 
100
+ public function get_default_value() {
101
+ return array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  }
103
 
104
  /**
115
  $part_name = happyforms_get_part_name( $part_data, $form_data );
116
 
117
  if ( isset( $_REQUEST[$part_name] ) ) {
118
+ $sanitized_value[0] = sanitize_text_field( $_REQUEST[$part_name] );
119
  }
120
 
121
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
122
+ $sanitized_value[1] = sanitize_text_field( $_REQUEST[$part_name . '_confirmation'] );
 
 
 
123
  }
124
 
125
  return $sanitized_value;
130
  *
131
  * @since 1.0.0.
132
  *
133
+ * @param array $part Form part data.
134
  * @param string $value Submitted value.
135
  *
136
  * @return string|object
137
  */
138
+ public function validate_value( $value, $part = array(), $form = array() ) {
139
+ $validated_values = $value;
 
140
 
141
+ if ( $part['required'] && empty( $validated_values ) ) {
142
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
143
  }
144
 
145
+ if ( $part['required'] && empty( $validated_values[0] ) ) {
146
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
147
  }
148
 
149
+ if ( ! is_email( $validated_values[0] ) ) {
150
+ return new WP_error( 'error', __( 'Not a valid e-mail address.', 'happyforms' ) );
 
151
  }
152
 
153
+ if ( isset( $validated_values[1] ) && $validated_values[0] !== $validated_values[1] ) {
154
+ return new WP_Error( 'error', __( 'Email and confirmation email are not matching.', 'happyforms' ) );
155
+ }
156
 
157
+ return $validated_values[0];
158
  }
159
 
160
+ public function get_part_value( $value, $part, $form, $component ) {
161
+ if ( $this->type === $part['type'] ) {
162
+ if ( false !== $component ) {
163
+ $value = isset( $value[$component] ) ? $value[$component] : '';
164
+ }
165
  }
166
 
167
+ return $value;
168
+ }
169
+
170
+
171
+ public function html_part_data_attributes( $attributes, $part, $form ) {
172
+ if ( $this->type === $part['type'] ) {
173
+ if ( $part['confirmation_field'] ) {
174
+ $attributes['happyforms-require-confirmation'] = '';
175
+ }
176
  }
177
 
178
  return $attributes;
179
  }
180
 
181
+ public function html_part_class( $class, $part, $form ) {
182
+ if ( $this->type === $part['type'] ) {
183
+ if ( happyforms_get_part_value( $part, $form, 0 )
184
+ || happyforms_get_part_value( $part, $form, 1 ) ) {
185
+ $class[] = 'happyforms-part--filled';
186
+ }
187
+ }
188
+
189
+ return $class;
190
+ }
191
+
192
  /**
193
  * Enqueue scripts in customizer area.
194
  *
inc/classes/parts/class-part-legal.php CHANGED
@@ -74,26 +74,6 @@ class HappyForms_Part_Legal extends HappyForms_Form_Part {
74
  include( happyforms_get_include_folder() . '/templates/parts/frontend-legal.php' );
75
  }
76
 
77
- /**
78
- * Get all possible messages definitions.
79
- *
80
- * @since 1.0.0.
81
- *
82
- * @return array Associative array, specifying message type and copy.
83
- */
84
- public function get_message_definitions() {
85
- return array(
86
- 'missing_required_field' => array(
87
- 'type' => 'error',
88
- 'message' => __( 'This field is required.', 'happyforms' ),
89
- ),
90
- 'not_valid_value' => array(
91
- 'type' => 'error',
92
- 'message' => __( 'Please accept terms before proceeding.', 'happyforms' ),
93
- ),
94
- );
95
- }
96
-
97
  /**
98
  * Sanitize submitted value before storing it.
99
  *
@@ -119,21 +99,21 @@ class HappyForms_Part_Legal extends HappyForms_Form_Part {
119
  *
120
  * @since 1.0.0.
121
  *
122
- * @param array $part_data Form part data.
123
  * @param string $value Submitted value.
124
  *
125
  * @return string|object
126
  */
127
- public function validate_value( $part_data, $value ) {
128
  $validated_value = $value;
129
 
130
  if ( empty( $validated_value ) ) {
131
- $validated_value = new WP_Error( 'missing_required_field' );
132
  return $validated_value;
133
  }
134
 
135
  if ( $validated_value !== 'yes' ) {
136
- $validated_value = new WP_Error( 'not_valid_value' );
137
  return $validated_value;
138
  }
139
 
74
  include( happyforms_get_include_folder() . '/templates/parts/frontend-legal.php' );
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  /**
78
  * Sanitize submitted value before storing it.
79
  *
99
  *
100
  * @since 1.0.0.
101
  *
102
+ * @param array $part Form part data.
103
  * @param string $value Submitted value.
104
  *
105
  * @return string|object
106
  */
107
+ public function validate_value( $value, $part = array(), $form = array() ) {
108
  $validated_value = $value;
109
 
110
  if ( empty( $validated_value ) ) {
111
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
112
  return $validated_value;
113
  }
114
 
115
  if ( $validated_value !== 'yes' ) {
116
+ $validated_value = new WP_Error( 'error', __( 'Please accept terms before proceeding.', 'happyforms' ) );
117
  return $validated_value;
118
  }
119
 
inc/classes/parts/class-part-multi-line-text.php CHANGED
@@ -7,6 +7,8 @@ class HappyForms_Part_MultiLineText extends HappyForms_Form_Part {
7
  public function __construct() {
8
  $this->label = __( 'Long Text', 'happyforms' );
9
  $this->description = __( 'For paragraph text fields.', 'happyforms' );
 
 
10
  }
11
 
12
  /**
@@ -85,22 +87,6 @@ class HappyForms_Part_MultiLineText extends HappyForms_Form_Part {
85
  include( happyforms_get_include_folder() . '/templates/parts/frontend-multi-line-text.php' );
86
  }
87
 
88
- /**
89
- * Get all possible messages definitions.
90
- *
91
- * @since 1.0.0.
92
- *
93
- * @return array Associative array, specifying message type and copy.
94
- */
95
- public function get_message_definitions() {
96
- return array(
97
- 'missing_required_field' => array(
98
- 'type' => 'error',
99
- 'message' => __( 'This field is required.', 'happyforms' ),
100
- ),
101
- );
102
- }
103
-
104
  /**
105
  * Enqueue scripts in customizer area.
106
  *
@@ -143,19 +129,29 @@ class HappyForms_Part_MultiLineText extends HappyForms_Form_Part {
143
  *
144
  * @since 1.0.0.
145
  *
146
- * @param array $part_data Form part data.
147
  * @param string $value Submitted value.
148
  *
149
  * @return string|object
150
  */
151
- public function validate_value( $part_data, $value ) {
152
  $validated_value = $value;
153
 
154
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
155
- $validated_value = new WP_Error( 'missing_required_field' );
156
  }
157
 
158
  return $validated_value;
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
161
  }
7
  public function __construct() {
8
  $this->label = __( 'Long Text', 'happyforms' );
9
  $this->description = __( 'For paragraph text fields.', 'happyforms' );
10
+
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  }
13
 
14
  /**
87
  include( happyforms_get_include_folder() . '/templates/parts/frontend-multi-line-text.php' );
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  /**
91
  * Enqueue scripts in customizer area.
92
  *
129
  *
130
  * @since 1.0.0.
131
  *
132
+ * @param array $part Form part data.
133
  * @param string $value Submitted value.
134
  *
135
  * @return string|object
136
  */
137
+ public function validate_value( $value, $part = array(), $form = array() ) {
138
  $validated_value = $value;
139
 
140
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
141
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
142
  }
143
 
144
  return $validated_value;
145
  }
146
 
147
+ public function html_part_class( $class, $part, $form ) {
148
+ if ( $this->type === $part['type'] ) {
149
+ if ( happyforms_get_part_value( $part, $form ) ) {
150
+ $class[] = 'happyforms-part--filled';
151
+ }
152
+ }
153
+
154
+ return $class;
155
+ }
156
+
157
  }
inc/classes/parts/class-part-number.php CHANGED
@@ -8,8 +8,10 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
8
  $this->label = __( 'Number', 'happyforms' );
9
  $this->description = __( 'For numeric fields.', 'happyforms' );
10
 
 
11
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
12
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
 
13
  }
14
 
15
  /**
@@ -120,36 +122,8 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
120
  include( happyforms_get_include_folder() . '/templates/parts/frontend-number.php' );
121
  }
122
 
123
- /**
124
- * Get all possible messages definitions.
125
- *
126
- * @since 1.0.0.
127
- *
128
- * @return array Associative array, specifying message type and copy.
129
- */
130
- public function get_message_definitions() {
131
- return array(
132
- 'missing_required_field' => array(
133
- 'type' => 'error',
134
- 'message' => __( 'This field is required.', 'happyforms' ),
135
- ),
136
- 'not_a_number' => array(
137
- 'type' => 'error',
138
- 'message' => __( 'This field requires a numeric value.', 'happyforms' ),
139
- ),
140
- 'missing_required_confirmation_field' => array(
141
- 'type' => 'error',
142
- 'message' => __( 'Confirmation field is required.', 'happyforms' )
143
- ),
144
- 'not_a_number_confirmation' => array(
145
- 'type' => 'error',
146
- 'message' => __( 'Confirmation number is not a valid number.', 'happyforms' )
147
- ),
148
- 'numbers_not_matching' => array(
149
- 'type' => 'error',
150
- 'message' => __( 'Number and confirmation number are not matching.', 'happyforms' )
151
- ),
152
- );
153
  }
154
 
155
  /**
@@ -166,49 +140,60 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
166
  $part_name = happyforms_get_part_name( $part_data, $form_data );
167
 
168
  if ( isset( $_REQUEST[$part_name] ) ) {
169
- $sanitized_value = sanitize_text_field( $_REQUEST[$part_name] );
170
  }
171
 
172
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
173
- $sanitized_value = array(
174
- $sanitized_value,
175
- sanitize_text_field( $_REQUEST[$part_name . '_confirmation'] )
176
- );
 
 
 
177
  }
178
 
 
179
  return $sanitized_value;
180
  }
181
 
182
  /**
183
- * Validate value before submitting it. If it fails validation, return WP_Error object, showing respective error message.
 
184
  *
185
  * @since 1.0.0.
186
  *
187
- * @param array $part_data Form part data.
188
  * @param string $value Submitted value.
189
  *
190
  * @return string|object
191
  */
192
- public function validate_value( $part_data, $value ) {
193
- $has_confirmation_value = is_array( $value );
194
- $validated_value = $has_confirmation_value ? $value[0] : $value;
195
 
196
- if ( $part_data['required'] && '' === $validated_value ) {
197
- $validated_value = new WP_Error( 'missing_required_field' );
198
- return $validated_value;
199
  }
200
 
201
- if ( ! $part_data['masked'] && ! is_numeric( $validated_value ) ) {
202
- $validated_value = new WP_Error( 'not_a_number' );
203
- return $validated_value;
204
  }
205
 
206
- if ( $has_confirmation_value && $value[0] !== $value[1] ) {
207
- $validated_value = new WP_Error( 'numbers_not_matching' );
208
- return $validated_value;
209
  }
210
 
211
- return $validated_value;
 
 
 
 
 
 
 
 
 
 
212
  }
213
 
214
  /**
@@ -228,6 +213,17 @@ class HappyForms_Part_Number extends HappyForms_Form_Part {
228
  );
229
  }
230
 
 
 
 
 
 
 
 
 
 
 
 
231
  public function html_part_data_attributes( $attributes, $part, $form ) {
232
  if ( $this->type !== $part['type'] ) {
233
  return $attributes;
8
  $this->label = __( 'Number', 'happyforms' );
9
  $this->description = __( 'For numeric fields.', 'happyforms' );
10
 
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
13
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
14
+ add_filter( 'happyforms_part_value', array( $this, 'get_part_value' ), 10, 4 );
15
  }
16
 
17
  /**
122
  include( happyforms_get_include_folder() . '/templates/parts/frontend-number.php' );
123
  }
124
 
125
+ public function get_default_value() {
126
+ return array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  }
128
 
129
  /**
140
  $part_name = happyforms_get_part_name( $part_data, $form_data );
141
 
142
  if ( isset( $_REQUEST[$part_name] ) ) {
143
+ $sanitized_value[0] = $_REQUEST[$part_name];
144
  }
145
 
146
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
147
+ $sanitized_value[1] = $_REQUEST[$part_name . '_confirmation'];
148
+ }
149
+
150
+ if ( ! $part_data['masked'] ) {
151
+ $sanitized_value = array_map( 'intval' , $sanitized_value );
152
+ } else {
153
+ $sanitized_value = array_map( 'sanitize_text_field' , $sanitized_value );
154
  }
155
 
156
+
157
  return $sanitized_value;
158
  }
159
 
160
  /**
161
+ * Validate value before submitting it. If it fails validation,
162
+ * return WP_Error object, showing respective error message.
163
  *
164
  * @since 1.0.0.
165
  *
166
+ * @param array $part Form part data.
167
  * @param string $value Submitted value.
168
  *
169
  * @return string|object
170
  */
171
+ public function validate_value( $value, $part = array(), $form = array() ) {
172
+ $validated_values = $value;
 
173
 
174
+ if ( $part['required'] && empty( $validated_values ) ) {
175
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
176
  }
177
 
178
+ if ( $part['required'] && empty( $validated_values[0] ) ) {
179
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
180
  }
181
 
182
+ if ( isset( $validated_values[1] ) && $validated_values[0] !== $validated_values[1] ) {
183
+ return new WP_Error( 'error', __( 'Number and confirmation number are not matching.', 'happyforms' ) );
 
184
  }
185
 
186
+ return $validated_values[0];
187
+ }
188
+
189
+ public function get_part_value( $value, $part, $form, $component ) {
190
+ if ( $this->type === $part['type'] ) {
191
+ if ( false !== $component ) {
192
+ $value = isset( $value[$component] ) ? $value[$component] : '';
193
+ }
194
+ }
195
+
196
+ return $value;
197
  }
198
 
199
  /**
213
  );
214
  }
215
 
216
+ public function html_part_class( $class, $part, $form ) {
217
+ if ( $this->type === $part['type'] ) {
218
+ if ( happyforms_get_part_value( $part, $form, 0 )
219
+ || happyforms_get_part_value( $part, $form, 1 ) ) {
220
+ $class[] = 'happyforms-part--filled';
221
+ }
222
+ }
223
+
224
+ return $class;
225
+ }
226
+
227
  public function html_part_data_attributes( $attributes, $part, $form ) {
228
  if ( $this->type !== $part['type'] ) {
229
  return $attributes;
inc/classes/parts/class-part-phone.php CHANGED
@@ -8,8 +8,10 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
8
  $this->label = __( 'Phone', 'happyforms' );
9
  $this->description = __( 'For phone numbers. Includes country specific formatting.', 'happyforms' );
10
 
 
11
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
12
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
 
13
  }
14
 
15
  /**
@@ -66,7 +68,7 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
66
  'sanitize' => 'intval'
67
  ),
68
  'confirmation_field_label' => array(
69
- 'default' => __( 'Confirm Number', 'happyforms' ),
70
  'sanitize' => 'sanitize_text_field'
71
  ),
72
  'required' => array(
@@ -104,30 +106,6 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
104
  include( happyforms_get_include_folder() . '/templates/parts/frontend-phone.php' );
105
  }
106
 
107
- /**
108
- * Get all possible messages definitions.
109
- *
110
- * @since 1.0.0.
111
- *
112
- * @return array Associative array, specifying message type and copy.
113
- */
114
- public function get_message_definitions() {
115
- return array(
116
- 'missing_required_field' => array(
117
- 'type' => 'error',
118
- 'message' => __( 'This field is required.', 'happyforms' ),
119
- ),
120
- 'missing_required_confirmation_field' => array(
121
- 'type' => 'error',
122
- 'message' => __( 'Confirmation field is required.', 'happyforms' )
123
- ),
124
- 'numbers_not_matching' => array(
125
- 'type' => 'error',
126
- 'message' => __( 'Number and confirmation number are not matching.', 'happyforms' )
127
- ),
128
- );
129
- }
130
-
131
  /**
132
  * Get associative array of country code => country name and phone code (prefix) for masking purposes.
133
  *
@@ -137,239 +115,244 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
137
  */
138
  public function get_phone_countries_array() {
139
  $phone_countries = array(
140
- 'AD'=>array('name'=>'ANDORRA','code'=>'376'),
141
- 'AE'=>array('name'=>'UNITED ARAB EMIRATES','code'=>'971'),
142
- 'AF'=>array('name'=>'AFGHANISTAN','code'=>'93'),
143
- 'AG'=>array('name'=>'ANTIGUA AND BARBUDA','code'=>'1268'),
144
- 'AI'=>array('name'=>'ANGUILLA','code'=>'1264'),
145
- 'AL'=>array('name'=>'ALBANIA','code'=>'355'),
146
- 'AM'=>array('name'=>'ARMENIA','code'=>'374'),
147
- 'AN'=>array('name'=>'NETHERLANDS ANTILLES','code'=>'599'),
148
- 'AO'=>array('name'=>'ANGOLA','code'=>'244'),
149
- 'AQ'=>array('name'=>'ANTARCTICA','code'=>'672'),
150
- 'AR'=>array('name'=>'ARGENTINA','code'=>'54'),
151
- 'AS'=>array('name'=>'AMERICAN SAMOA','code'=>'1684'),
152
- 'AT'=>array('name'=>'AUSTRIA','code'=>'43'),
153
- 'AU'=>array('name'=>'AUSTRALIA','code'=>'61'),
154
- 'AW'=>array('name'=>'ARUBA','code'=>'297'),
155
- 'AZ'=>array('name'=>'AZERBAIJAN','code'=>'994'),
156
- 'BA'=>array('name'=>'BOSNIA AND HERZEGOVINA','code'=>'387'),
157
- 'BB'=>array('name'=>'BARBADOS','code'=>'1246'),
158
- 'BD'=>array('name'=>'BANGLADESH','code'=>'880'),
159
- 'BE'=>array('name'=>'BELGIUM','code'=>'32'),
160
- 'BF'=>array('name'=>'BURKINA FASO','code'=>'226'),
161
- 'BG'=>array('name'=>'BULGARIA','code'=>'359'),
162
- 'BH'=>array('name'=>'BAHRAIN','code'=>'973'),
163
- 'BI'=>array('name'=>'BURUNDI','code'=>'257'),
164
- 'BJ'=>array('name'=>'BENIN','code'=>'229'),
165
- 'BL'=>array('name'=>'SAINT BARTHELEMY','code'=>'590'),
166
- 'BM'=>array('name'=>'BERMUDA','code'=>'1441'),
167
- 'BN'=>array('name'=>'BRUNEI DARUSSALAM','code'=>'673'),
168
- 'BO'=>array('name'=>'BOLIVIA','code'=>'591'),
169
- 'BR'=>array('name'=>'BRAZIL','code'=>'55'),
170
- 'BS'=>array('name'=>'BAHAMAS','code'=>'1242'),
171
- 'BT'=>array('name'=>'BHUTAN','code'=>'975'),
172
- 'BW'=>array('name'=>'BOTSWANA','code'=>'267'),
173
- 'BY'=>array('name'=>'BELARUS','code'=>'375'),
174
- 'BZ'=>array('name'=>'BELIZE','code'=>'501'),
175
- 'CA'=>array('name'=>'CANADA','code'=>'1'),
176
- 'CD'=>array('name'=>'CONGO, THE DEMOCRATIC REPUBLIC OF THE','code'=>'243'),
177
- 'CF'=>array('name'=>'CENTRAL AFRICAN REPUBLIC','code'=>'236'),
178
- 'CG'=>array('name'=>'CONGO','code'=>'242'),
179
- 'CH'=>array('name'=>'SWITZERLAND','code'=>'41'),
180
- 'CI'=>array('name'=>'COTE D IVOIRE','code'=>'225'),
181
- 'CK'=>array('name'=>'COOK ISLANDS','code'=>'682'),
182
- 'CL'=>array('name'=>'CHILE','code'=>'56'),
183
- 'CM'=>array('name'=>'CAMEROON','code'=>'237'),
184
- 'CN'=>array('name'=>'CHINA','code'=>'86'),
185
- 'CO'=>array('name'=>'COLOMBIA','code'=>'57'),
186
- 'CR'=>array('name'=>'COSTA RICA','code'=>'506'),
187
- 'CU'=>array('name'=>'CUBA','code'=>'53'),
188
- 'CV'=>array('name'=>'CAPE VERDE','code'=>'238'),
189
- 'CY'=>array('name'=>'CYPRUS','code'=>'357'),
190
- 'CZ'=>array('name'=>'CZECH REPUBLIC','code'=>'420'),
191
- 'DE'=>array('name'=>'GERMANY','code'=>'49'),
192
- 'DJ'=>array('name'=>'DJIBOUTI','code'=>'253'),
193
- 'DK'=>array('name'=>'DENMARK','code'=>'45'),
194
- 'DM'=>array('name'=>'DOMINICA','code'=>'1767'),
195
- 'DO'=>array('name'=>'DOMINICAN REPUBLIC','code'=>'1809'),
196
- 'DZ'=>array('name'=>'ALGERIA','code'=>'213'),
197
- 'EC'=>array('name'=>'ECUADOR','code'=>'593'),
198
- 'EE'=>array('name'=>'ESTONIA','code'=>'372'),
199
- 'EG'=>array('name'=>'EGYPT','code'=>'20'),
200
- 'ER'=>array('name'=>'ERITREA','code'=>'291'),
201
- 'ES'=>array('name'=>'SPAIN','code'=>'34'),
202
- 'ET'=>array('name'=>'ETHIOPIA','code'=>'251'),
203
- 'FI'=>array('name'=>'FINLAND','code'=>'358'),
204
- 'FJ'=>array('name'=>'FIJI','code'=>'679'),
205
- 'FK'=>array('name'=>'FALKLAND ISLANDS (MALVINAS)','code'=>'500'),
206
- 'FM'=>array('name'=>'MICRONESIA, FEDERATED STATES OF','code'=>'691'),
207
- 'FO'=>array('name'=>'FAROE ISLANDS','code'=>'298'),
208
- 'FR'=>array('name'=>'FRANCE','code'=>'33'),
209
- 'GA'=>array('name'=>'GABON','code'=>'241'),
210
- 'GB'=>array('name'=>'UNITED KINGDOM','code'=>'44'),
211
- 'GD'=>array('name'=>'GRENADA','code'=>'1473'),
212
- 'GE'=>array('name'=>'GEORGIA','code'=>'995'),
213
- 'GH'=>array('name'=>'GHANA','code'=>'233'),
214
- 'GI'=>array('name'=>'GIBRALTAR','code'=>'350'),
215
- 'GL'=>array('name'=>'GREENLAND','code'=>'299'),
216
- 'GM'=>array('name'=>'GAMBIA','code'=>'220'),
217
- 'GN'=>array('name'=>'GUINEA','code'=>'224'),
218
- 'GQ'=>array('name'=>'EQUATORIAL GUINEA','code'=>'240'),
219
- 'GR'=>array('name'=>'GREECE','code'=>'30'),
220
- 'GT'=>array('name'=>'GUATEMALA','code'=>'502'),
221
- 'GU'=>array('name'=>'GUAM','code'=>'1671'),
222
- 'GW'=>array('name'=>'GUINEA-BISSAU','code'=>'245'),
223
- 'GY'=>array('name'=>'GUYANA','code'=>'592'),
224
- 'HK'=>array('name'=>'HONG KONG','code'=>'852'),
225
- 'HN'=>array('name'=>'HONDURAS','code'=>'504'),
226
- 'HR'=>array('name'=>'CROATIA','code'=>'385'),
227
- 'HT'=>array('name'=>'HAITI','code'=>'509'),
228
- 'HU'=>array('name'=>'HUNGARY','code'=>'36'),
229
- 'ID'=>array('name'=>'INDONESIA','code'=>'62'),
230
- 'IE'=>array('name'=>'IRELAND','code'=>'353'),
231
- 'IL'=>array('name'=>'ISRAEL','code'=>'972'),
232
- 'IM'=>array('name'=>'ISLE OF MAN','code'=>'44'),
233
- 'IN'=>array('name'=>'INDIA','code'=>'91'),
234
- 'IQ'=>array('name'=>'IRAQ','code'=>'964'),
235
- 'IR'=>array('name'=>'IRAN, ISLAMIC REPUBLIC OF','code'=>'98'),
236
- 'IS'=>array('name'=>'ICELAND','code'=>'354'),
237
- 'IT'=>array('name'=>'ITALY','code'=>'39'),
238
- 'JM'=>array('name'=>'JAMAICA','code'=>'1876'),
239
- 'JO'=>array('name'=>'JORDAN','code'=>'962'),
240
- 'JP'=>array('name'=>'JAPAN','code'=>'81'),
241
- 'KE'=>array('name'=>'KENYA','code'=>'254'),
242
- 'KG'=>array('name'=>'KYRGYZSTAN','code'=>'996'),
243
- 'KH'=>array('name'=>'CAMBODIA','code'=>'855'),
244
- 'KI'=>array('name'=>'KIRIBATI','code'=>'686'),
245
- 'KM'=>array('name'=>'COMOROS','code'=>'269'),
246
- 'KN'=>array('name'=>'SAINT KITTS AND NEVIS','code'=>'1869'),
247
- 'KP'=>array('name'=>'KOREA DEMOCRATIC PEOPLES REPUBLIC OF','code'=>'850'),
248
- 'KR'=>array('name'=>'KOREA REPUBLIC OF','code'=>'82'),
249
- 'KW'=>array('name'=>'KUWAIT','code'=>'965'),
250
- 'KY'=>array('name'=>'CAYMAN ISLANDS','code'=>'1345'),
251
- 'KZ'=>array('name'=>'KAZAKSTAN','code'=>'7'),
252
- 'LA'=>array('name'=>'LAO PEOPLES DEMOCRATIC REPUBLIC','code'=>'856'),
253
- 'LB'=>array('name'=>'LEBANON','code'=>'961'),
254
- 'LC'=>array('name'=>'SAINT LUCIA','code'=>'1758'),
255
- 'LI'=>array('name'=>'LIECHTENSTEIN','code'=>'423'),
256
- 'LK'=>array('name'=>'SRI LANKA','code'=>'94'),
257
- 'LR'=>array('name'=>'LIBERIA','code'=>'231'),
258
- 'LS'=>array('name'=>'LESOTHO','code'=>'266'),
259
- 'LT'=>array('name'=>'LITHUANIA','code'=>'370'),
260
- 'LU'=>array('name'=>'LUXEMBOURG','code'=>'352'),
261
- 'LV'=>array('name'=>'LATVIA','code'=>'371'),
262
- 'LY'=>array('name'=>'LIBYAN ARAB JAMAHIRIYA','code'=>'218'),
263
- 'MA'=>array('name'=>'MOROCCO','code'=>'212'),
264
- 'MC'=>array('name'=>'MONACO','code'=>'377'),
265
- 'MD'=>array('name'=>'MOLDOVA, REPUBLIC OF','code'=>'373'),
266
- 'ME'=>array('name'=>'MONTENEGRO','code'=>'382'),
267
- 'MF'=>array('name'=>'SAINT MARTIN','code'=>'1599'),
268
- 'MG'=>array('name'=>'MADAGASCAR','code'=>'261'),
269
- 'MH'=>array('name'=>'MARSHALL ISLANDS','code'=>'692'),
270
- 'MK'=>array('name'=>'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF','code'=>'389'),
271
- 'ML'=>array('name'=>'MALI','code'=>'223'),
272
- 'MM'=>array('name'=>'MYANMAR','code'=>'95'),
273
- 'MN'=>array('name'=>'MONGOLIA','code'=>'976'),
274
- 'MO'=>array('name'=>'MACAU','code'=>'853'),
275
- 'MP'=>array('name'=>'NORTHERN MARIANA ISLANDS','code'=>'1670'),
276
- 'MR'=>array('name'=>'MAURITANIA','code'=>'222'),
277
- 'MS'=>array('name'=>'MONTSERRAT','code'=>'1664'),
278
- 'MT'=>array('name'=>'MALTA','code'=>'356'),
279
- 'MU'=>array('name'=>'MAURITIUS','code'=>'230'),
280
- 'MV'=>array('name'=>'MALDIVES','code'=>'960'),
281
- 'MW'=>array('name'=>'MALAWI','code'=>'265'),
282
- 'MX'=>array('name'=>'MEXICO','code'=>'52'),
283
- 'MY'=>array('name'=>'MALAYSIA','code'=>'60'),
284
- 'MZ'=>array('name'=>'MOZAMBIQUE','code'=>'258'),
285
- 'NA'=>array('name'=>'NAMIBIA','code'=>'264'),
286
- 'NC'=>array('name'=>'NEW CALEDONIA','code'=>'687'),
287
- 'NE'=>array('name'=>'NIGER','code'=>'227'),
288
- 'NG'=>array('name'=>'NIGERIA','code'=>'234'),
289
- 'NI'=>array('name'=>'NICARAGUA','code'=>'505'),
290
- 'NL'=>array('name'=>'NETHERLANDS','code'=>'31'),
291
- 'NO'=>array('name'=>'NORWAY','code'=>'47'),
292
- 'NP'=>array('name'=>'NEPAL','code'=>'977'),
293
- 'NR'=>array('name'=>'NAURU','code'=>'674'),
294
- 'NU'=>array('name'=>'NIUE','code'=>'683'),
295
- 'NZ'=>array('name'=>'NEW ZEALAND','code'=>'64'),
296
- 'OM'=>array('name'=>'OMAN','code'=>'968'),
297
- 'PA'=>array('name'=>'PANAMA','code'=>'507'),
298
- 'PE'=>array('name'=>'PERU','code'=>'51'),
299
- 'PF'=>array('name'=>'FRENCH POLYNESIA','code'=>'689'),
300
- 'PG'=>array('name'=>'PAPUA NEW GUINEA','code'=>'675'),
301
- 'PH'=>array('name'=>'PHILIPPINES','code'=>'63'),
302
- 'PK'=>array('name'=>'PAKISTAN','code'=>'92'),
303
- 'PL'=>array('name'=>'POLAND','code'=>'48'),
304
- 'PM'=>array('name'=>'SAINT PIERRE AND MIQUELON','code'=>'508'),
305
- 'PN'=>array('name'=>'PITCAIRN','code'=>'870'),
306
- 'PR'=>array('name'=>'PUERTO RICO','code'=>'1'),
307
- 'PT'=>array('name'=>'PORTUGAL','code'=>'351'),
308
- 'PW'=>array('name'=>'PALAU','code'=>'680'),
309
- 'PY'=>array('name'=>'PARAGUAY','code'=>'595'),
310
- 'QA'=>array('name'=>'QATAR','code'=>'974'),
311
- 'RO'=>array('name'=>'ROMANIA','code'=>'40'),
312
- 'RS'=>array('name'=>'SERBIA','code'=>'381'),
313
- 'RU'=>array('name'=>'RUSSIAN FEDERATION','code'=>'7'),
314
- 'RW'=>array('name'=>'RWANDA','code'=>'250'),
315
- 'SA'=>array('name'=>'SAUDI ARABIA','code'=>'966'),
316
- 'SB'=>array('name'=>'SOLOMON ISLANDS','code'=>'677'),
317
- 'SC'=>array('name'=>'SEYCHELLES','code'=>'248'),
318
- 'SD'=>array('name'=>'SUDAN','code'=>'249'),
319
- 'SE'=>array('name'=>'SWEDEN','code'=>'46'),
320
- 'SG'=>array('name'=>'SINGAPORE','code'=>'65'),
321
- 'SH'=>array('name'=>'SAINT HELENA','code'=>'290'),
322
- 'SI'=>array('name'=>'SLOVENIA','code'=>'386'),
323
- 'SK'=>array('name'=>'SLOVAKIA','code'=>'421'),
324
- 'SL'=>array('name'=>'SIERRA LEONE','code'=>'232'),
325
- 'SM'=>array('name'=>'SAN MARINO','code'=>'378'),
326
- 'SN'=>array('name'=>'SENEGAL','code'=>'221'),
327
- 'SO'=>array('name'=>'SOMALIA','code'=>'252'),
328
- 'SR'=>array('name'=>'SURINAME','code'=>'597'),
329
- 'ST'=>array('name'=>'SAO TOME AND PRINCIPE','code'=>'239'),
330
- 'SV'=>array('name'=>'EL SALVADOR','code'=>'503'),
331
- 'SY'=>array('name'=>'SYRIAN ARAB REPUBLIC','code'=>'963'),
332
- 'SZ'=>array('name'=>'SWAZILAND','code'=>'268'),
333
- 'TC'=>array('name'=>'TURKS AND CAICOS ISLANDS','code'=>'1649'),
334
- 'TD'=>array('name'=>'CHAD','code'=>'235'),
335
- 'TG'=>array('name'=>'TOGO','code'=>'228'),
336
- 'TH'=>array('name'=>'THAILAND','code'=>'66'),
337
- 'TJ'=>array('name'=>'TAJIKISTAN','code'=>'992'),
338
- 'TK'=>array('name'=>'TOKELAU','code'=>'690'),
339
- 'TL'=>array('name'=>'TIMOR-LESTE','code'=>'670'),
340
- 'TM'=>array('name'=>'TURKMENISTAN','code'=>'993'),
341
- 'TN'=>array('name'=>'TUNISIA','code'=>'216'),
342
- 'TO'=>array('name'=>'TONGA','code'=>'676'),
343
- 'TR'=>array('name'=>'TURKEY','code'=>'90'),
344
- 'TT'=>array('name'=>'TRINIDAD AND TOBAGO','code'=>'1868'),
345
- 'TV'=>array('name'=>'TUVALU','code'=>'688'),
346
- 'TW'=>array('name'=>'TAIWAN, PROVINCE OF CHINA','code'=>'886'),
347
- 'TZ'=>array('name'=>'TANZANIA, UNITED REPUBLIC OF','code'=>'255'),
348
- 'UA'=>array('name'=>'UKRAINE','code'=>'380'),
349
- 'UG'=>array('name'=>'UGANDA','code'=>'256'),
350
- 'US'=>array('name'=>'UNITED STATES','code'=>'1'),
351
- 'UY'=>array('name'=>'URUGUAY','code'=>'598'),
352
- 'UZ'=>array('name'=>'UZBEKISTAN','code'=>'998'),
353
- 'VA'=>array('name'=>'HOLY SEE (VATICAN CITY STATE)','code'=>'39'),
354
- 'VC'=>array('name'=>'SAINT VINCENT AND THE GRENADINES','code'=>'1784'),
355
- 'VE'=>array('name'=>'VENEZUELA','code'=>'58'),
356
- 'VG'=>array('name'=>'VIRGIN ISLANDS, BRITISH','code'=>'1284'),
357
- 'VI'=>array('name'=>'VIRGIN ISLANDS, U.S.','code'=>'1340'),
358
- 'VN'=>array('name'=>'VIET NAM','code'=>'84'),
359
- 'VU'=>array('name'=>'VANUATU','code'=>'678'),
360
- 'WF'=>array('name'=>'WALLIS AND FUTUNA','code'=>'681'),
361
- 'WS'=>array('name'=>'SAMOA','code'=>'685'),
362
- 'XK'=>array('name'=>'KOSOVO','code'=>'381'),
363
- 'YE'=>array('name'=>'YEMEN','code'=>'967'),
364
- 'YT'=>array('name'=>'MAYOTTE','code'=>'262'),
365
- 'ZA'=>array('name'=>'SOUTH AFRICA','code'=>'27'),
366
- 'ZM'=>array('name'=>'ZAMBIA','code'=>'260'),
367
- 'ZW'=>array('name'=>'ZIMBABWE','code'=>'263')
 
368
  );
369
 
370
  return $phone_countries;
371
  }
372
 
 
 
 
 
373
  /**
374
  * Sanitize submitted value before storing it.
375
  *
@@ -381,32 +364,31 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
381
  */
382
  public function sanitize_value( $part_data = array(), $form_data = array() ) {
383
  $sanitized_value = $this->get_default_value();
384
- $confirmed_value = $sanitized_value;
385
  $part_name = happyforms_get_part_name( $part_data, $form_data );
386
 
387
  if ( isset( $_REQUEST[$part_name] ) ) {
388
- $sanitized_value = sanitize_text_field( $_REQUEST[$part_name] );
389
  }
390
 
391
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
392
- $confirmed_value = sanitize_text_field( $_REQUEST[$part_name . '_confirmation'] );
393
  }
394
 
395
- if ( $part_data['mask_phone_country'] ) {
396
- $prefix_length = strlen( $part_data['mask_phone_country'] ) + 1;
397
- $sanitized_value = substr( $sanitized_value, $prefix_length );
398
- $confirmed_value = substr( $confirmed_value, $prefix_length );
399
- }
400
 
401
- if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
402
- $sanitized_value = array( $sanitized_value, $confirmed_value );
403
  }
404
 
405
  return $sanitized_value;
406
  }
407
 
408
  /**
409
- * Validate value before submitting it. If it fails validation, return WP_Error object, showing respective error message.
 
410
  *
411
  * @since 1.0.0.
412
  *
@@ -415,21 +397,54 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
415
  *
416
  * @return string|object
417
  */
418
- public function validate_value( $part_data, $value ) {
419
- $has_confirmation_value = is_array( $value );
420
- $validated_value = $has_confirmation_value ? $value[0] : $value;
 
 
 
421
 
422
- if ( $part_data['required'] && '' === $validated_value ) {
423
- $validated_value = new WP_Error( 'missing_required_field' );
424
- return $validated_value;
425
  }
426
 
427
- if ( $has_confirmation_value && $value[0] !== $value[1] ) {
428
- $validated_value = new WP_Error( 'numbers_not_matching' );
429
- return $validated_value;
430
  }
431
 
432
- return $validated_value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433
  }
434
 
435
  public function html_part_data_attributes( $attributes, $part, $form ) {
@@ -513,6 +528,15 @@ class HappyForms_Part_Phone extends HappyForms_Form_Part {
513
  array( 'cleave-phone' ), HAPPYFORMS_VERSION, true
514
  );
515
 
 
 
 
 
 
 
 
 
 
516
  $deps[] = 'happyforms-part-phone';
517
 
518
  return $deps;
8
  $this->label = __( 'Phone', 'happyforms' );
9
  $this->description = __( 'For phone numbers. Includes country specific formatting.', 'happyforms' );
10
 
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  add_filter( 'happyforms_part_data_attributes', array( $this, 'html_part_data_attributes' ), 10, 3 );
13
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
14
+ add_filter( 'happyforms_part_value', array( $this, 'get_part_value' ), 10, 4 );
15
  }
16
 
17
  /**
68
  'sanitize' => 'intval'
69
  ),
70
  'confirmation_field_label' => array(
71
+ 'default' => __( 'Confirm Phone', 'happyforms' ),
72
  'sanitize' => 'sanitize_text_field'
73
  ),
74
  'required' => array(
106
  include( happyforms_get_include_folder() . '/templates/parts/frontend-phone.php' );
107
  }
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  /**
110
  * Get associative array of country code => country name and phone code (prefix) for masking purposes.
111
  *
115
  */
116
  public function get_phone_countries_array() {
117
  $phone_countries = array(
118
+ 'AD' => array( 'name' => 'ANDORRA', 'code' => '376' ),
119
+ 'AE' => array( 'name' => 'UNITED ARAB EMIRATES', 'code' => '971' ),
120
+ 'AF' => array( 'name' => 'AFGHANISTAN', 'code' => '93' ),
121
+ 'AG' => array( 'name' => 'ANTIGUA AND BARBUDA', 'code' => '1268' ),
122
+ 'AI' => array( 'name' => 'ANGUILLA', 'code' => '1264' ),
123
+ 'AL' => array( 'name' => 'ALBANIA', 'code' => '355' ),
124
+ 'AM' => array( 'name' => 'ARMENIA', 'code' => '374' ),
125
+ 'AN' => array( 'name' => 'NETHERLANDS ANTILLES', 'code' => '599' ),
126
+ 'AO' => array( 'name' => 'ANGOLA', 'code' => '244' ),
127
+ 'AQ' => array( 'name' => 'ANTARCTICA', 'code' => '672' ),
128
+ 'AR' => array( 'name' => 'ARGENTINA', 'code' => '54' ),
129
+ 'AS' => array( 'name' => 'AMERICAN SAMOA', 'code' => '1684' ),
130
+ 'AT' => array( 'name' => 'AUSTRIA', 'code' => '43' ),
131
+ 'AU' => array( 'name' => 'AUSTRALIA', 'code' => '61' ),
132
+ 'AW' => array( 'name' => 'ARUBA', 'code' => '297' ),
133
+ 'AZ' => array( 'name' => 'AZERBAIJAN', 'code' => '994' ),
134
+ 'BA' => array( 'name' => 'BOSNIA AND HERZEGOVINA', 'code' => '387' ),
135
+ 'BB' => array( 'name' => 'BARBADOS', 'code' => '1246' ),
136
+ 'BD' => array( 'name' => 'BANGLADESH', 'code' => '880' ),
137
+ 'BE' => array( 'name' => 'BELGIUM', 'code' => '32' ),
138
+ 'BF' => array( 'name' => 'BURKINA FASO', 'code' => '226' ),
139
+ 'BG' => array( 'name' => 'BULGARIA', 'code' => '359' ),
140
+ 'BH' => array( 'name' => 'BAHRAIN', 'code' => '973' ),
141
+ 'BI' => array( 'name' => 'BURUNDI', 'code' => '257' ),
142
+ 'BJ' => array( 'name' => 'BENIN', 'code' => '229' ),
143
+ 'BL' => array( 'name' => 'SAINT BARTHELEMY', 'code' => '590' ),
144
+ 'BM' => array( 'name' => 'BERMUDA', 'code' => '1441' ),
145
+ 'BN' => array( 'name' => 'BRUNEI DARUSSALAM', 'code' => '673' ),
146
+ 'BO' => array( 'name' => 'BOLIVIA', 'code' => '591' ),
147
+ 'BR' => array( 'name' => 'BRAZIL', 'code' => '55' ),
148
+ 'BS' => array( 'name' => 'BAHAMAS', 'code' => '1242' ),
149
+ 'BT' => array( 'name' => 'BHUTAN', 'code' => '975' ),
150
+ 'BW' => array( 'name' => 'BOTSWANA', 'code' => '267' ),
151
+ 'BY' => array( 'name' => 'BELARUS', 'code' => '375' ),
152
+ 'BZ' => array( 'name' => 'BELIZE', 'code' => '501' ),
153
+ 'CA' => array( 'name' => 'CANADA', 'code' => '1' ),
154
+ 'CC' => array( 'name' => 'COCOS (KEELING) ISLANDS', 'code' => '61' ),
155
+ 'CD' => array( 'name' => 'CONGO, THE DEMOCRATIC REPUBLIC OF THE', 'code' => '243' ),
156
+ 'CF' => array( 'name' => 'CENTRAL AFRICAN REPUBLIC', 'code' => '236' ),
157
+ 'CG' => array( 'name' => 'CONGO', 'code' => '242' ),
158
+ 'CH' => array( 'name' => 'SWITZERLAND', 'code' => '41' ),
159
+ 'CI' => array( 'name' => 'COTE D IVOIRE', 'code' => '225' ),
160
+ 'CK' => array( 'name' => 'COOK ISLANDS', 'code' => '682' ),
161
+ 'CL' => array( 'name' => 'CHILE', 'code' => '56' ),
162
+ 'CM' => array( 'name' => 'CAMEROON', 'code' => '237' ),
163
+ 'CN' => array( 'name' => 'CHINA', 'code' => '86' ),
164
+ 'CO' => array( 'name' => 'COLOMBIA', 'code' => '57' ),
165
+ 'CR' => array( 'name' => 'COSTA RICA', 'code' => '506' ),
166
+ 'CU' => array( 'name' => 'CUBA', 'code' => '53' ),
167
+ 'CV' => array( 'name' => 'CAPE VERDE', 'code' => '238' ),
168
+ 'CY' => array( 'name' => 'CYPRUS', 'code' => '357' ),
169
+ 'CZ' => array( 'name' => 'CZECH REPUBLIC', 'code' => '420' ),
170
+ 'DE' => array( 'name' => 'GERMANY', 'code' => '49' ),
171
+ 'DJ' => array( 'name' => 'DJIBOUTI', 'code' => '253' ),
172
+ 'DK' => array( 'name' => 'DENMARK', 'code' => '45' ),
173
+ 'DM' => array( 'name' => 'DOMINICA', 'code' => '1767' ),
174
+ 'DO' => array( 'name' => 'DOMINICAN REPUBLIC', 'code' => '1809' ),
175
+ 'DZ' => array( 'name' => 'ALGERIA', 'code' => '213' ),
176
+ 'EC' => array( 'name' => 'ECUADOR', 'code' => '593' ),
177
+ 'EE' => array( 'name' => 'ESTONIA', 'code' => '372' ),
178
+ 'EG' => array( 'name' => 'EGYPT', 'code' => '20' ),
179
+ 'ER' => array( 'name' => 'ERITREA', 'code' => '291' ),
180
+ 'ES' => array( 'name' => 'SPAIN', 'code' => '34' ),
181
+ 'ET' => array( 'name' => 'ETHIOPIA', 'code' => '251' ),
182
+ 'FI' => array( 'name' => 'FINLAND', 'code' => '358' ),
183
+ 'FJ' => array( 'name' => 'FIJI', 'code' => '679' ),
184
+ 'FK' => array( 'name' => 'FALKLAND ISLANDS (MALVINAS)', 'code' => '500' ),
185
+ 'FM' => array( 'name' => 'MICRONESIA, FEDERATED STATES OF', 'code' => '691' ),
186
+ 'FO' => array( 'name' => 'FAROE ISLANDS', 'code' => '298' ),
187
+ 'FR' => array( 'name' => 'FRANCE', 'code' => '33' ),
188
+ 'GA' => array( 'name' => 'GABON', 'code' => '241' ),
189
+ 'GB' => array( 'name' => 'UNITED KINGDOM', 'code' => '44' ),
190
+ 'GD' => array( 'name' => 'GRENADA', 'code' => '1473' ),
191
+ 'GE' => array( 'name' => 'GEORGIA', 'code' => '995' ),
192
+ 'GH' => array( 'name' => 'GHANA', 'code' => '233' ),
193
+ 'GI' => array( 'name' => 'GIBRALTAR', 'code' => '350' ),
194
+ 'GL' => array( 'name' => 'GREENLAND', 'code' => '299' ),
195
+ 'GM' => array( 'name' => 'GAMBIA', 'code' => '220' ),
196
+ 'GN' => array( 'name' => 'GUINEA', 'code' => '224' ),
197
+ 'GQ' => array( 'name' => 'EQUATORIAL GUINEA', 'code' => '240' ),
198
+ 'GR' => array( 'name' => 'GREECE', 'code' => '30' ),
199
+ 'GT' => array( 'name' => 'GUATEMALA', 'code' => '502' ),
200
+ 'GU' => array( 'name' => 'GUAM', 'code' => '1671' ),
201
+ 'GW' => array( 'name' => 'GUINEA-BISSAU', 'code' => '245' ),
202
+ 'GY' => array( 'name' => 'GUYANA', 'code' => '592' ),
203
+ 'HK' => array( 'name' => 'HONG KONG', 'code' => '852' ),
204
+ 'HN' => array( 'name' => 'HONDURAS', 'code' => '504' ),
205
+ 'HR' => array( 'name' => 'CROATIA', 'code' => '385' ),
206
+ 'HT' => array( 'name' => 'HAITI', 'code' => '509' ),
207
+ 'HU' => array( 'name' => 'HUNGARY', 'code' => '36' ),
208
+ 'ID' => array( 'name' => 'INDONESIA', 'code' => '62' ),
209
+ 'IE' => array( 'name' => 'IRELAND', 'code' => '353' ),
210
+ 'IL' => array( 'name' => 'ISRAEL', 'code' => '972' ),
211
+ 'IM' => array( 'name' => 'ISLE OF MAN', 'code' => '44' ),
212
+ 'IN' => array( 'name' => 'INDIA', 'code' => '91' ),
213
+ 'IQ' => array( 'name' => 'IRAQ', 'code' => '964' ),
214
+ 'IR' => array( 'name' => 'IRAN, ISLAMIC REPUBLIC OF', 'code' => '98' ),
215
+ 'IS' => array( 'name' => 'ICELAND', 'code' => '354' ),
216
+ 'IT' => array( 'name' => 'ITALY', 'code' => '39' ),
217
+ 'JM' => array( 'name' => 'JAMAICA', 'code' => '1876' ),
218
+ 'JO' => array( 'name' => 'JORDAN', 'code' => '962' ),
219
+ 'JP' => array( 'name' => 'JAPAN', 'code' => '81' ),
220
+ 'KE' => array( 'name' => 'KENYA', 'code' => '254' ),
221
+ 'KG' => array( 'name' => 'KYRGYZSTAN', 'code' => '996' ),
222
+ 'KH' => array( 'name' => 'CAMBODIA', 'code' => '855' ),
223
+ 'KI' => array( 'name' => 'KIRIBATI', 'code' => '686' ),
224
+ 'KM' => array( 'name' => 'COMOROS', 'code' => '269' ),
225
+ 'KN' => array( 'name' => 'SAINT KITTS AND NEVIS', 'code' => '1869' ),
226
+ 'KP' => array( 'name' => 'KOREA DEMOCRATIC PEOPLES REPUBLIC OF', 'code' => '850' ),
227
+ 'KR' => array( 'name' => 'KOREA REPUBLIC OF', 'code' => '82' ),
228
+ 'KW' => array( 'name' => 'KUWAIT', 'code' => '965' ),
229
+ 'KY' => array( 'name' => 'CAYMAN ISLANDS', 'code' => '1345' ),
230
+ 'KZ' => array( 'name' => 'KAZAKSTAN', 'code' => '7' ),
231
+ 'LA' => array( 'name' => 'LAO PEOPLES DEMOCRATIC REPUBLIC', 'code' => '856' ),
232
+ 'LB' => array( 'name' => 'LEBANON', 'code' => '961' ),
233
+ 'LC' => array( 'name' => 'SAINT LUCIA', 'code' => '1758' ),
234
+ 'LI' => array( 'name' => 'LIECHTENSTEIN', 'code' => '423' ),
235
+ 'LK' => array( 'name' => 'SRI LANKA', 'code' => '94' ),
236
+ 'LR' => array( 'name' => 'LIBERIA', 'code' => '231' ),
237
+ 'LS' => array( 'name' => 'LESOTHO', 'code' => '266' ),
238
+ 'LT' => array( 'name' => 'LITHUANIA', 'code' => '370' ),
239
+ 'LU' => array( 'name' => 'LUXEMBOURG', 'code' => '352' ),
240
+ 'LV' => array( 'name' => 'LATVIA', 'code' => '371' ),
241
+ 'LY' => array( 'name' => 'LIBYAN ARAB JAMAHIRIYA', 'code' => '218' ),
242
+ 'MA' => array( 'name' => 'MOROCCO', 'code' => '212' ),
243
+ 'MC' => array( 'name' => 'MONACO', 'code' => '377' ),
244
+ 'MD' => array( 'name' => 'MOLDOVA, REPUBLIC OF', 'code' => '373' ),
245
+ 'ME' => array( 'name' => 'MONTENEGRO', 'code' => '382' ),
246
+ 'MF' => array( 'name' => 'SAINT MARTIN', 'code' => '1599' ),
247
+ 'MG' => array( 'name' => 'MADAGASCAR', 'code' => '261' ),
248
+ 'MH' => array( 'name' => 'MARSHALL ISLANDS', 'code' => '692' ),
249
+ 'MK' => array( 'name' => 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF', 'code' => '389' ),
250
+ 'ML' => array( 'name' => 'MALI', 'code' => '223' ),
251
+ 'MM' => array( 'name' => 'MYANMAR', 'code' => '95' ),
252
+ 'MN' => array( 'name' => 'MONGOLIA', 'code' => '976' ),
253
+ 'MO' => array( 'name' => 'MACAU', 'code' => '853' ),
254
+ 'MP' => array( 'name' => 'NORTHERN MARIANA ISLANDS', 'code' => '1670' ),
255
+ 'MR' => array( 'name' => 'MAURITANIA', 'code' => '222' ),
256
+ 'MS' => array( 'name' => 'MONTSERRAT', 'code' => '1664' ),
257
+ 'MT' => array( 'name' => 'MALTA', 'code' => '356' ),
258
+ 'MU' => array( 'name' => 'MAURITIUS', 'code' => '230' ),
259
+ 'MV' => array( 'name' => 'MALDIVES', 'code' => '960' ),
260
+ 'MW' => array( 'name' => 'MALAWI', 'code' => '265' ),
261
+ 'MX' => array( 'name' => 'MEXICO', 'code' => '52' ),
262
+ 'MY' => array( 'name' => 'MALAYSIA', 'code' => '60' ),
263
+ 'MZ' => array( 'name' => 'MOZAMBIQUE', 'code' => '258' ),
264
+ 'NA' => array( 'name' => 'NAMIBIA', 'code' => '264' ),
265
+ 'NC' => array( 'name' => 'NEW CALEDONIA', 'code' => '687' ),
266
+ 'NE' => array( 'name' => 'NIGER', 'code' => '227' ),
267
+ 'NG' => array( 'name' => 'NIGERIA', 'code' => '234' ),
268
+ 'NI' => array( 'name' => 'NICARAGUA', 'code' => '505' ),
269
+ 'NL' => array( 'name' => 'NETHERLANDS', 'code' => '31' ),
270
+ 'NO' => array( 'name' => 'NORWAY', 'code' => '47' ),
271
+ 'NP' => array( 'name' => 'NEPAL', 'code' => '977' ),
272
+ 'NR' => array( 'name' => 'NAURU', 'code' => '674' ),
273
+ 'NU' => array( 'name' => 'NIUE', 'code' => '683' ),
274
+ 'NZ' => array( 'name' => 'NEW ZEALAND', 'code' => '64' ),
275
+ 'OM' => array( 'name' => 'OMAN', 'code' => '968' ),
276
+ 'PA' => array( 'name' => 'PANAMA', 'code' => '507' ),
277
+ 'PE' => array( 'name' => 'PERU', 'code' => '51' ),
278
+ 'PF' => array( 'name' => 'FRENCH POLYNESIA', 'code' => '689' ),
279
+ 'PG' => array( 'name' => 'PAPUA NEW GUINEA', 'code' => '675' ),
280
+ 'PH' => array( 'name' => 'PHILIPPINES', 'code' => '63' ),
281
+ 'PK' => array( 'name' => 'PAKISTAN', 'code' => '92' ),
282
+ 'PL' => array( 'name' => 'POLAND', 'code' => '48' ),
283
+ 'PM' => array( 'name' => 'SAINT PIERRE AND MIQUELON', 'code' => '508' ),
284
+ 'PN' => array( 'name' => 'PITCAIRN', 'code' => '870' ),
285
+ 'PR' => array( 'name' => 'PUERTO RICO', 'code' => '1' ),
286
+ 'PT' => array( 'name' => 'PORTUGAL', 'code' => '351' ),
287
+ 'PW' => array( 'name' => 'PALAU', 'code' => '680' ),
288
+ 'PY' => array( 'name' => 'PARAGUAY', 'code' => '595' ),
289
+ 'QA' => array( 'name' => 'QATAR', 'code' => '974' ),
290
+ 'RO' => array( 'name' => 'ROMANIA', 'code' => '40' ),
291
+ 'RS' => array( 'name' => 'SERBIA', 'code' => '381' ),
292
+ 'RU' => array( 'name' => 'RUSSIAN FEDERATION', 'code' => '7' ),
293
+ 'RW' => array( 'name' => 'RWANDA', 'code' => '250' ),
294
+ 'SA' => array( 'name' => 'SAUDI ARABIA', 'code' => '966' ),
295
+ 'SB' => array( 'name' => 'SOLOMON ISLANDS', 'code' => '677' ),
296
+ 'SC' => array( 'name' => 'SEYCHELLES', 'code' => '248' ),
297
+ 'SD' => array( 'name' => 'SUDAN', 'code' => '249' ),
298
+ 'SE' => array( 'name' => 'SWEDEN', 'code' => '46' ),
299
+ 'SG' => array( 'name' => 'SINGAPORE', 'code' => '65' ),
300
+ 'SH' => array( 'name' => 'SAINT HELENA', 'code' => '290' ),
301
+ 'SI' => array( 'name' => 'SLOVENIA', 'code' => '386' ),
302
+ 'SK' => array( 'name' => 'SLOVAKIA', 'code' => '421' ),
303
+ 'SL' => array( 'name' => 'SIERRA LEONE', 'code' => '232' ),
304
+ 'SM' => array( 'name' => 'SAN MARINO', 'code' => '378' ),
305
+ 'SN' => array( 'name' => 'SENEGAL', 'code' => '221' ),
306
+ 'SO' => array( 'name' => 'SOMALIA', 'code' => '252' ),
307
+ 'SR' => array( 'name' => 'SURINAME', 'code' => '597' ),
308
+ 'ST' => array( 'name' => 'SAO TOME AND PRINCIPE', 'code' => '239' ),
309
+ 'SV' => array( 'name' => 'EL SALVADOR', 'code' => '503' ),
310
+ 'SY' => array( 'name' => 'SYRIAN ARAB REPUBLIC', 'code' => '963' ),
311
+ 'SZ' => array( 'name' => 'SWAZILAND', 'code' => '268' ),
312
+ 'TC' => array( 'name' => 'TURKS AND CAICOS ISLANDS', 'code' => '1649' ),
313
+ 'TD' => array( 'name' => 'CHAD', 'code' => '235' ),
314
+ 'TG' => array( 'name' => 'TOGO', 'code' => '228' ),
315
+ 'TH' => array( 'name' => 'THAILAND', 'code' => '66' ),
316
+ 'TJ' => array( 'name' => 'TAJIKISTAN', 'code' => '992' ),
317
+ 'TK' => array( 'name' => 'TOKELAU', 'code' => '690' ),
318
+ 'TL' => array( 'name' => 'TIMOR-LESTE', 'code' => '670' ),
319
+ 'TM' => array( 'name' => 'TURKMENISTAN', 'code' => '993' ),
320
+ 'TN' => array( 'name' => 'TUNISIA', 'code' => '216' ),
321
+ 'TO' => array( 'name' => 'TONGA', 'code' => '676' ),
322
+ 'TR' => array( 'name' => 'TURKEY', 'code' => '90' ),
323
+ 'TT' => array( 'name' => 'TRINIDAD AND TOBAGO', 'code' => '1868' ),
324
+ 'TV' => array( 'name' => 'TUVALU', 'code' => '688' ),
325
+ 'TW' => array( 'name' => 'TAIWAN, PROVINCE OF CHINA', 'code' => '886' ),
326
+ 'TZ' => array( 'name' => 'TANZANIA, UNITED REPUBLIC OF', 'code' => '255' ),
327
+ 'UA' => array( 'name' => 'UKRAINE', 'code' => '380' ),
328
+ 'UG' => array( 'name' => 'UGANDA', 'code' => '256' ),
329
+ 'US' => array( 'name' => 'UNITED STATES', 'code' => '1' ),
330
+ 'UY' => array( 'name' => 'URUGUAY', 'code' => '598' ),
331
+ 'UZ' => array( 'name' => 'UZBEKISTAN', 'code' => '998' ),
332
+ 'VA' => array( 'name' => 'HOLY SEE (VATICAN CITY STATE)', 'code' => '39' ),
333
+ 'VC' => array( 'name' => 'SAINT VINCENT AND THE GRENADINES', 'code' => '1784' ),
334
+ 'VE' => array( 'name' => 'VENEZUELA', 'code' => '58' ),
335
+ 'VG' => array( 'name' => 'VIRGIN ISLANDS, BRITISH', 'code' => '1284' ),
336
+ 'VI' => array( 'name' => 'VIRGIN ISLANDS, U.S.', 'code' => '1340' ),
337
+ 'VN' => array( 'name' => 'VIET NAM', 'code' => '84' ),
338
+ 'VU' => array( 'name' => 'VANUATU', 'code' => '678' ),
339
+ 'WF' => array( 'name' => 'WALLIS AND FUTUNA', 'code' => '681' ),
340
+ 'WS' => array( 'name' => 'SAMOA', 'code' => '685' ),
341
+ 'XK' => array( 'name' => 'KOSOVO', 'code' => '381' ),
342
+ 'YE' => array( 'name' => 'YEMEN', 'code' => '967' ),
343
+ 'YT' => array( 'name' => 'MAYOTTE', 'code' => '262' ),
344
+ 'ZA' => array( 'name' => 'SOUTH AFRICA', 'code' => '27' ),
345
+ 'ZM' => array( 'name' => 'ZAMBIA', 'code' => '260' ),
346
+ 'ZW' => array( 'name' => 'ZIMBABWE', 'code' => '263 '),
347
  );
348
 
349
  return $phone_countries;
350
  }
351
 
352
+ public function get_default_value() {
353
+ return array();
354
+ }
355
+
356
  /**
357
  * Sanitize submitted value before storing it.
358
  *
364
  */
365
  public function sanitize_value( $part_data = array(), $form_data = array() ) {
366
  $sanitized_value = $this->get_default_value();
 
367
  $part_name = happyforms_get_part_name( $part_data, $form_data );
368
 
369
  if ( isset( $_REQUEST[$part_name] ) ) {
370
+ $sanitized_value[0] = $_REQUEST[$part_name];
371
  }
372
 
373
  if ( isset( $_REQUEST[$part_name . '_confirmation'] ) ) {
374
+ $sanitized_value[1] = $_REQUEST[$part_name . '_confirmation'];
375
  }
376
 
377
+ foreach ( $sanitized_value as $v => $value ) {
378
+ if ( $part_data['mask_phone_country'] ) {
379
+ $prefix_length = strlen( $part_data['mask_phone_country'] ) + 1;
380
+ $value = substr( $value, $prefix_length );
381
+ }
382
 
383
+ $sanitized_value[$v] = preg_replace( '/[^0-9]/', '', $value );
 
384
  }
385
 
386
  return $sanitized_value;
387
  }
388
 
389
  /**
390
+ * Validate value before submitting it. If it fails validation,
391
+ * return WP_Error object, showing respective error message.
392
  *
393
  * @since 1.0.0.
394
  *
397
  *
398
  * @return string|object
399
  */
400
+ public function validate_value( $value, $part = array(), $form = array() ) {
401
+ $validated_values = $value;
402
+
403
+ if ( $part['required'] && empty( $validated_values ) ) {
404
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
405
+ }
406
 
407
+ if ( $part['required'] && empty( $validated_values[0] ) ) {
408
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
409
  }
410
 
411
+ if ( isset( $validated_values[1] ) && $validated_values[0] !== $validated_values[1] ) {
412
+ return new WP_Error( 'error', __( 'Number and confirmation number are not matching.', 'happyforms' ) );
 
413
  }
414
 
415
+ if ( $part['mask_phone_country'] ) {
416
+ foreach ( $validated_values as $v => $validated_value ) {
417
+ $validated_values[$v] = $part['mask_phone_country'] . $validated_values[$v];
418
+ }
419
+ }
420
+
421
+ return $validated_values[0];
422
+ }
423
+
424
+ public function get_part_value( $value, $part, $form, $component ) {
425
+ if ( $this->type === $part['type'] ) {
426
+ if ( false !== $component ) {
427
+ $value = isset( $value[$component] ) ? $value[$component] : '';
428
+
429
+ if ( $part['masked'] && $part['mask_phone_country'] ) {
430
+ $value = '+' . $part['mask_phone_country'] . $value;
431
+ }
432
+ }
433
+ }
434
+
435
+ return $value;
436
+ }
437
+
438
+ public function html_part_class( $class, $part, $form ) {
439
+ if ( $this->type === $part['type'] ) {
440
+ if ( $part['masked'] && $part['mask_phone_country']
441
+ || happyforms_get_part_value( $part, $form, 0 )
442
+ || happyforms_get_part_value( $part, $form, 1 ) ) {
443
+ $class[] = 'happyforms-part--filled';
444
+ }
445
+ }
446
+
447
+ return $class;
448
  }
449
 
450
  public function html_part_data_attributes( $attributes, $part, $form ) {
528
  array( 'cleave-phone' ), HAPPYFORMS_VERSION, true
529
  );
530
 
531
+ $codes = wp_list_pluck( $this->get_phone_countries_array(), 'code' );
532
+ $codes = array_flip( $codes );
533
+ $settings = array( 'codes' => $codes );
534
+
535
+ wp_localize_script(
536
+ 'happyforms-part-phone',
537
+ 'HappyFormsPhoneSettings', $settings
538
+ );
539
+
540
  $deps[] = 'happyforms-part-phone';
541
 
542
  return $deps;
inc/classes/parts/class-part-placeholder.php CHANGED
@@ -7,6 +7,8 @@ class HappyForms_Part_Placeholder extends HappyForms_Form_Part {
7
  public function __construct() {
8
  $this->label = __( 'Placeholder', 'happyforms' );
9
  $this->description = __( 'For adding helper text, horizontal rules and extra space.', 'happyforms' );
 
 
10
  }
11
 
12
  /**
@@ -44,7 +46,7 @@ class HappyForms_Part_Placeholder extends HappyForms_Form_Part {
44
  ),
45
  'placeholder_text' => array(
46
  'default' => '',
47
- 'sanitize' => 'sanitize_text_field'
48
  )
49
  );
50
  }
@@ -113,17 +115,25 @@ class HappyForms_Part_Placeholder extends HappyForms_Form_Part {
113
  *
114
  * @since 1.0.0.
115
  *
116
- * @param array $part_data Form part data.
117
  * @param string $value Submitted value.
118
  *
119
  * @return string
120
  */
121
- public function validate_value( $part_data, $value ) {
122
  $validated_value = esc_attr( $value );
123
 
124
  return $validated_value;
125
  }
126
 
 
 
 
 
 
 
 
 
127
  /**
128
  * Enqueue scripts in customizer area.
129
  *
7
  public function __construct() {
8
  $this->label = __( 'Placeholder', 'happyforms' );
9
  $this->description = __( 'For adding helper text, horizontal rules and extra space.', 'happyforms' );
10
+
11
+ add_filter( 'happyforms_message_part_visible', array( $this, 'message_part_visible' ), 10, 2 );
12
  }
13
 
14
  /**
46
  ),
47
  'placeholder_text' => array(
48
  'default' => '',
49
+ 'sanitize' => 'esc_html'
50
  )
51
  );
52
  }
115
  *
116
  * @since 1.0.0.
117
  *
118
+ * @param array $part Form part data.
119
  * @param string $value Submitted value.
120
  *
121
  * @return string
122
  */
123
+ public function validate_value( $value, $part = array(), $form = array() ) {
124
  $validated_value = esc_attr( $value );
125
 
126
  return $validated_value;
127
  }
128
 
129
+ public function message_part_visible( $visible, $part ) {
130
+ if ( $this->type === $part['type'] ) {
131
+ $visible = false;
132
+ }
133
+
134
+ return $visible;
135
+ }
136
+
137
  /**
138
  * Enqueue scripts in customizer area.
139
  *
inc/classes/parts/class-part-radio.php CHANGED
@@ -128,26 +128,6 @@ class HappyForms_Part_Radio extends HappyForms_Form_Part {
128
  );
129
  }
130
 
131
- /**
132
- * Get all possible messages definitions.
133
- *
134
- * @since 1.0.0.
135
- *
136
- * @return array Associative array, specifying message type and copy.
137
- */
138
- public function get_message_definitions() {
139
- return array(
140
- 'missing_required_field' => array(
141
- 'type' => 'error',
142
- 'message' => __( 'This field is required.', 'happyforms' ),
143
- ),
144
- 'not_valid_value' => array(
145
- 'type' => 'error',
146
- 'message' => __( 'Radio values are not valid.', 'happyforms' )
147
- )
148
- );
149
- }
150
-
151
  /**
152
  * Sanitize submitted value before storing it.
153
  *
@@ -173,32 +153,33 @@ class HappyForms_Part_Radio extends HappyForms_Form_Part {
173
  *
174
  * @since 1.0.0.
175
  *
176
- * @param array $part_data Form part data.
177
  * @param string $value Submitted value.
178
  *
179
  * @return string|object
180
  */
181
- public function validate_value( $part_data, $value ) {
182
  $validated_value = $value;
183
 
184
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
185
- $validated_value = new WP_Error( 'missing_required_field' );
186
- return $validated_value;
187
  }
188
 
189
- $allowed_values = wp_list_pluck( $part_data['options'], 'label' );
 
190
 
191
- if ( ! in_array( $value, $allowed_values ) ) {
192
- $validated_value = new WP_Error( 'not_valid_value' );
193
- return $validated_value;
194
  }
195
 
196
  return $validated_value;
197
  }
198
 
199
- public function html_part_class( $class, $part_data, $form_data ) {
200
- if ( isset( $part_data['display_type'] ) && 'block' === $part_data['display_type'] ) {
201
- $class[] = 'display-type--block';
 
 
202
  }
203
 
204
  return $class;
128
  );
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  /**
132
  * Sanitize submitted value before storing it.
133
  *
153
  *
154
  * @since 1.0.0.
155
  *
156
+ * @param array $part Form part data.
157
  * @param string $value Submitted value.
158
  *
159
  * @return string|object
160
  */
161
+ public function validate_value( $value, $part = array(), $form = array() ) {
162
  $validated_value = $value;
163
 
164
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
165
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
166
  }
167
 
168
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
169
+ $options = wp_list_pluck( $options, 'label' );
170
 
171
+ if ( ! in_array( $value, $options ) ) {
172
+ return new WP_Error( 'error', __( 'Radio values are not valid.', 'happyforms' ) );
 
173
  }
174
 
175
  return $validated_value;
176
  }
177
 
178
+ public function html_part_class( $class, $part, $form ) {
179
+ if ( $this->type === $part['type'] ) {
180
+ if ( isset( $part['display_type'] ) && 'block' === $part['display_type'] ) {
181
+ $class[] = 'display-type--block';
182
+ }
183
  }
184
 
185
  return $class;
inc/classes/parts/class-part-rating.php CHANGED
@@ -8,6 +8,8 @@ class HappyForms_Part_Rating extends HappyForms_Form_Part {
8
  public function __construct() {
9
  $this->label = __( 'Rating', 'happyforms' );
10
  $this->description = __( 'For collecting opinions using a zero to five star scale.', 'happyforms' );
 
 
11
  }
12
 
13
  /**
@@ -86,26 +88,6 @@ class HappyForms_Part_Rating extends HappyForms_Form_Part {
86
  include( happyforms_get_include_folder() . '/templates/parts/frontend-rating.php' );
87
  }
88
 
89
- /**
90
- * Get all possible messages definitions.
91
- *
92
- * @since 1.0.0.
93
- *
94
- * @return array Associative array, specifying message type and copy.
95
- */
96
- public function get_message_definitions() {
97
- return array(
98
- 'missing_required_field' => array(
99
- 'type' => 'error',
100
- 'message' => __( 'This field is required.', 'happyforms' ),
101
- ),
102
- 'incorrect_value' => array(
103
- 'type' => 'error',
104
- 'message' => __( 'Value should be between 1 and 5.', 'happyforms' )
105
- )
106
- );
107
- }
108
-
109
  /**
110
  * Sanitize submitted value before storing it.
111
  *
@@ -131,21 +113,21 @@ class HappyForms_Part_Rating extends HappyForms_Form_Part {
131
  *
132
  * @since 1.0.0.
133
  *
134
- * @param array $part_data Form part data.
135
  * @param string $value Submitted value.
136
  *
137
  * @return string|object
138
  */
139
- public function validate_value( $part_data, $value ) {
140
  $validated_value = $value;
141
 
142
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
143
- $validated_value = new WP_Error( 'missing_required_field' );
144
  return $validated_value;
145
  }
146
 
147
  if ( $validated_value < 1 || $validated_value > 5 ) {
148
- $validated_value = new WP_Error( 'incorrect_value' );
149
  return $validated_value;
150
  }
151
 
@@ -169,4 +151,30 @@ class HappyForms_Part_Rating extends HappyForms_Form_Part {
169
  );
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }
8
  public function __construct() {
9
  $this->label = __( 'Rating', 'happyforms' );
10
  $this->description = __( 'For collecting opinions using a zero to five star scale.', 'happyforms' );
11
+
12
+ add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
13
  }
14
 
15
  /**
88
  include( happyforms_get_include_folder() . '/templates/parts/frontend-rating.php' );
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  /**
92
  * Sanitize submitted value before storing it.
93
  *
113
  *
114
  * @since 1.0.0.
115
  *
116
+ * @param array $part Form part data.
117
  * @param string $value Submitted value.
118
  *
119
  * @return string|object
120
  */
121
+ public function validate_value( $value, $part = array(), $form = array() ) {
122
  $validated_value = $value;
123
 
124
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
125
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
126
  return $validated_value;
127
  }
128
 
129
  if ( $validated_value < 1 || $validated_value > 5 ) {
130
+ $validated_value = new WP_Error( 'error', __( 'Value should be between 1 and 5.', 'happyforms' ) );
131
  return $validated_value;
132
  }
133
 
151
  );
152
  }
153
 
154
+ public function script_dependencies( $deps, $forms ) {
155
+ $contains_rating = false;
156
+ $form_controller = happyforms_get_form_controller();
157
+
158
+ foreach ( $forms as $form ) {
159
+ if ( $form_controller->get_first_part_by_type( $form, $this->type ) ) {
160
+ $contains_rating = true;
161
+ break;
162
+ }
163
+ }
164
+
165
+ if ( ! happyforms_is_preview() && ! $contains_rating ) {
166
+ return $deps;
167
+ }
168
+
169
+ wp_register_script(
170
+ 'happyforms-part-rating',
171
+ happyforms_get_plugin_url() . 'assets/js/frontend/rating.js',
172
+ array(), HAPPYFORMS_VERSION, true
173
+ );
174
+
175
+ $deps[] = 'happyforms-part-rating';
176
+
177
+ return $deps;
178
+ }
179
+
180
  }
inc/classes/parts/class-part-scale.php CHANGED
@@ -10,6 +10,7 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
10
 
11
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
12
  add_filter( 'happyforms_part_value', array( $this, 'part_value' ), 10, 2 );
 
13
  }
14
 
15
  /**
@@ -61,6 +62,18 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
61
  'default' => 100,
62
  'sanitize' => 'intval'
63
  ),
 
 
 
 
 
 
 
 
 
 
 
 
64
  'step' => array(
65
  'default' => 1,
66
  'sanitize' => 'sanitize_key'
@@ -108,26 +121,6 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
108
  include( happyforms_get_include_folder() . '/templates/parts/frontend-scale.php' );
109
  }
110
 
111
- /**
112
- * Get all possible messages definitions.
113
- *
114
- * @since 1.0.0.
115
- *
116
- * @return array Associative array, specifying message type and copy.
117
- */
118
- public function get_message_definitions() {
119
- return array(
120
- 'missing_required_field' => array(
121
- 'type' => 'error',
122
- 'message' => __( 'This field is required.', 'happyforms' ),
123
- ),
124
- 'not_a_number' => array(
125
- 'type' => 'error',
126
- 'message' => __( 'This field requires numeric value.', 'happyforms' ),
127
- )
128
- );
129
- }
130
-
131
  /**
132
  * Sanitize submitted value before storing it.
133
  *
@@ -142,7 +135,12 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
142
  $part_name = happyforms_get_part_name( $part_data, $form_data );
143
 
144
  if ( isset( $_REQUEST[$part_name] ) ) {
145
- $sanitized_value = sanitize_text_field( $_REQUEST[$part_name] );
 
 
 
 
 
146
  }
147
 
148
  return $sanitized_value;
@@ -153,19 +151,24 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
153
  *
154
  * @since 1.0.0.
155
  *
156
- * @param array $part_data Form part data.
157
  * @param string $value Submitted value.
158
  *
159
  * @return string|object
160
  */
161
- public function validate_value( $part_data, $value ) {
162
  $validated_value = $value;
163
 
164
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
165
- $validated_value = new WP_Error( 'missing_required_field' );
 
 
 
 
 
166
  }
167
 
168
- if ( !is_numeric( $validated_value ) ) {
169
  $validated_value = new WP_Error( 'not_a_number' );
170
  }
171
 
@@ -174,12 +177,32 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
174
 
175
  public function part_value( $value, $part ) {
176
  if ( $this->type === $part['type'] ) {
177
- $value = $part['default_value'];
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
  return $value;
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
183
  /**
184
  * Enqueue scripts in customizer area.
185
  *
@@ -212,10 +235,18 @@ class HappyForms_Part_Scale extends HappyForms_Form_Part {
212
  return $deps;
213
  }
214
 
 
 
 
 
 
 
 
 
215
  wp_register_script(
216
  'happyforms-part-scale',
217
  happyforms_get_plugin_url() . 'assets/js/frontend/scale.js',
218
- array(), HAPPYFORMS_VERSION, true
219
  );
220
 
221
  $deps[] = 'happyforms-part-scale';
10
 
11
  add_filter( 'happyforms_frontend_dependencies', array( $this, 'script_dependencies' ), 10, 2 );
12
  add_filter( 'happyforms_part_value', array( $this, 'part_value' ), 10, 2 );
13
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
14
  }
15
 
16
  /**
62
  'default' => 100,
63
  'sanitize' => 'intval'
64
  ),
65
+ 'multiple' => array(
66
+ 'default' => 0,
67
+ 'sanitize' => 'happyforms_sanitize_checkbox'
68
+ ),
69
+ 'default_range_from' => array(
70
+ 'default' => 0,
71
+ 'sanitize' => 'intval'
72
+ ),
73
+ 'default_range_to' => array(
74
+ 'default' => 50,
75
+ 'sanitize' => 'intval'
76
+ ),
77
  'step' => array(
78
  'default' => 1,
79
  'sanitize' => 'sanitize_key'
121
  include( happyforms_get_include_folder() . '/templates/parts/frontend-scale.php' );
122
  }
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  /**
125
  * Sanitize submitted value before storing it.
126
  *
135
  $part_name = happyforms_get_part_name( $part_data, $form_data );
136
 
137
  if ( isset( $_REQUEST[$part_name] ) ) {
138
+ if ( is_array( $_REQUEST[$part_name] ) && isset( $_REQUEST[$part_name][0] ) ) {
139
+ $array_value = explode( ',', $_REQUEST[$part_name][0] );
140
+ $sanitized_value = array_map( 'intval', $array_value );
141
+ } else {
142
+ $sanitized_value = intval( $_REQUEST[$part_name] );
143
+ }
144
  }
145
 
146
  return $sanitized_value;
151
  *
152
  * @since 1.0.0.
153
  *
154
+ * @param array $part Form part data.
155
  * @param string $value Submitted value.
156
  *
157
  * @return string|object
158
  */
159
+ public function validate_value( $value, $part = array(), $form = array() ) {
160
  $validated_value = $value;
161
 
162
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
163
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
164
+ }
165
+
166
+ // handle multiple range
167
+ if ( is_array( $validated_value ) && count( $validated_value ) !== count( array_filter( $validated_value, 'is_numeric' ) ) ) {
168
+ $validated_value = new WP_Error( 'not_a_number' );
169
  }
170
 
171
+ if ( ! is_array( $validated_value ) && ! is_numeric( $validated_value ) ) {
172
  $validated_value = new WP_Error( 'not_a_number' );
173
  }
174
 
177
 
178
  public function part_value( $value, $part ) {
179
  if ( $this->type === $part['type'] ) {
180
+ if ( ! empty( $value ) ) {
181
+ if ( is_array( $value ) ) {
182
+ $value = implode( ',', $value );
183
+ }
184
+ } else {
185
+ if ( 1 === intval( $part['multiple'] ) ) {
186
+ $value = $part['default_range_from'] . ',' . $part['default_range_to'];
187
+ } else {
188
+ $value = $part['default_value'];
189
+ }
190
+ }
191
  }
192
 
193
  return $value;
194
  }
195
 
196
+ public function html_part_class( $class, $part, $form ) {
197
+ if ( $this->type === $part['type'] ) {
198
+ if ( 1 === intval( $part['multiple'] ) ) {
199
+ $class[] = 'happyforms-part--scale-multiple';
200
+ }
201
+ }
202
+
203
+ return $class;
204
+ }
205
+
206
  /**
207
  * Enqueue scripts in customizer area.
208
  *
235
  return $deps;
236
  }
237
 
238
+ wp_register_script(
239
+ 'multirange-polyfill',
240
+ happyforms_get_plugin_url() . 'assets/js/lib/multirange.js',
241
+ '',
242
+ false,
243
+ true
244
+ );
245
+
246
  wp_register_script(
247
  'happyforms-part-scale',
248
  happyforms_get_plugin_url() . 'assets/js/frontend/scale.js',
249
+ array( 'multirange-polyfill' ), HAPPYFORMS_VERSION, true
250
  );
251
 
252
  $deps[] = 'happyforms-part-scale';
inc/classes/parts/class-part-select.php CHANGED
@@ -120,26 +120,6 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
120
  );
121
  }
122
 
123
- /**
124
- * Get all possible messages definitions.
125
- *
126
- * @since 1.0.0.
127
- *
128
- * @return array Associative array, specifying message type and copy.
129
- */
130
- public function get_message_definitions() {
131
- return array(
132
- 'missing_required_field' => array(
133
- 'type' => 'error',
134
- 'message' => __( 'This field is required.', 'happyforms' ),
135
- ),
136
- 'not_valid_value' => array(
137
- 'type' => 'error',
138
- 'message' => __( 'Select values are not valid.', 'happyforms' )
139
- )
140
- );
141
- }
142
-
143
  /**
144
  * Sanitize submitted value before storing it.
145
  *
@@ -165,22 +145,23 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
165
  *
166
  * @since 1.0.0.
167
  *
168
- * @param array $part_data Form part data.
169
  * @param string $value Submitted value.
170
  *
171
  * @return string|object
172
  */
173
- public function validate_value( $part_data, $value ) {
174
  $validated_value = $value;
175
 
176
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
177
- $validated_value = new WP_Error( 'missing_required_field' );
178
  }
179
 
180
- $allowed_values = wp_list_pluck( $part_data['options'], 'label' );
 
181
 
182
- if ( ! in_array( $value, $allowed_values ) ) {
183
- $validated_value = new WP_Error( 'not_valid_value' );
184
  }
185
 
186
  return $validated_value;
120
  );
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  /**
124
  * Sanitize submitted value before storing it.
125
  *
145
  *
146
  * @since 1.0.0.
147
  *
148
+ * @param array $part Form part data.
149
  * @param string $value Submitted value.
150
  *
151
  * @return string|object
152
  */
153
+ public function validate_value( $value, $part = array(), $form = array() ) {
154
  $validated_value = $value;
155
 
156
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
157
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
158
  }
159
 
160
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
161
+ $options = wp_list_pluck( $options, 'label' );
162
 
163
+ if ( ! in_array( $value, $options ) ) {
164
+ return new WP_Error( 'error', __( 'Select values are not valid.', 'happyforms' ) );
165
  }
166
 
167
  return $validated_value;
inc/classes/parts/class-part-single-line-text.php CHANGED
@@ -7,6 +7,8 @@ class HappyForms_Part_SingleLineText extends HappyForms_Form_Part {
7
  public function __construct() {
8
  $this->label = __( 'Short Text', 'happyforms' );
9
  $this->description = __( 'For single line text fields.', 'happyforms' );
 
 
10
  }
11
 
12
  /**
@@ -85,22 +87,6 @@ class HappyForms_Part_SingleLineText extends HappyForms_Form_Part {
85
  include( happyforms_get_include_folder() . '/templates/parts/frontend-single-line-text.php' );
86
  }
87
 
88
- /**
89
- * Get all possible messages definitions.
90
- *
91
- * @since 1.0.0.
92
- *
93
- * @return array Associative array, specifying message type and copy.
94
- */
95
- public function get_message_definitions() {
96
- return array(
97
- 'missing_required_field' => array(
98
- 'type' => 'error',
99
- 'message' => __( 'This field is required.', 'happyforms' ),
100
- ),
101
- );
102
- }
103
-
104
  /**
105
  * Sanitize submitted value before storing it.
106
  *
@@ -126,21 +112,31 @@ class HappyForms_Part_SingleLineText extends HappyForms_Form_Part {
126
  *
127
  * @since 1.0.0.
128
  *
129
- * @param array $part_data Form part data.
130
  * @param string $value Submitted value.
131
  *
132
  * @return string|object
133
  */
134
- public function validate_value( $part_data, $value ) {
135
  $validated_value = $value;
136
 
137
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
138
- $validated_value = new WP_Error( 'missing_required_field' );
139
  }
140
 
141
  return $validated_value;
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Enqueue scripts in customizer area.
146
  *
7
  public function __construct() {
8
  $this->label = __( 'Short Text', 'happyforms' );
9
  $this->description = __( 'For single line text fields.', 'happyforms' );
10
+
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  }
13
 
14
  /**
87
  include( happyforms_get_include_folder() . '/templates/parts/frontend-single-line-text.php' );
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  /**
91
  * Sanitize submitted value before storing it.
92
  *
112
  *
113
  * @since 1.0.0.
114
  *
115
+ * @param array $part Form part data.
116
  * @param string $value Submitted value.
117
  *
118
  * @return string|object
119
  */
120
+ public function validate_value( $value, $part = array(), $form = array() ) {
121
  $validated_value = $value;
122
 
123
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
124
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
125
  }
126
 
127
  return $validated_value;
128
  }
129
 
130
+ public function html_part_class( $class, $part, $form ) {
131
+ if ( $this->type === $part['type'] ) {
132
+ if ( happyforms_get_part_value( $part, $form ) ) {
133
+ $class[] = 'happyforms-part--filled';
134
+ }
135
+ }
136
+
137
+ return $class;
138
+ }
139
+
140
  /**
141
  * Enqueue scripts in customizer area.
142
  *
inc/classes/parts/class-part-title.php CHANGED
@@ -76,6 +76,7 @@ class HappyForms_Part_Title extends HappyForms_Form_Part {
76
  */
77
  public function frontend_template( $part_data = array(), $form_data = array() ) {
78
  $part = wp_parse_args( $part_data, $this->get_customize_defaults() );
 
79
  $form = $form_data;
80
 
81
  include( happyforms_get_include_folder() . '/templates/parts/frontend-title.php' );
@@ -90,12 +91,12 @@ class HappyForms_Part_Title extends HappyForms_Form_Part {
90
  */
91
  public function get_honorifics() {
92
  return array(
93
- __( 'Mr.', 'happyforms' ),
94
- __( 'Mrs.', 'happyforms' ),
95
- __( 'Ms.', 'happyforms' ),
96
- __( 'Miss', 'happyforms' ),
97
- __( 'Prof.', 'happyforms' ),
98
- __( 'Dr.', 'happyforms' )
99
  );
100
  }
101
 
@@ -116,26 +117,6 @@ class HappyForms_Part_Title extends HappyForms_Form_Part {
116
  );
117
  }
118
 
119
- /**
120
- * Get all possible messages definitions.
121
- *
122
- * @since 1.0.0.
123
- *
124
- * @return array Associative array, specifying message type and copy.
125
- */
126
- public function get_message_definitions() {
127
- return array(
128
- 'missing_required_field' => array(
129
- 'type' => 'error',
130
- 'message' => __( 'This field is required.', 'happyforms' ),
131
- ),
132
- 'not_valid_value' => array(
133
- 'type' => 'error',
134
- 'message' => __( 'Values is not valid.', 'happyforms' )
135
- )
136
- );
137
- }
138
-
139
  /**
140
  * Sanitize submitted value before storing it.
141
  *
@@ -161,24 +142,23 @@ class HappyForms_Part_Title extends HappyForms_Form_Part {
161
  *
162
  * @since 1.0.0.
163
  *
164
- * @param array $part_data Form part data.
165
  * @param string $value Submitted value.
166
  *
167
  * @return string|object
168
  */
169
- public function validate_value( $part_data, $value ) {
170
  $validated_value = $value;
171
 
172
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
173
- $validated_value = new WP_Error( 'missing_required_field' );
174
- return $validated_value;
175
  }
176
 
177
- $possible_options = $this->get_honorifics();
 
178
 
179
- if ( ! in_array( $validated_value, $possible_options ) ) {
180
- $validated_value = new WP_Error( 'not_valid_value' );
181
- return $validated_value;
182
  }
183
 
184
  return $validated_value;
76
  */
77
  public function frontend_template( $part_data = array(), $form_data = array() ) {
78
  $part = wp_parse_args( $part_data, $this->get_customize_defaults() );
79
+ $part['options'] = $this->get_honorifics();
80
  $form = $form_data;
81
 
82
  include( happyforms_get_include_folder() . '/templates/parts/frontend-title.php' );
91
  */
92
  public function get_honorifics() {
93
  return array(
94
+ array( 'id' => 'mr', 'label' => __( 'Mr.', 'happyforms' ) ),
95
+ array( 'id' => 'mrs', 'label' => __( 'Mrs.', 'happyforms' ) ),
96
+ array( 'id' => 'ms', 'label' => __( 'Ms.', 'happyforms' ) ),
97
+ array( 'id' => 'miss', 'label' => __( 'Miss', 'happyforms' ) ),
98
+ array( 'id' => 'prof', 'label' => __( 'Prof.', 'happyforms' ) ),
99
+ array( 'id' => 'dr', 'label' => __( 'Dr.', 'happyforms' ) ),
100
  );
101
  }
102
 
117
  );
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
  * Sanitize submitted value before storing it.
122
  *
142
  *
143
  * @since 1.0.0.
144
  *
145
+ * @param array $part Form part data.
146
  * @param string $value Submitted value.
147
  *
148
  * @return string|object
149
  */
150
+ public function validate_value( $value, $part = array(), $form = array() ) {
151
  $validated_value = $value;
152
 
153
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
154
+ return new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
 
155
  }
156
 
157
+ $options = happyforms_get_part_options( $this->get_honorifics(), $part, $form );
158
+ $options = wp_list_pluck( $options, 'label' );
159
 
160
+ if ( ! in_array( $validated_value, $options ) ) {
161
+ return new WP_Error( 'error', __( 'Values is not valid.', 'happyforms' ) );
 
162
  }
163
 
164
  return $validated_value;
inc/classes/parts/class-part-website-url.php CHANGED
@@ -7,6 +7,8 @@ class HappyForms_Part_WebsiteUrl extends HappyForms_Form_Part {
7
  public function __construct() {
8
  $this->label = __( 'Website Link', 'happyforms' );
9
  $this->description = __( 'For formatted website URLs.', 'happyforms' );
 
 
10
  }
11
 
12
  /**
@@ -85,26 +87,6 @@ class HappyForms_Part_WebsiteUrl extends HappyForms_Form_Part {
85
  include( happyforms_get_include_folder() . '/templates/parts/frontend-website-url.php' );
86
  }
87
 
88
- /**
89
- * Get all possible messages definitions.
90
- *
91
- * @since 1.0.0.
92
- *
93
- * @return array Associative array, specifying message type and copy.
94
- */
95
- public function get_message_definitions() {
96
- return array(
97
- 'missing_required_field' => array(
98
- 'type' => 'error',
99
- 'message' => __( 'This field is required.', 'happyforms' ),
100
- ),
101
- 'not_valid_url' => array(
102
- 'type' => 'error',
103
- 'message' => __( 'Not a valid URL.', 'happyforms' )
104
- )
105
- );
106
- }
107
-
108
  /**
109
  * Sanitize submitted value before storing it.
110
  *
@@ -130,27 +112,37 @@ class HappyForms_Part_WebsiteUrl extends HappyForms_Form_Part {
130
  *
131
  * @since 1.0.0.
132
  *
133
- * @param array $part_data Form part data.
134
  * @param string $value Submitted value.
135
  *
136
  * @return string|object
137
  */
138
- public function validate_value( $part_data, $value ) {
139
  $validated_value = $value;
140
 
141
- if ( 1 === $part_data['required'] && empty( $validated_value ) ) {
142
- $validated_value = new WP_Error( 'missing_required_field' );
143
  return $validated_value;
144
  }
145
 
146
- if ( '' === esc_url_raw( $validated_value ) || ! wp_parse_url( $validated_value ) ) {
147
- $validated_value = new WP_Error( 'not_valid_url' );
148
  return $validated_value;
149
  }
150
 
151
  return $validated_value;
152
  }
153
 
 
 
 
 
 
 
 
 
 
 
154
  /**
155
  * Enqueue scripts in customizer area.
156
  *
7
  public function __construct() {
8
  $this->label = __( 'Website Link', 'happyforms' );
9
  $this->description = __( 'For formatted website URLs.', 'happyforms' );
10
+
11
+ add_filter( 'happyforms_part_class', array( $this, 'html_part_class' ), 10, 3 );
12
  }
13
 
14
  /**
87
  include( happyforms_get_include_folder() . '/templates/parts/frontend-website-url.php' );
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  /**
91
  * Sanitize submitted value before storing it.
92
  *
112
  *
113
  * @since 1.0.0.
114
  *
115
+ * @param array $part Form part data.
116
  * @param string $value Submitted value.
117
  *
118
  * @return string|object
119
  */
120
+ public function validate_value( $value, $part = array(), $form = array() ) {
121
  $validated_value = $value;
122
 
123
+ if ( 1 === $part['required'] && empty( $validated_value ) ) {
124
+ $validated_value = new WP_Error( 'error', __( 'This field is required.', 'happyforms' ) );
125
  return $validated_value;
126
  }
127
 
128
+ if ( '' === esc_url_raw( $validated_value ) || ! wp_http_validate_url( $validated_value ) ) {
129
+ $validated_value = new WP_Error( 'error', __( 'Not a valid URL.', 'happyforms' ) );
130
  return $validated_value;
131
  }
132
 
133
  return $validated_value;
134
  }
135
 
136
+ public function html_part_class( $class, $part, $form ) {
137
+ if ( $this->type === $part['type'] ) {
138
+ if ( happyforms_get_part_value( $part, $form ) ) {
139
+ $class[] = 'happyforms-part--filled';
140
+ }
141
+ }
142
+
143
+ return $class;
144
+ }
145
+
146
  /**
147
  * Enqueue scripts in customizer area.
148
  *
inc/helpers/helper-activation.php CHANGED
@@ -20,17 +20,13 @@ function happyforms_first_run() {
20
  $tracking = happyforms_get_tracking();
21
  $status = $tracking->get_status();
22
 
23
- if ( 0 < $status['status'] ) {
24
- // Immediately register our custom post type
25
- // and force a permalinks refresh
26
- happyforms_get_form_controller()->register_post_type();
27
- flush_rewrite_rules();
28
-
29
  return;
30
  }
31
 
32
  require_once( happyforms_get_include_folder() . '/classes/class-form-part-library.php' );
33
  require_once( happyforms_get_include_folder() . '/classes/class-form-styles.php' );
 
34
  require_once( happyforms_get_include_folder() . '/classes/class-message-controller.php' );
35
  require_once( happyforms_get_include_folder() . '/helpers/helper-form-templates.php' );
36
  require_once( happyforms_get_include_folder() . '/helpers/helper-validation.php' );
20
  $tracking = happyforms_get_tracking();
21
  $status = $tracking->get_status();
22
 
23
+ if ( 0 < intval( $status['status'] ) ) {
 
 
 
 
 
24
  return;
25
  }
26
 
27
  require_once( happyforms_get_include_folder() . '/classes/class-form-part-library.php' );
28
  require_once( happyforms_get_include_folder() . '/classes/class-form-styles.php' );
29
+ require_once( happyforms_get_include_folder() . '/classes/class-session.php' );
30
  require_once( happyforms_get_include_folder() . '/classes/class-message-controller.php' );
31
  require_once( happyforms_get_include_folder() . '/helpers/helper-form-templates.php' );
32
  require_once( happyforms_get_include_folder() . '/helpers/helper-validation.php' );
inc/helpers/helper-form-templates.php CHANGED
@@ -11,8 +11,7 @@ if ( ! function_exists( 'happyforms_form_field' ) ):
11
  * @return void
12
  */
13
  function happyforms_form_field( $id ) {
14
- $parameter = happyforms_get_message_controller()->submit_parameter;
15
- ?>
16
  <input type="hidden" name="<?php echo esc_attr( $parameter ); ?>" value="<?php echo esc_attr( $id ); ?>" />
17
  <?php
18
  }
@@ -28,40 +27,13 @@ if ( ! function_exists( 'happyforms_action_field' ) ):
28
  * @return void
29
  */
30
  function happyforms_action_field() {
31
- $action = happyforms_get_message_controller()->submit_action;
32
- ?>
33
  <input type="hidden" name="action" value="<?php echo esc_attr( $action ); ?>">
34
  <?php
35
  }
36
 
37
  endif;
38
 
39
- if ( ! function_exists( 'happyforms_redirect_field' ) ):
40
- /**
41
- * Output a hidden field with the location to
42
- * redirect to after the form has been submitted.
43
- *
44
- * @since 1.0
45
- *
46
- * @param array $form_data Current form data.
47
- *
48
- * @return void
49
- */
50
- function happyforms_redirect_field( $form_data ) {
51
- global $post;
52
-
53
- $redirect = get_permalink( $post->ID );
54
-
55
- if ( ! empty( $form_data['redirect_url'] ) ) {
56
- $redirect = $form_data['redirect_url'];
57
- }
58
- ?>
59
- <input type="hidden" name="happyforms_redirect" value="<?php echo esc_attr( $redirect ); ?>">
60
- <?php
61
- }
62
-
63
- endif;
64
-
65
  if ( ! function_exists( 'happyforms_nonce_field' ) ):
66
  /**
67
  * Output the nonce field for the current form.
@@ -88,11 +60,9 @@ if ( ! function_exists( 'happyforms_honeypot' ) ) :
88
  function happyforms_honeypot( $form ) {
89
  $controller = happyforms_get_form_controller();
90
 
91
- if ( $controller->has_spam_protection( $form ) ) :
92
- ?>
93
  <input type="checkbox" name="<?php echo $form['ID']; ?>single_line_text_-1" value="1" style="display: none;" tabindex="-1" autocomplete="off">
94
- <?php
95
- endif;
96
  }
97
 
98
  endif;
@@ -124,13 +94,12 @@ if ( ! function_exists( 'happyforms_message_notices' ) ):
124
  *
125
  * @since 1.0
126
  *
127
- * @param array $form Current form data.
128
  * @param string $location The notice location to display.
129
  *
130
  * @return void
131
  */
132
- function happyforms_message_notices( $form, $location = 'top' ) {
133
- $notices = happyforms_get_message_notices()->get_messages( $form, $location );
134
 
135
  if ( ! empty( $notices ) ) : ?>
136
  <div class="happyforms-message-notices">
@@ -270,8 +239,9 @@ if ( ! function_exists( 'happyforms_get_part_value' ) ):
270
  *
271
  * @return string
272
  */
273
- function happyforms_get_part_value( $part, $form, $component = '' ) {
274
- $value = '';
 
275
 
276
  /**
277
  * Filter the default submission value for this form part.
@@ -302,7 +272,7 @@ if ( ! function_exists( 'happyforms_the_part_value' ) ):
302
  *
303
  * @return void
304
  */
305
- function happyforms_the_part_value( $part, $form, $component = '' ) {
306
  echo esc_attr( happyforms_get_part_value( $part, $form, $component ) );
307
  }
308
 
@@ -695,10 +665,46 @@ function happyforms_the_part_label( $part, $form ) {
695
 
696
  endif;
697
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
  if ( ! function_exists( 'happyforms_recaptcha' ) ) :
699
 
700
  function happyforms_recaptcha( $form ) {
701
- if ( $form['captcha'] ): ?>
 
702
  <div class="happyforms-form__part happyforms-part happyforms-part--recaptcha" data-sitekey="<?php echo $form['captcha_site_key']; ?>" data-happyforms-type="recaptcha">
703
  <div class="happyforms-part-wrap" id="happyforms-<?php echo $form['ID']; ?>-recaptcha">
704
  </div>
@@ -717,3 +723,47 @@ function happyforms_geolocation_link( $part ) {
717
  }
718
 
719
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  * @return void
12
  */
13
  function happyforms_form_field( $id ) {
14
+ $parameter = happyforms_get_message_controller()->submit_parameter; ?>
 
15
  <input type="hidden" name="<?php echo esc_attr( $parameter ); ?>" value="<?php echo esc_attr( $id ); ?>" />
16
  <?php
17
  }
27
  * @return void
28
  */
29
  function happyforms_action_field() {
30
+ $action = happyforms_get_message_controller()->submit_action; ?>
 
31
  <input type="hidden" name="action" value="<?php echo esc_attr( $action ); ?>">
32
  <?php
33
  }
34
 
35
  endif;
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  if ( ! function_exists( 'happyforms_nonce_field' ) ):
38
  /**
39
  * Output the nonce field for the current form.
60
  function happyforms_honeypot( $form ) {
61
  $controller = happyforms_get_form_controller();
62
 
63
+ if ( $controller->has_spam_protection( $form ) ) : ?>
 
64
  <input type="checkbox" name="<?php echo $form['ID']; ?>single_line_text_-1" value="1" style="display: none;" tabindex="-1" autocomplete="off">
65
+ <?php endif;
 
66
  }
67
 
68
  endif;
94
  *
95
  * @since 1.0
96
  *
 
97
  * @param string $location The notice location to display.
98
  *
99
  * @return void
100
  */
101
+ function happyforms_message_notices( $location = '' ) {
102
+ $notices = happyforms_get_session()->get_messages( $location );
103
 
104
  if ( ! empty( $notices ) ) : ?>
105
  <div class="happyforms-message-notices">
239
  *
240
  * @return string
241
  */
242
+ function happyforms_get_part_value( $part, $form, $component = false ) {
243
+ $part_name = happyforms_get_part_name( $part, $form );
244
+ $value = happyforms_get_session()->get_value( $part_name );
245
 
246
  /**
247
  * Filter the default submission value for this form part.
272
  *
273
  * @return void
274
  */
275
+ function happyforms_the_part_value( $part, $form, $component = false ) {
276
  echo esc_attr( happyforms_get_part_value( $part, $form, $component ) );
277
  }
278
 
665
 
666
  endif;
667
 
668
+ if ( ! function_exists( 'happyforms_the_part_confirmation_label' ) ) :
669
+ /**
670
+ * Output a part confirmation label
671
+ *
672
+ * @since 1.3
673
+ *
674
+ * @param string $id Current part id.
675
+ * @param array $part Current part data.
676
+ * @param array $form Current form data.
677
+ *
678
+ * @return void
679
+ */
680
+ function happyforms_the_part_confirmation_label( $part, $form ) {
681
+ ?>
682
+ <label for="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__label happyforms-part__label--confirmation">
683
+ <span class="label"><?php echo esc_html( $part['confirmation_field_label'] ); ?></span>
684
+ <?php if ( 1 === intval( $part['required'] ) ) : ?>
685
+ <span class="happyforms-required"><?php echo happyforms_get_form_property( $form, 'hf_style_required_text' ); ?></span>
686
+ <?php endif; ?>
687
+ </label>
688
+ <?php
689
+ }
690
+
691
+ endif;
692
+
693
+ if ( ! function_exists( 'happyforms_get_part_options' ) ) :
694
+
695
+ function happyforms_get_part_options( $options, $part, $form ) {
696
+ $options = apply_filters( 'happyforms_part_options', $options, $part, $form );
697
+
698
+ return $options;
699
+ }
700
+
701
+ endif;
702
+
703
  if ( ! function_exists( 'happyforms_recaptcha' ) ) :
704
 
705
  function happyforms_recaptcha( $form ) {
706
+ $has_captcha = apply_filters( 'happyforms_form_has_captcha', false, $form );
707
+ if ( $has_captcha ): ?>
708
  <div class="happyforms-form__part happyforms-part happyforms-part--recaptcha" data-sitekey="<?php echo $form['captcha_site_key']; ?>" data-happyforms-type="recaptcha">
709
  <div class="happyforms-part-wrap" id="happyforms-<?php echo $form['ID']; ?>-recaptcha">
710
  </div>
723
  }
724
 
725
  endif;
726
+
727
+
728
+ if ( ! function_exists( 'happyforms_get_months' ) ) :
729
+
730
+ function happyforms_get_months() {
731
+ $months = array(
732
+ 1 => __( 'January', 'happyforms' ),
733
+ 2 => __( 'February', 'happyforms' ),
734
+ 3 => __( 'March', 'happyforms' ),
735
+ 4 => __( 'April', 'happyforms' ),
736
+ 5 => __( 'May', 'happyforms' ),
737
+ 6 => __( 'June', 'happyforms' ),
738
+ 7 => __( 'July', 'happyforms' ),
739
+ 8 => __( 'August', 'happyforms' ),
740
+ 9 => __( 'September', 'happyforms' ),
741
+ 10 => __( 'October', 'happyforms' ),
742
+ 11 => __( 'November', 'happyforms' ),
743
+ 12 => __( 'December', 'happyforms' )
744
+ );
745
+
746
+ $months = apply_filters( 'happyforms_get_months', $months );
747
+
748
+ return $months;
749
+ }
750
+
751
+ endif;
752
+
753
+
754
+ if ( ! function_exists( 'happyforms_get_site_date_format' ) ) :
755
+
756
+ function happyforms_get_site_date_format() {
757
+ $site_date_format = get_option( 'date_format' );
758
+
759
+ $format = 'day_first';
760
+
761
+ if ( 0 === strpos( $site_date_format, 'F' ) || 0 === strpos( $site_date_format, 'm' ) ||
762
+ 0 === strpos( $site_date_format, 'M' ) || 0 === strpos( $site_date_format, 'n' ) ) {
763
+ $format = 'month_first';
764
+ }
765
+
766
+ return apply_filters( 'happyforms_date_part_format', $format );
767
+ }
768
+
769
+ endif;
inc/helpers/helper-misc.php CHANGED
@@ -57,6 +57,7 @@ function happyforms_get_message_part_value( $value ) {
57
  }
58
 
59
  if ( is_array( $value ) ) {
 
60
  $value = implode( ', ', $value );
61
  }
62
 
@@ -67,6 +68,27 @@ function happyforms_get_message_part_value( $value ) {
67
 
68
  endif;
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  if ( ! function_exists( 'happyforms_customizer_url' ) ):
71
  /**
72
  * Get a formatted url for the Customize screen,
57
  }
58
 
59
  if ( is_array( $value ) ) {
60
+ $value = array_filter( array_values( $value ) );
61
  $value = implode( ', ', $value );
62
  }
63
 
68
 
69
  endif;
70
 
71
+ if ( ! function_exists( 'happyforms_stringify_part_value' ) ):
72
+ /**
73
+ * Transforms a part value into a string.
74
+ *
75
+ * @since 1.0
76
+ *
77
+ * @param mixed $value The original submission value.
78
+ * @param array $part Current part data.
79
+ * @param array $form Current form data.
80
+ *
81
+ * @return string
82
+ */
83
+ function happyforms_stringify_part_value( $value, $part, $form ) {
84
+ $value = apply_filters( 'happyforms_stringify_part_value', $value, $part, $form );
85
+ $value = maybe_serialize( $value );
86
+
87
+ return $value;
88
+ }
89
+
90
+ endif;
91
+
92
  if ( ! function_exists( 'happyforms_customizer_url' ) ):
93
  /**
94
  * Get a formatted url for the Customize screen,
inc/templates/admin-message-edit.php CHANGED
@@ -7,12 +7,18 @@ if ( ! $form ) {
7
  ?>
8
  <table class="form-table happyforms-message-data-table">
9
  <tbody>
10
- <?php $index = 0; foreach ( $message['parts'] as $part_id => $part_value ): ?>
11
- <tr <?php if ($index % 2 == 0) : ?>class="alternate"<?php endif; ?>>
12
- <th scope="row"><?php echo esc_html( $form['parts'][$index]['label'] ); ?></th>
 
 
 
 
 
 
13
  <td><?php echo happyforms_get_message_part_value( $part_value ); ?></td>
14
  </tr>
15
- <?php $index ++; endforeach; ?>
16
  </tbody>
17
  </table>
18
  <p class="happyforms-message-nav">
7
  ?>
8
  <table class="form-table happyforms-message-data-table">
9
  <tbody>
10
+ <?php foreach ( $form['parts'] as $p => $part ):
11
+ $part_value = $message['parts'][$part['id']];
12
+ $visible = apply_filters( 'happyforms_message_part_visible', true, $part );
13
+
14
+ if ( ! $visible ) {
15
+ continue;
16
+ } ?>
17
+ <tr <?php if ($p % 2 == 0) : ?>class="alternate"<?php endif; ?>>
18
+ <th scope="row"><?php echo esc_html( $part['label'] ); ?></th>
19
  <td><?php echo happyforms_get_message_part_value( $part_value ); ?></td>
20
  </tr>
21
+ <?php endforeach; ?>
22
  </tbody>
23
  </table>
24
  <p class="happyforms-message-nav">
inc/templates/customize-form-setup.php CHANGED
@@ -1,36 +1,36 @@
1
  <script type="text/template" id="happyforms-form-setup-template">
2
  <div class="happyforms-stack-view">
3
  <div class="customize-control">
4
- <label for="" class="customize-control-title"><?php _e( 'Your email address', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="email_recipient"></i></label>
5
- <input type="text" value="<%= email_recipient %>" data-attribute="email_recipient" data-pointer-target />
6
  </div>
7
  <div class="customize-control">
8
- <label for="" class="customize-control-title"><?php _e( 'Message alert email subject', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="alert_email_subject"></i></label>
9
- <input type="text" value="<%= alert_email_subject %>" data-attribute="alert_email_subject" data-pointer-target />
10
  </div>
11
  <div class="customize-control">
12
- <label for="" class="customize-control-title"><?php _e( 'Confirmation message', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_message"></i></label>
13
  <div data-pointer-target>
14
  <textarea name="" id="happyforms-confirmation-message" cols="34" rows="3" data-attribute="confirmation_message"><%= confirmation_message %></textarea>
15
  </div>
16
  </div>
17
  <div class="customize-control">
18
- <label for="" class="customize-control-title"><?php _e( 'Confirmation email subject', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_email_subject"></i></label>
19
- <input type="text" value="<%= confirmation_email_subject %>" data-attribute="confirmation_email_subject" data-pointer-target />
20
  </div>
21
  <div class="customize-control">
22
- <label for="" class="customize-control-title"><?php _e( 'Confirmation email content', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_email_content"></i></label>
23
  <div data-pointer-target>
24
  <textarea name="" id="happyforms-confirmation-email-content" cols="34" rows="3" data-attribute="confirmation_email_content"><%= confirmation_email_content %></textarea>
25
  </div>
26
  </div>
27
  <div class="customize-control">
28
- <label for="" class="customize-control-title"><?php _e( 'On complete redirect link', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="redirect_url"></i></label>
29
- <input type="text" value="<%= redirect_url %>" data-attribute="redirect_url" data-pointer-target />
30
  </div>
31
  <div class="customize-control">
32
- <label for="" class="customize-control-title"><?php _e( 'Submit button text', 'happyforms' ); ?></label>
33
- <input type="text" value="<%= submit_button_label %>" data-attribute="submit_button_label" data-preview-selector=".happyforms-button--submit" data-pointer-target />
34
  </div>
35
  <div class="customize-control customize-control-checkbox">
36
  <div class="customize-inside-control-row" data-pointer-target>
@@ -45,12 +45,12 @@
45
  </div>
46
  <div id="happyforms-captcha-settings" <% if ( captcha ) { %>style="display: block;"<% } %>>
47
  <p>
48
- <label for="" class="customize-control-title"><?php _e( 'ReCaptcha site key', 'happyforms' ); ?></label>
49
- <input type="text" value="<%= captcha_site_key %>" data-attribute="captcha_site_key" />
50
  </p>
51
  <p>
52
- <label for="" class="customize-control-title"><?php _e( 'ReCaptcha secret key', 'happyforms' ); ?></label>
53
- <input type="text" value="<%= captcha_secret_key %>" data-attribute="captcha_secret_key" />
54
  </p>
55
  </div>
56
  </div>
1
  <script type="text/template" id="happyforms-form-setup-template">
2
  <div class="happyforms-stack-view">
3
  <div class="customize-control">
4
+ <label for="form_email_recipient" class="customize-control-title"><?php _e( 'Your email address', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="email_recipient"></i></label>
5
+ <input type="text" id="form_email_recipient" value="<%= email_recipient %>" data-attribute="email_recipient" data-pointer-target />
6
  </div>
7
  <div class="customize-control">
8
+ <label for="form_alert_email_subject" class="customize-control-title"><?php _e( 'Message alert email subject', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="alert_email_subject"></i></label>
9
+ <input type="text" id="form_alert_email_subject" value="<%= alert_email_subject %>" data-attribute="alert_email_subject" data-pointer-target />
10
  </div>
11
  <div class="customize-control">
12
+ <label for="happyforms-confirmation-message" class="customize-control-title"><?php _e( 'Confirmation message', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_message"></i></label>
13
  <div data-pointer-target>
14
  <textarea name="" id="happyforms-confirmation-message" cols="34" rows="3" data-attribute="confirmation_message"><%= confirmation_message %></textarea>
15
  </div>
16
  </div>
17
  <div class="customize-control">
18
+ <label for="form_confirmation_email_subject" class="customize-control-title"><?php _e( 'Confirmation email subject', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_email_subject"></i></label>
19
+ <input type="text" id="form_confirmation_email_subject" value="<%= confirmation_email_subject %>" data-attribute="confirmation_email_subject" data-pointer-target />
20
  </div>
21
  <div class="customize-control">
22
+ <label for="happyforms-confirmation-email-content" class="customize-control-title"><?php _e( 'Confirmation email content', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="confirmation_email_content"></i></label>
23
  <div data-pointer-target>
24
  <textarea name="" id="happyforms-confirmation-email-content" cols="34" rows="3" data-attribute="confirmation_email_content"><%= confirmation_email_content %></textarea>
25
  </div>
26
  </div>
27
  <div class="customize-control">
28
+ <label for="form_redirect_url" class="customize-control-title"><?php _e( 'On complete redirect link', 'happyforms' ); ?> <i class="fa fa-question-circle" aria-hidden="true" data-pointer="redirect_url"></i></label>
29
+ <input type="text" id="form_redirect_url" value="<%= redirect_url %>" data-attribute="redirect_url" data-pointer-target />
30
  </div>
31
  <div class="customize-control">
32
+ <label for="form_submit_button_label" class="customize-control-title"><?php _e( 'Submit button text', 'happyforms' ); ?></label>
33
+ <input type="text" id="form_submit_button_label" value="<%= submit_button_label %>" data-attribute="submit_button_label" data-pointer-target />
34
  </div>
35
  <div class="customize-control customize-control-checkbox">
36
  <div class="customize-inside-control-row" data-pointer-target>
45
  </div>
46
  <div id="happyforms-captcha-settings" <% if ( captcha ) { %>style="display: block;"<% } %>>
47
  <p>
48
+ <label for="form_captcha_site_key" class="customize-control-title"><?php _e( 'ReCaptcha site key', 'happyforms' ); ?></label>
49
+ <input type="text" id="form_captcha_site_key" value="<%= captcha_site_key %>" data-attribute="captcha_site_key" />
50
  </p>
51
  <p>
52
+ <label for="form_captcha_secret_key" class="customize-control-title"><?php _e( 'ReCaptcha secret key', 'happyforms' ); ?></label>
53
+ <input type="text" id="form_captcha_secret_key" value="<%= captcha_secret_key %>" data-attribute="captcha_secret_key" />
54
  </p>
55
  </div>
56
  </div>
inc/templates/parts/customize-date.php CHANGED
@@ -47,16 +47,31 @@
47
  </label>
48
  </p>
49
  <div class="happyforms-part-advanced-settings-wrap">
 
 
 
 
 
 
 
 
50
  <div class="date-options happyforms-customize-controls-wrap--side-by-side"<%= (instance.date_type == 'time') ? ' style="display: none"' : '' %>>
51
  <p>
52
- <label for="<%= instance.id %>min_year"><?php _e( 'Min year', 'happyforms' ); ?></label>
53
- <input type="number" id="<%= instance.id %>min_year" data-bind="min_year" value="<%= instance.min_year %>">
54
  </p>
55
  <p>
56
- <label for="<%= instance.id %>_max_year"><?php _e( 'Max year', 'happyforms' ); ?></label>
57
  <input type="number" id="<%= instance.id %>_max_year" data-bind="max_year" min="<%= instance.min_year %>" max="<?php echo date( 'Y' ) + 2; ?>" value="<%= instance.max_year %>">
58
  </p>
59
  </div>
 
 
 
 
 
 
 
60
  <div class="time-options happyforms-customize-controls-wrap--side-by-side"<%= (instance.date_type == 'date') ? ' style="display: none"' : '' %>>
61
  <p>
62
  <label for="<%= instance.id %>_min_hour"><?php _e( 'Min hour', 'happyforms' ); ?></label>
47
  </label>
48
  </p>
49
  <div class="happyforms-part-advanced-settings-wrap">
50
+ <p class="date-options" style="margin-bottom: 0<%= (instance.date_type == 'time') ? '; display: none' : '' %>">
51
+ <label for="<%= instance.id %>_years_option"><?php _e( 'Show', 'happyforms' ); ?></label>
52
+ <select id="<%= instance.id %>_years_option" name="years_option" data-bind="years_option" class="widefat">
53
+ <option value="all"<%= (instance.years_option == 'all') ? ' selected' : '' %>><?php _e( 'All years', 'happyforms' ); ?></option>
54
+ <option value="past"<%= (instance.years_option == 'past') ? ' selected' : '' %>><?php _e( 'Past years only', 'happyforms' ); ?></option>
55
+ <option value="future"<%= (instance.years_option == 'future') ? ' selected' : '' %>><?php _e( 'Future years only', 'happyforms' ); ?></option>
56
+ </select>
57
+ </p>
58
  <div class="date-options happyforms-customize-controls-wrap--side-by-side"<%= (instance.date_type == 'time') ? ' style="display: none"' : '' %>>
59
  <p>
60
+ <label for="<%= instance.id %>_min_year"><?php _e( 'Start from', 'happyforms' ); ?></label>
61
+ <input type="number" id="<%= instance.id %>_min_year" data-bind="min_year" value="<%= instance.min_year %>">
62
  </p>
63
  <p>
64
+ <label for="<%= instance.id %>_max_year"><?php _e( 'End at', 'happyforms' ); ?></label>
65
  <input type="number" id="<%= instance.id %>_max_year" data-bind="max_year" min="<%= instance.min_year %>" max="<?php echo date( 'Y' ) + 2; ?>" value="<%= instance.max_year %>">
66
  </p>
67
  </div>
68
+ <p class="date-options" style="margin-top: 0;<%= (instance.date_type == 'time') ? ' display: none' : '' %>">
69
+ <label for="<%= instance.id %>_years_order"><?php _e( 'Years order', 'happyforms' ); ?></label>
70
+ <select id="<%= instance.id %>_years_order" name="years_order" data-bind="years_order" class="widefat">
71
+ <option value="desc"<%= (instance.years_order == 'desc') ? ' selected' : '' %>>DESC</option>
72
+ <option value="asc"<%= (instance.years_order == 'asc') ? ' selected' : '' %>>ASC</option>
73
+ </select>
74
+ </p>
75
  <div class="time-options happyforms-customize-controls-wrap--side-by-side"<%= (instance.date_type == 'date') ? ' style="display: none"' : '' %>>
76
  <p>
77
  <label for="<%= instance.id %>_min_hour"><?php _e( 'Min hour', 'happyforms' ); ?></label>
inc/templates/parts/customize-phone.php CHANGED
@@ -47,14 +47,12 @@
47
  <p>
48
  <label for="<%= instance.id %>_mask_phone_country"><?php _e( 'Pre-format phone number region', 'happyforms' ); ?></label>
49
  <select id="<%= instance.id %>_mask_phone_country" class="widefat title" data-bind="mask_phone_country">
50
- <option value="">- <?php _e( 'Select', 'happyforms' ); ?> -</option>
51
- <?php
52
- $phone_countries = $this->get_phone_countries_array();
53
 
54
- foreach ( $phone_countries as $country_code => $country ) {
55
- echo '<option value="'. $country['code'] .'"<% if (instance.mask_phone_country == "'. $country['code'] .'") { %> selected<% } %>>'. ucwords( strtolower( $country['name'] ) ) .'</option>';
56
- }
57
- ?>
58
  </select>
59
  </p>
60
  </div>
47
  <p>
48
  <label for="<%= instance.id %>_mask_phone_country"><?php _e( 'Pre-format phone number region', 'happyforms' ); ?></label>
49
  <select id="<%= instance.id %>_mask_phone_country" class="widefat title" data-bind="mask_phone_country">
50
+ <?php
51
+ $phone_countries = $this->get_phone_countries_array();
 
52
 
53
+ foreach ( $phone_countries as $country_code => $country ) : ?>
54
+ <option value="<?php echo esc_attr( $country['code'] ); ?>"<% if (instance.mask_phone_country == "'. $country['code'] .'") { %> selected<% } %>><?php echo ucwords( strtolower( $country['name'] ) ); ?></option>
55
+ <?php endforeach; ?>
 
56
  </select>
57
  </p>
58
  </div>
inc/templates/parts/customize-scale.php CHANGED
@@ -26,17 +26,13 @@
26
  <input type="checkbox" class="checkbox" value="1" <% if ( instance.tooltip_description ) { %>checked="checked"<% } %> data-bind="tooltip_description" /> <?php _e( 'Show description in a tooltip', 'happyforms' ); ?>
27
  </label>
28
  </p>
29
- <p>
30
- <label for="<%= instance.id %>_default_value"><?php _e( 'Default value', 'happyforms' ); ?></label>
31
- <input type="text" id="<%= instance.id %>_default_value" class="widefat title" value="<%= instance.default_value %>" data-bind="default_value" />
32
- </p>
33
  <div class="happyforms-customize-controls-wrap--side-by-side">
34
  <p>
35
- <label for="<%= instance.id %>_max_value"><?php _e( 'Minimum accepted value', 'happyforms' ); ?></label>
36
  <input type="text" id="<%= instance.id %>_max_value" class="widefat title" value="<%= instance.min_value %>" data-bind="min_value" />
37
  </p>
38
  <p>
39
- <label for="<%= instance.id %>_max_value"><?php _e( 'Maximum accepted value', 'happyforms' ); ?></label>
40
  <input type="text" id="<%= instance.id %>_max_value" class="widefat title" value="<%= instance.max_value %>" data-bind="max_value" />
41
  </p>
42
  </div>
@@ -46,6 +42,25 @@
46
  </label>
47
  </p>
48
  <div class="happyforms-part-advanced-settings-wrap">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  <div class="happyforms-customize-controls-wrap--side-by-side">
50
  <p>
51
  <label for="<%= instance.id %>_min_label"><?php _e( 'Minimum value label', 'happyforms' ); ?></label>
@@ -83,4 +98,4 @@
83
  </p>
84
  </div>
85
  <?php include( happyforms_get_include_folder() . '/templates/customize-form-part-footer.php' ); ?>
86
- </script>
26
  <input type="checkbox" class="checkbox" value="1" <% if ( instance.tooltip_description ) { %>checked="checked"<% } %> data-bind="tooltip_description" /> <?php _e( 'Show description in a tooltip', 'happyforms' ); ?>
27
  </label>
28
  </p>
 
 
 
 
29
  <div class="happyforms-customize-controls-wrap--side-by-side">
30
  <p>
31
+ <label for="<%= instance.id %>_max_value"><?php _e( 'Minimum value', 'happyforms' ); ?></label>
32
  <input type="text" id="<%= instance.id %>_max_value" class="widefat title" value="<%= instance.min_value %>" data-bind="min_value" />
33
  </p>
34
  <p>
35
+ <label for="<%= instance.id %>_max_value"><?php _e( 'Maximum value', 'happyforms' ); ?></label>
36
  <input type="text" id="<%= instance.id %>_max_value" class="widefat title" value="<%= instance.max_value %>" data-bind="max_value" />
37
  </p>
38
  </div>
42
  </label>
43
  </p>
44
  <div class="happyforms-part-advanced-settings-wrap">
45
+ <p>
46
+ <label>
47
+ <input type="checkbox" class="checkbox" value="1" <% if ( instance.multiple ) { %>checked="checked"<% } %> data-bind="multiple" /> <?php _e( 'Allow range select', 'happyforms' ); ?>
48
+ </label>
49
+ </p>
50
+ <div class="happyforms-customize-controls-wrap--side-by-side scale-multiple-options" style="display: <%= ( instance.multiple ) ? 'flex' : 'none' %>">
51
+ <p>
52
+ <label for="<%= instance.id %>_default_range_from"><?php _e( 'Default range from', 'happyforms' ); ?></label>
53
+ <input type="text" id="<%= instance.id %>_default_range_from" class="widefat title" value="<%= instance.default_range_from %>" data-bind="default_range_from" />
54
+ </p>
55
+ <p>
56
+ <label for="<%= instance.id %>_default_range_to"><?php _e( 'Default range to', 'happyforms' ); ?></label>
57
+ <input type="text" id="<%= instance.id %>_default_range_to" class="widefat title" value="<%= instance.default_range_to %>" data-bind="default_range_to" />
58
+ </p>
59
+ </div>
60
+ <p class="scale-single-options" style="display: <%= ( instance.multiple ) ? 'none' : 'block' %>">
61
+ <label for="<%= instance.id %>_default_value"><?php _e( 'Default value', 'happyforms' ); ?></label>
62
+ <input type="text" id="<%= instance.id %>_default_value" class="widefat title" value="<%= instance.default_value %>" data-bind="default_value" />
63
+ </p>
64
  <div class="happyforms-customize-controls-wrap--side-by-side">
65
  <p>
66
  <label for="<%= instance.id %>_min_label"><?php _e( 'Minimum value label', 'happyforms' ); ?></label>
98
  </p>
99
  </div>
100
  <?php include( happyforms_get_include_folder() . '/templates/customize-form-part-footer.php' ); ?>
101
+ </script>
inc/templates/parts/frontend-address.php CHANGED
@@ -4,13 +4,13 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <?php if ( 'simple' === $part['mode'] ) : ?>
10
  <div class="happyforms-part-el-wrap">
11
  <div class="happyforms-part__el">
12
  <div class="happyforms-part__dummy-input">
13
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>[full]" class="address-full" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
14
  <?php happyforms_geolocation_link( $part ); ?>
15
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
16
  <?php happyforms_the_part_label( $part, $form ); ?>
@@ -22,7 +22,7 @@
22
  <div class="happyforms-part-el-wrap">
23
  <div class="happyforms-part__el">
24
  <div class="happyforms-part__dummy-input">
25
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>[full]" class="happyforms-part--address__autocomplete address-full" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> autocomplete="off" />
26
  <?php happyforms_geolocation_link( $part ); ?>
27
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
28
  <?php happyforms_the_part_label( $part, $form ); ?>
@@ -60,7 +60,7 @@
60
  <?php endif; ?>
61
  <?php happyforms_print_part_description( $part ); ?>
62
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
63
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
64
  <?php endif; ?>
65
  </div>
66
  </div>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <?php if ( 'simple' === $part['mode'] ) : ?>
10
  <div class="happyforms-part-el-wrap">
11
  <div class="happyforms-part__el">
12
  <div class="happyforms-part__dummy-input">
13
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>[full]" class="address-full" type="text" value="<?php happyforms_the_part_value( $part, $form, 'full' ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
14
  <?php happyforms_geolocation_link( $part ); ?>
15
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
16
  <?php happyforms_the_part_label( $part, $form ); ?>
22
  <div class="happyforms-part-el-wrap">
23
  <div class="happyforms-part__el">
24
  <div class="happyforms-part__dummy-input">
25
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>[full]" class="happyforms-part--address__autocomplete address-full" type="text" value="<?php happyforms_the_part_value( $part, $form, 'full' ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> autocomplete="off" />
26
  <?php happyforms_geolocation_link( $part ); ?>
27
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
28
  <?php happyforms_the_part_label( $part, $form ); ?>
60
  <?php endif; ?>
61
  <?php happyforms_print_part_description( $part ); ?>
62
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
63
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
64
  <?php endif; ?>
65
  </div>
66
  </div>
inc/templates/parts/frontend-checkbox.php CHANGED
@@ -2,13 +2,17 @@
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__el">
8
- <?php foreach( $part['options'] as $option ) : ?>
 
 
9
  <?php
10
- $checked = checked( $option['is_default'], 1, false );
11
- $checked = $checked ? $checked : checked( happyforms_get_part_value( $part, $form, $option['label'] ), $option['label'], false );
 
 
12
  ?>
13
  <label class="option-label" id="<?php echo esc_attr( $option['id'] ); ?>">
14
  <input type="checkbox" class="happyforms-visuallyhidden" name="<?php happyforms_the_part_name( $part, $form ); ?>[]" value="<?php echo esc_attr( $option['label'] ); ?>" <?php echo $checked; ?>>
@@ -19,7 +23,7 @@
19
  </div>
20
  <?php happyforms_print_part_description( $part ); ?>
21
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
22
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
23
  <?php endif; ?>
24
  </div>
25
  </div>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__el">
8
+ <?php
9
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
10
+ foreach( $options as $option ) : ?>
11
  <?php
12
+ $value = happyforms_get_part_value( $part, $form );
13
+ $is_default = ( 1 === intval( $option['is_default'] ) );
14
+ $is_checked = ( is_array( $value ) && in_array( $option['label'], $value ) );
15
+ $checked = ( $is_default || $is_checked ) ? 'checked="checked"' : true;
16
  ?>
17
  <label class="option-label" id="<?php echo esc_attr( $option['id'] ); ?>">
18
  <input type="checkbox" class="happyforms-visuallyhidden" name="<?php happyforms_the_part_name( $part, $form ); ?>[]" value="<?php echo esc_attr( $option['label'] ); ?>" <?php echo $checked; ?>>
23
  </div>
24
  <?php happyforms_print_part_description( $part ); ?>
25
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
26
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
27
  <?php endif; ?>
28
  </div>
29
  </div>
inc/templates/parts/frontend-date-day.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $day_value = ( 'current' === $part['default_datetime'] ) ? date( 'j' ) : intval( happyforms_get_part_value( $part, $form, 'day' ) ); ?>
2
+ <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
3
+ <div class="happyforms-part__select-bg">
4
+ <select name="<?php happyforms_the_part_name( $part, $form ); ?>[day]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
5
+ <option value=""><?php _e( 'Day', 'happyforms' ); ?></option>
6
+ <?php for ( $i = 1; $i <= 31; $i++ ) : ?>
7
+ <option value="<?php echo $i; ?>" <?php selected( $day_value, $i ); ?>><?php echo $i; ?></option>
8
+ <?php endfor; ?>
9
+ </select>
10
+ </div>
11
+ </div>
inc/templates/parts/frontend-date-month.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $month_value = ( 'current' === $part['default_datetime'] ) ? date( 'n' ) : intval( happyforms_get_part_value( $part, $form, 'month' ) ); ?>
2
+ <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
3
+ <div class="happyforms-part__select-bg">
4
+ <select name="<?php happyforms_the_part_name( $part, $form ); ?>[month]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
5
+ <option value=""><?php _e( 'Month', 'happyforms' ); ?></option>
6
+ <?php $months = happyforms_get_months(); ?>
7
+ <?php for ( $i = 1; $i <= 12; $i++ ) : ?>
8
+ <option value="<?php echo $i; ?>" <?php selected( $month_value, $i ); ?>><?php echo $months[$i]; ?></option>
9
+ <?php endfor; ?>
10
+ </select>
11
+ </div>
12
+ </div>
inc/templates/parts/frontend-date.php CHANGED
@@ -5,59 +5,59 @@
5
  <?php happyforms_the_part_label( $part, $form ); ?>
6
  <?php endif; ?>
7
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
8
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
9
  <?php endif; ?>
10
  <div class="happyforms-part__el">
11
  <?php if ( $part['date_type'] === 'datetime' || $part['date_type'] === 'date' ) : ?>
12
- <?php $month_value = ( 'current' === $part['default_datetime'] ) ? date( 'n' ) : happyforms_get_part_value( $part, $form, 'month' ); ?>
13
- <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
14
- <div class="happyforms-part__select-bg">
15
- <select name="<?php happyforms_the_part_name( $part, $form ); ?>[month]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
16
- <option value=""><?php _e( 'Month', 'happyforms' ); ?></option>
17
- <?php for ( $i = 1; $i <= 12; $i++ ) : ?>
18
- <option value="<?php echo $i; ?>" <?php selected( $month_value, $i ); ?>><?php echo date( 'F', mktime( 0, 0, 0, $i) ); ?></option>
19
- <?php endfor; ?>
20
- </select>
21
- </div>
22
- </div>
23
- <?php $day_value = ( 'current' === $part['default_datetime'] ) ? date( 'j' ) : happyforms_get_part_value( $part, $form, 'day' ); ?>
24
- <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
25
- <div class="happyforms-part__select-bg">
26
- <select name="<?php happyforms_the_part_name( $part, $form ); ?>[day]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
27
- <option value=""><?php _e( 'Day', 'happyforms' ); ?></option>
28
- <?php for ( $i = 1; $i <= 31; $i++ ) : ?>
29
- <option value="<?php echo $i; ?>" <?php selected( $day_value, $i ); ?>><?php echo $i; ?></option>
30
- <?php endfor; ?>
31
- </select>
32
- </div>
33
- </div>
34
- <?php $year_value = ( 'current' === $part['default_datetime'] ) ? date( 'Y', $current_timestamp ) : happyforms_get_part_value( $part, $form, 'year' ); ?>
35
  <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
36
  <div class="happyforms-part__select-bg">
37
  <select name="<?php happyforms_the_part_name( $part, $form ); ?>[year]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
38
  <option value=""><?php _e( 'Year', 'happyforms' ); ?></option>
39
  <?php
 
40
  $min_year = $part['min_year'];
41
  $max_year = ( $part['max_year'] > $min_year ) ? $part['max_year'] : date('Y');
42
 
43
- for ( $i = $max_year; $i >= $min_year; $i-- ) : ?>
44
- <option value="<?php echo $i; ?>" <?php selected( $year_value, $i ); ?>><?php echo $i; ?></option>
45
- <?php endfor; ?>
 
 
 
 
 
 
 
 
 
46
  </select>
47
  </div>
48
  </div>
49
  <?php endif; ?>
50
  <?php if ( $part['date_type'] === 'datetime' || $part['date_type'] === 'time' ) : ?>
51
- <?php
52
  if ( 12 === $part['time_format'] ) {
53
  $hour_pattern = '(0[0-9]|1[0-2])';
54
  $hour_date_string = 'h';
 
55
  } else {
56
  $hour_pattern = '(0[0-9]|1[0-9]|2[0-3])';
57
  $hour_date_string = 'H';
 
58
  }
59
 
60
- $hour_value = ( 'current' === $part['default_datetime'] ) ? date( $hour_date_string, $current_timestamp ) : '';
 
61
  ?>
62
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--hours">
63
  <input type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>[hour]" min="<?php echo $part['min_hour']; ?>" max="<?php echo $part['max_hour']; ?>" maxlength="2" pattern="<?php echo $hour_pattern; ?>" autocomplete="off" value="<?php echo $hour_value; ?>"<?php if ( 1 == $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
@@ -67,8 +67,9 @@
67
  <div class="happyforms-part--date__time-separator">
68
  <span>:</span>
69
  </div>
70
- <?php
71
- $minute_value = ( 'current' === $part['default_datetime'] ) ? date( 'i', $current_timestamp ) : '';
 
72
  ?>
73
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--minutes">
74
  <input type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>[minute]" min="0" max="59" step="<?php echo $part['minute_step']; ?>" maxlength="2" pattern="([0-5][0-9])" autocomplete="off" value="<?php echo $minute_value; ?>"<?php if ( 1 == $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
@@ -76,10 +77,13 @@
76
  <span class="happyforms-spinner-arrow happyforms-spinner-arrow--down"></span>
77
  </div>
78
  <?php if ( 12 == intval( $part['time_format'] ) ) : ?>
79
- <?php $period_value = ( 'current' === $part['default_datetime'] ) ? date( 'A', $current_timestamp ) : happyforms_get_part_value( $part, $form, 'period' ); ?>
 
 
80
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--period happyforms-part__select-wrap">
81
  <div class="happyforms-part__select-bg">
82
  <select name="<?php happyforms_the_part_name( $part, $form ); ?>[period]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
 
83
  <option value="AM" <?php selected( $period_value, 'AM' ); ?>><?php _e( 'AM', 'happyforms' ); ?></option>
84
  <option value="PM" <?php selected( $period_value, 'PM' ); ?>><?php _e( 'PM', 'happyforms' ); ?></option>
85
  </select>
@@ -93,7 +97,7 @@
93
  <?php endif; ?>
94
  <?php happyforms_print_part_description( $part ); ?>
95
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
96
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
97
  <?php endif; ?>
98
  </div>
99
  </div>
5
  <?php happyforms_the_part_label( $part, $form ); ?>
6
  <?php endif; ?>
7
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
8
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
9
  <?php endif; ?>
10
  <div class="happyforms-part__el">
11
  <?php if ( $part['date_type'] === 'datetime' || $part['date_type'] === 'date' ) : ?>
12
+ <?php
13
+ if ( 'month_first' === happyforms_get_site_date_format() ) {
14
+ require( 'frontend-date-month.php' );
15
+ require( 'frontend-date-day.php' );
16
+ } else {
17
+ require( 'frontend-date-day.php' );
18
+ require( 'frontend-date-month.php' );
19
+ }
20
+ ?>
21
+ <?php $year_value = ( 'current' === $part['default_datetime'] ) ? date( 'Y', $current_timestamp ) : intval( happyforms_get_part_value( $part, $form, 'year' ) ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  <div class="happyforms-part-date__date-input happyforms-part__select-wrap">
23
  <div class="happyforms-part__select-bg">
24
  <select name="<?php happyforms_the_part_name( $part, $form ); ?>[year]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
25
  <option value=""><?php _e( 'Year', 'happyforms' ); ?></option>
26
  <?php
27
+ $order = ( isset( $part['years_order'] ) ) ? $part['years_order'] : 'desc';
28
  $min_year = $part['min_year'];
29
  $max_year = ( $part['max_year'] > $min_year ) ? $part['max_year'] : date('Y');
30
 
31
+ $option_template = '<option value="%d" %s>%d</option>';
32
+
33
+ if ( 'desc' === $order ) {
34
+ for ( $i = $max_year; $i >= $min_year; $i-- ) {
35
+ printf( $option_template, $i, selected( $year_value, $i ), $i );
36
+ }
37
+ } else {
38
+ for ( $i = $min_year; $i <= $max_year; $i++ ) {
39
+ printf( $option_template, $i, selected( $year_value, $i ), $i );
40
+ }
41
+ }
42
+ ?>
43
  </select>
44
  </div>
45
  </div>
46
  <?php endif; ?>
47
  <?php if ( $part['date_type'] === 'datetime' || $part['date_type'] === 'time' ) : ?>
48
+ <?php
49
  if ( 12 === $part['time_format'] ) {
50
  $hour_pattern = '(0[0-9]|1[0-2])';
51
  $hour_date_string = 'h';
52
+ $default_hour = '12';
53
  } else {
54
  $hour_pattern = '(0[0-9]|1[0-9]|2[0-3])';
55
  $hour_date_string = 'H';
56
+ $default_hour = '00';
57
  }
58
 
59
+ $happyforms_hour_value = ( happyforms_get_part_value( $part, $form, 'hour' ) ) ? happyforms_get_part_value( $part, $form, 'hour' ) : $default_hour;
60
+ $hour_value = ( 'current' === $part['default_datetime'] ) ? date( $hour_date_string, $current_timestamp ) : $happyforms_hour_value;
61
  ?>
62
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--hours">
63
  <input type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>[hour]" min="<?php echo $part['min_hour']; ?>" max="<?php echo $part['max_hour']; ?>" maxlength="2" pattern="<?php echo $hour_pattern; ?>" autocomplete="off" value="<?php echo $hour_value; ?>"<?php if ( 1 == $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
67
  <div class="happyforms-part--date__time-separator">
68
  <span>:</span>
69
  </div>
70
+ <?php
71
+ $happyforms_minute_value = ( happyforms_get_part_value( $part, $form, 'minute' ) ) ? happyforms_get_part_value( $part, $form, 'minute' ) : '00';
72
+ $minute_value = ( 'current' === $part['default_datetime'] ) ? date( 'i', $current_timestamp ) : $happyforms_minute_value;
73
  ?>
74
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--minutes">
75
  <input type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>[minute]" min="0" max="59" step="<?php echo $part['minute_step']; ?>" maxlength="2" pattern="([0-5][0-9])" autocomplete="off" value="<?php echo $minute_value; ?>"<?php if ( 1 == $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
77
  <span class="happyforms-spinner-arrow happyforms-spinner-arrow--down"></span>
78
  </div>
79
  <?php if ( 12 == intval( $part['time_format'] ) ) : ?>
80
+ <?php
81
+ $happyforms_period_value = ( happyforms_get_part_value( $part, $form, 'period' ) ) ? happyforms_get_part_value( $part, $form, 'period' ) : 'AM';
82
+ $period_value = ( 'current' === $part['default_datetime'] ) ? date( 'A', $current_timestamp ) : $happyforms_period_value; ?>
83
  <div class="happyforms-part--date__input-wrap happyforms-part-date__time-input happyforms-part-date__time-input--period happyforms-part__select-wrap">
84
  <div class="happyforms-part__select-bg">
85
  <select name="<?php happyforms_the_part_name( $part, $form ); ?>[period]"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
86
+ <option value=""><?php _e( 'Period', 'happyforms' ); ?></option>
87
  <option value="AM" <?php selected( $period_value, 'AM' ); ?>><?php _e( 'AM', 'happyforms' ); ?></option>
88
  <option value="PM" <?php selected( $period_value, 'PM' ); ?>><?php _e( 'PM', 'happyforms' ); ?></option>
89
  </select>
97
  <?php endif; ?>
98
  <?php happyforms_print_part_description( $part ); ?>
99
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
100
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
101
  <?php endif; ?>
102
  </div>
103
  </div>
inc/templates/parts/frontend-email.php CHANGED
@@ -4,36 +4,25 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
- <input type="email" id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php happyforms_the_part_value( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
11
  <?php happyforms_the_part_label( $part, $form ); ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
19
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
20
- <div class="happyforms-message-notices" style="display: none">
21
- <div class="happyforms-message-notice error">
22
- <h2><?php _e( 'Fields do not match.', 'happyforms' ); ?></h2>
23
- </div>
24
- </div>
25
  <?php if ( 'as_placeholder' !== $part['label_placement'] ) : ?>
26
- <label for="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__label happyforms-part__label--confirmation">
27
- <span class="label"><?php echo esc_html( $part['confirmation_field_label'] ); ?></span>
28
- <span class="happyforms-required"><?php echo happyforms_get_form_property( $form, 'hf_style_required_text' ); ?></span>
29
- </label>
30
  <?php endif; ?>
31
- <input type="email" id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" class="happyforms-part__el happyforms-part__el--text-input happyforms-confirmation-input" data-confirmation-of="<?php echo esc_attr( $part['id'] ); ?>" <?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?> />
32
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
33
- <label for="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__label happyforms-part__label--confirmation">
34
- <span class="label"><?php echo esc_html( $part['confirmation_field_label'] ); ?></span>
35
- <span class="happyforms-required"><?php echo happyforms_get_form_property( $form, 'hf_style_required_text' ); ?></span>
36
- </label>
37
  <?php endif; ?>
38
  </div>
39
  <?php endif; ?>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
+ <input type="email" id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php happyforms_the_part_value( $part, $form, 0 ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
11
  <?php happyforms_the_part_label( $part, $form ); ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
19
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
 
 
 
 
 
20
  <?php if ( 'as_placeholder' !== $part['label_placement'] ) : ?>
21
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
 
 
 
22
  <?php endif; ?>
23
+ <input type="email" id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" value="<?php happyforms_the_part_value( $part, $form, 1 ); ?>" class="happyforms-part__el happyforms-part__el--text-input happyforms-confirmation-input" data-confirmation-of="<?php echo esc_attr( $part['id'] ); ?>" <?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?> />
24
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
25
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
 
 
 
26
  <?php endif; ?>
27
  </div>
28
  <?php endif; ?>
inc/templates/parts/frontend-legal.php CHANGED
@@ -6,5 +6,5 @@
6
  </label>
7
  </div>
8
  </div>
9
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
10
  </div>
6
  </label>
7
  </div>
8
  </div>
9
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
10
  </div>
inc/templates/parts/frontend-multi-line-text.php CHANGED
@@ -4,7 +4,7 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <textarea id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input" name="<?php happyforms_the_part_name( $part, $form ); ?>" rows="5" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>><?php happyforms_the_part_value( $part, $form ); ?></textarea>
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
@@ -12,7 +12,7 @@
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <textarea id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input" name="<?php happyforms_the_part_name( $part, $form ); ?>" rows="5" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>><?php happyforms_the_part_value( $part, $form ); ?></textarea>
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
inc/templates/parts/frontend-number.php CHANGED
@@ -4,38 +4,33 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <?php if ( ! $part['masked'] ) : ?>
10
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input" type="number" value="<?php happyforms_the_part_value( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php echo esc_attr( $part['min_value'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
11
  <?php else: ?>
12
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input happyforms-masked-input" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
13
  <?php endif; ?>
14
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
15
  <?php happyforms_the_part_label( $part, $form ); ?>
16
  <?php endif; ?>
17
  <?php happyforms_print_part_description( $part ); ?>
18
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
19
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
20
  <?php endif; ?>
21
  </div>
22
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
23
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
24
- <div class="happyforms-message-notices" style="display: none">
25
- <div class="happyforms-message-notice error">
26
- <h2><?php _e( 'Fields do not match.', 'happyforms' ); ?></h2>
27
- </div>
28
- </div>
29
- <label for="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__label happyforms-part__label--confirmation">
30
- <span class="label"><?php echo esc_html( $part['confirmation_field_label'] ); ?></span>
31
- <?php if ( 1 === intval( $part['required'] ) ) : ?>
32
- <span class="happyforms-required"><?php echo happyforms_get_form_property( $form, 'hf_style_required_text' ); ?></span>
33
- <?php endif; ?>
34
- </label>
35
  <?php if ( ! $part['masked'] ) : ?>
36
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__el happyforms-part__el--text-input happyforms-confirmation-input" type="number" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php echo esc_attr( $part['min_value'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
37
  <?php else: ?>
38
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__el happyforms-part__el--text-input happyforms-masked-input happyforms-confirmation-input" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
 
 
 
39
  <?php endif; ?>
40
  </div>
41
  <?php endif; ?>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <?php if ( ! $part['masked'] ) : ?>
10
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input" type="number" value="<?php happyforms_the_part_value( $part, $form, 0 ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php echo esc_attr( $part['min_value'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
11
  <?php else: ?>
12
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>" class="happyforms-part__el happyforms-part__el--text-input happyforms-masked-input" type="text" value="<?php happyforms_the_part_value( $part, $form, 0 ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
13
  <?php endif; ?>
14
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
15
  <?php happyforms_the_part_label( $part, $form ); ?>
16
  <?php endif; ?>
17
  <?php happyforms_print_part_description( $part ); ?>
18
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
19
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
20
  <?php endif; ?>
21
  </div>
22
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
23
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
24
+ <?php if ( 'as_placeholder' !== $part['label_placement'] ) : ?>
25
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
26
+ <?php endif; ?>
 
 
 
 
 
 
 
 
27
  <?php if ( ! $part['masked'] ) : ?>
28
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__el happyforms-part__el--text-input happyforms-confirmation-input" type="number" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" value="<?php happyforms_the_part_value( $part, $form, 1 ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php echo esc_attr( $part['min_value'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
29
  <?php else: ?>
30
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__el happyforms-part__el--text-input happyforms-masked-input happyforms-confirmation-input" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" value="<?php happyforms_the_part_value( $part, $form, 1 ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
31
+ <?php endif; ?>
32
+ <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
33
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
34
  <?php endif; ?>
35
  </div>
36
  <?php endif; ?>
inc/templates/parts/frontend-phone.php CHANGED
@@ -4,31 +4,26 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
11
  <?php happyforms_the_part_label( $part, $form ); ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
19
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
20
- <div class="happyforms-message-notices" style="display: none">
21
- <div class="happyforms-message-notice error">
22
- <h2><?php _e( 'Fields do not match.', 'happyforms' ); ?></h2>
23
- </div>
24
- </div>
25
- <label for="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" class="happyforms-part__label happyforms-part__label--confirmation">
26
- <span class="label"><?php echo esc_html( $part['confirmation_field_label'] ); ?></span>
27
- <?php if ( 1 === intval( $part['required'] ) ) : ?>
28
- <span class="happyforms-required"><?php echo happyforms_get_form_property( $form, 'hf_style_required_text' ); ?></span>
29
- <?php endif; ?>
30
- </label>
31
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" class="happyforms-confirmation-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
32
  </div>
33
  <?php endif; ?>
34
  </div>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" value="<?php happyforms_the_part_value( $part, $form, 0 ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
11
  <?php happyforms_the_part_label( $part, $form ); ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  <?php if ( 1 === intval( $part['confirmation_field'] ) ) : ?>
19
  <div class="happyforms-part-wrap happyforms-part-wrap--confirmation" id="<?php happyforms_the_part_id( $part, $form ); ?>-part_confirmation">
20
+ <?php if ( 'as_placeholder' !== $part['label_placement'] ) : ?>
21
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
22
+ <?php endif; ?>
23
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>_confirmation" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>_confirmation" value="<?php happyforms_the_part_value( $part, $form, 1 ); ?>" class="happyforms-confirmation-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
24
+ <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
25
+ <?php happyforms_the_part_confirmation_label( $part, $form ); ?>
26
+ <?php endif; ?>
 
 
 
 
 
27
  </div>
28
  <?php endif; ?>
29
  </div>
inc/templates/parts/frontend-placeholder.php CHANGED
@@ -1,6 +1,6 @@
1
  <div class="<?php happyforms_the_part_class( $part, $form ); ?>" id="<?php happyforms_the_part_id( $part, $form ); ?>-part" <?php happyforms_the_part_data_attributes( $part, $form ); ?>>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
- <div class="happyforms-part__el"><?php echo $part['placeholder_text']; ?></div>
5
  </div>
6
  </div>
1
  <div class="<?php happyforms_the_part_class( $part, $form ); ?>" id="<?php happyforms_the_part_id( $part, $form ); ?>-part" <?php happyforms_the_part_data_attributes( $part, $form ); ?>>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
+ <div class="happyforms-part__el"><?php echo html_entity_decode( $part['placeholder_text'] ); ?></div>
5
  </div>
6
  </div>
inc/templates/parts/frontend-radio.php CHANGED
@@ -2,13 +2,15 @@
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__el">
8
- <?php foreach( $part['options'] as $option ) : ?>
 
 
9
  <?php
10
  $checked = checked( $option['is_default'], 1, false );
11
- $checked = $checked ? $checked : checked( happyforms_get_part_value( $part, $form, $option['label'] ), $option['label'], false );
12
  ?>
13
  <div class="happyforms-part__option happyforms-part-option" id="<?php echo esc_attr( $option['id'] ); ?>">
14
  <label class="option-label">
@@ -23,7 +25,7 @@
23
  </div>
24
  <?php happyforms_print_part_description( $part ); ?>
25
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
26
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
27
  <?php endif; ?>
28
  </div>
29
  </div>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__el">
8
+ <?php
9
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
10
+ foreach( $options as $option ) : ?>
11
  <?php
12
  $checked = checked( $option['is_default'], 1, false );
13
+ $checked = $checked ? $checked : checked( happyforms_get_part_value( $part, $form ), $option['label'], false );
14
  ?>
15
  <div class="happyforms-part__option happyforms-part-option" id="<?php echo esc_attr( $option['id'] ); ?>">
16
  <label class="option-label">
25
  </div>
26
  <?php happyforms_print_part_description( $part ); ?>
27
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
28
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
29
  <?php endif; ?>
30
  </div>
31
  </div>
inc/templates/parts/frontend-rating.php CHANGED
@@ -13,6 +13,6 @@
13
  <?php } ?>
14
  </div>
15
  <?php happyforms_print_part_description( $part ); ?>
16
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
17
  </div>
18
  </div>
13
  <?php } ?>
14
  </div>
15
  <?php happyforms_print_part_description( $part ); ?>
16
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
17
  </div>
18
  </div>
inc/templates/parts/frontend-scale.php CHANGED
@@ -2,21 +2,35 @@
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
- <div class="happyforms-part--scale__labels">
8
- <span class="label-min"><?php echo $part['min_label']; ?></span>
9
- <span class="label-max"><?php echo $part['max_label']; ?></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </div>
11
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="range" name="<?php happyforms_the_part_name( $part, $form ); ?>" step="<?php echo esc_attr( $part['step'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input"
12
- <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?>
13
- min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php happyforms_the_part_value( $part, $form ); ?>" />
14
- <?php happyforms_print_part_description( $part ); ?>
15
- <output for="<?php happyforms_the_part_id( $part, $form ); ?>">
16
- <span><?php echo $part['default_value']; ?></span>
17
- </output>
18
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
19
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
20
  <?php endif; ?>
21
  </div>
22
  </div>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
+ <?php
8
+ $part_name = happyforms_get_part_name( $part, $form );
9
+
10
+ if ( 1 === intval( $part['multiple'] ) ) {
11
+ $part_name = $part_name . '[]';
12
+ }
13
+ ?>
14
+ <div class="happyforms-part--scale__inputwrap">
15
+ <div class="happyforms-part--scale__labels">
16
+ <span class="label-min"><?php echo $part['min_label']; ?></span>
17
+ <span class="label-max"><?php echo $part['max_label']; ?></span>
18
+ </div>
19
+ <input id="<?php happyforms_the_part_id( $part, $form ); ?>"<?php if ( 1 === intval( $part['multiple'] ) ) : ?> multiple<?php endif; ?> type="range" name="<?php echo $part_name; ?>" step="<?php echo esc_attr( $part['step'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input"
20
+ <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?>
21
+ min="<?php echo esc_attr( $part['min_value'] ); ?>" max="<?php echo esc_attr( $part['max_value'] ); ?>" value="<?php happyforms_the_part_value( $part, $form ); ?>" />
22
+ <?php happyforms_print_part_description( $part ); ?>
23
+ <output for="<?php happyforms_the_part_id( $part, $form ); ?>">
24
+ <span><?php happyforms_the_part_value( $part, $form ); ?></span>
25
+ </output>
26
+ <?php if ( 1 === intval( $part['multiple'] ) ) : ?>
27
+ <output for="<?php happyforms_the_part_id( $part, $form ); ?>_clone">
28
+ <span><?php happyforms_the_part_value( $part, $form ); ?></span>
29
+ </output>
30
+ <?php endif; ?>
31
  </div>
 
 
 
 
 
 
 
32
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
33
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
34
  <?php endif; ?>
35
  </div>
36
  </div>
inc/templates/parts/frontend-select.php CHANGED
@@ -2,15 +2,17 @@
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__select-wrap">
8
  <div class="happyforms-part__select-bg">
9
  <select id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" class="happyforms-part__el"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
10
- <?php foreach( $part['options'] as $option ) : ?>
11
  <?php
12
- $selected = selected( $option['is_default'], 1, false );
13
- $selected = $selected ? $selected : selected( happyforms_get_part_value( $part, $form, $option['label'] ), $option['label'], false );
 
 
14
  ?>
15
  <option id="<?php echo esc_attr( $option['id'] ); ?>" value="<?php echo esc_attr( $option['label'] ); ?>" <?php echo $selected; ?>><?php echo esc_attr( $option['label'] ); ?></option>
16
  <?php endforeach; ?>
@@ -19,7 +21,7 @@
19
  </div>
20
  <?php happyforms_print_part_description( $part ); ?>
21
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
22
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
23
  <?php endif; ?>
24
  </div>
25
  </div>
2
  <div class="happyforms-part-wrap">
3
  <?php happyforms_the_part_label( $part, $form ); ?>
4
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
5
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
6
  <?php endif; ?>
7
  <div class="happyforms-part__select-wrap">
8
  <div class="happyforms-part__select-bg">
9
  <select id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" class="happyforms-part__el"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
10
+ <option value="">- <?php _e( 'Select', 'happyforms' ); ?> -</option>
11
  <?php
12
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
13
+ foreach( $options as $option ) :
14
+ $selected = selected( $option['is_default'], 1, false );
15
+ $selected = $selected ? $selected : selected( happyforms_get_part_value( $part, $form ), $option['label'], false );
16
  ?>
17
  <option id="<?php echo esc_attr( $option['id'] ); ?>" value="<?php echo esc_attr( $option['label'] ); ?>" <?php echo $selected; ?>><?php echo esc_attr( $option['label'] ); ?></option>
18
  <?php endforeach; ?>
21
  </div>
22
  <?php happyforms_print_part_description( $part ); ?>
23
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
24
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
25
  <?php endif; ?>
26
  </div>
27
  </div>
inc/templates/parts/frontend-single-line-text.php CHANGED
@@ -4,7 +4,7 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php happyforms_the_part_value( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
@@ -12,7 +12,7 @@
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php happyforms_the_part_value( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
inc/templates/parts/frontend-title.php CHANGED
@@ -5,13 +5,15 @@
5
  <div class="happyforms-part__select-bg">
6
  <select id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" class="happyforms-part__el"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
7
  <option value="">- <?php _e( 'Select', 'happyforms' ); ?> -</option>
8
- <?php $honorifics = $this->get_honorifics(); foreach ( $honorifics as $title ) : ?>
9
- <option value="<?php echo $title; ?>" <?php selected( happyforms_get_part_value( $part, $form ), $title ); ?>><?php echo $title; ?></option>
 
 
10
  <?php endforeach; ?>
11
  </select>
12
  </div>
13
  </div>
14
  <?php happyforms_print_part_description( $part ); ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  </div>
17
  </div>
5
  <div class="happyforms-part__select-bg">
6
  <select id="<?php happyforms_the_part_id( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" class="happyforms-part__el"<?php if ( 1 === $part['required'] ) : ?> required aria-required="true"<?php endif; ?>>
7
  <option value="">- <?php _e( 'Select', 'happyforms' ); ?> -</option>
8
+ <?php
9
+ $options = happyforms_get_part_options( $part['options'], $part, $form );
10
+ foreach( $options as $option ) : ?>
11
+ <option value="<?php echo $option['label']; ?>" <?php selected( happyforms_get_part_value( $part, $form ), $option['label'] ); ?>><?php echo $option['label']; ?></option>
12
  <?php endforeach; ?>
13
  </select>
14
  </div>
15
  </div>
16
  <?php happyforms_print_part_description( $part ); ?>
17
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
18
  </div>
19
  </div>
inc/templates/parts/frontend-website-url.php CHANGED
@@ -4,7 +4,7 @@
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
@@ -12,7 +12,7 @@
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
- <?php happyforms_message_notices( $form, happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
4
  <?php happyforms_the_part_label( $part, $form ); ?>
5
  <?php endif; ?>
6
  <?php if ( 'happyforms-form--part-error-notices-above' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) : ?>
7
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
8
  <?php endif; ?>
9
  <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" value="<?php happyforms_the_part_value( $part, $form ); ?>" name="<?php happyforms_the_part_name( $part, $form ); ?>" placeholder="<?php echo esc_attr( $part['placeholder'] ); ?>" class="happyforms-part__el happyforms-part__el--text-input" <?php if ( 1 === $part['required'] ) : ?>required aria-required="true"<?php endif; ?> />
10
  <?php if ( 'as_placeholder' === $part['label_placement'] ) : ?>
12
  <?php endif; ?>
13
  <?php happyforms_print_part_description( $part ); ?>
14
  <?php if ( 'happyforms-form--part-error-notices-below' === happyforms_get_form_property( $form, 'part_error_notices_location' ) || ( '' === happyforms_get_form_property( $form, 'part_error_notices_location' ) ) ) : ?>
15
+ <?php happyforms_message_notices( happyforms_get_part_name( $part, $form ) ); ?>
16
  <?php endif; ?>
17
  </div>
18
  </div>
inc/templates/preview-form-edit.php CHANGED
@@ -1,41 +1,19 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <title><?php wp_title(); ?></title>
6
- <?php wp_head(); ?>
7
- </head>
8
- <body class="happyforms-preview">
9
-
10
  <div id="message" class="updated published notice notice-success">
11
  <p><?php printf( __( 'This is a preview of your new HappyForm. Once you’ve finished building, you can add this form to any Page, Post and Widget area. Have questions? <a href="%s" class="happyforms-ask-link" target="_blank">Ask for help in our support forums.</a>', 'happyforms' ), 'https://wordpress.org/support/plugin/happyforms' ); ?></p>
12
  </div>
13
 
14
- <?php
15
- function happyforms_the_form_title_preview( $title ) {
16
- $before = '<div class="happyforms-block-editable happyforms-block-editable--title">';
17
- $after = '</div>';
18
- $title = "{$before}{$title}{$after}";
19
-
20
- return $title;
21
- }
22
-
23
- function happyforms_part_class_preview( $classes ) {
24
- $classes[] = 'happyforms-block-editable happyforms-block-editable--part';
25
-
26
- return $classes;
27
- }
28
-
29
- add_filter( 'happyforms_the_form_title', 'happyforms_the_form_title_preview' );
30
- add_filter( 'happyforms_part_class', 'happyforms_part_class_preview' );
31
- ?>
32
-
33
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); global $post; ?>
34
- <?php $form = happyforms_get_form_controller()->get( $post->ID ); ?>
35
- <?php require_once( happyforms_get_include_folder() . '/templates/single-form.php' ); ?>
36
- <?php endwhile; endif; ?>
37
 
38
  <?php wp_footer(); ?>
39
-
40
  </body>
41
  </html>
1
  <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title><?php wp_title(); ?></title>
6
+ <?php wp_head(); ?>
7
+ </head>
8
+ <body class="happyforms-preview">
 
9
  <div id="message" class="updated published notice notice-success">
10
  <p><?php printf( __( 'This is a preview of your new HappyForm. Once you’ve finished building, you can add this form to any Page, Post and Widget area. Have questions? <a href="%s" class="happyforms-ask-link" target="_blank">Ask for help in our support forums.</a>', 'happyforms' ), 'https://wordpress.org/support/plugin/happyforms' ); ?></p>
11
  </div>
12
 
13
+ <?php global $post; $form = happyforms_get_form_controller()->get( $post->ID ); ?>
14
+ <?php happyforms_the_form_styles( $form ); ?>
15
+ <?php require_once( happyforms_get_include_folder() . '/templates/single-form.php' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  <?php wp_footer(); ?>
 
18
  </body>
19
  </html>
inc/templates/single-form.php CHANGED
@@ -1,12 +1,15 @@
1
- <?php happyforms_the_form_styles( $form ); ?>
 
2
  <div class="happyforms-form" id="happyforms-<?php echo esc_attr( $form['ID'] ); ?>">
3
  <form action="<?php happyforms_form_action( $form['ID'] ); ?>" class="<?php happyforms_the_form_class( $form ); ?>" id="happyforms-form-<?php echo esc_attr( $form['ID'] ); ?>" method="post">
 
 
 
4
  <?php happyforms_action_field(); ?>
5
- <?php happyforms_redirect_field( $form ); ?>
6
  <?php happyforms_form_field( $form['ID'] ); ?>
7
  <?php happyforms_nonce_field( $form ); ?>
8
  <?php happyforms_the_form_title( $form ); ?>
9
- <?php happyforms_message_notices( $form, 'top' ); ?>
10
 
11
  <div class="happyforms-flex">
12
  <?php foreach ( $form['parts'] as $part ) {
@@ -16,5 +19,9 @@
16
  <?php happyforms_recaptcha( $form ); ?>
17
  <?php happyforms_submit( $form ); ?>
18
  </div>
 
 
19
  </form>
20
  </div>
 
 
1
+ <?php do_action( 'happyforms_form_before', $form ); ?>
2
+
3
  <div class="happyforms-form" id="happyforms-<?php echo esc_attr( $form['ID'] ); ?>">
4
  <form action="<?php happyforms_form_action( $form['ID'] ); ?>" class="<?php happyforms_the_form_class( $form ); ?>" id="happyforms-form-<?php echo esc_attr( $form['ID'] ); ?>" method="post">
5
+
6
+ <?php do_action( 'happyforms_form_open', $form ); ?>
7
+
8
  <?php happyforms_action_field(); ?>
 
9
  <?php happyforms_form_field( $form['ID'] ); ?>
10
  <?php happyforms_nonce_field( $form ); ?>
11
  <?php happyforms_the_form_title( $form ); ?>
12
+ <?php happyforms_message_notices( $form['ID'] ); ?>
13
 
14
  <div class="happyforms-flex">
15
  <?php foreach ( $form['parts'] as $part ) {
19
  <?php happyforms_recaptcha( $form ); ?>
20
  <?php happyforms_submit( $form ); ?>
21
  </div>
22
+
23
+ <?php do_action( 'happyforms_form_close', $form ); ?>
24
  </form>
25
  </div>
26
+
27
+ <?php do_action( 'happyforms_form_after', $form ); ?>
languages/happyforms.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the HappyForms package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: HappyForms 1.4.6\n"
6
  "Report-Msgid-Bugs-To: https://thethemefoundry.com/support/\n"
7
- "POT-Creation-Date: 2018-06-07 09:06:05+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -13,179 +13,180 @@ msgstr ""
13
  "Language-Team: The Theme Foundry\n"
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
- #: inc/classes/class-form-admin.php:131
17
- #: inc/classes/class-form-controller.php:73
18
  msgid "View form"
19
  msgstr ""
20
 
21
- #: inc/classes/class-form-admin.php:136
22
  msgid "Preview form"
23
  msgstr ""
24
 
25
- #: inc/classes/class-form-admin.php:141 inc/classes/class-form-admin.php:144
26
  msgid "Form updated."
27
  msgstr ""
28
 
29
- #: inc/classes/class-form-admin.php:142 inc/classes/class-message-admin.php:193
30
  msgid "Custom field updated."
31
  msgstr ""
32
 
33
- #: inc/classes/class-form-admin.php:143 inc/classes/class-message-admin.php:194
34
  msgid "Custom field deleted."
35
  msgstr ""
36
 
37
- #: inc/classes/class-form-admin.php:145
38
  msgid "Form restored to revision from %s."
39
  msgstr ""
40
 
41
- #: inc/classes/class-form-admin.php:146
42
  msgid "Form published."
43
  msgstr ""
44
 
45
- #: inc/classes/class-form-admin.php:147
46
- #: inc/classes/class-wp-customize-form-manager.php:166
47
  msgid "Form saved."
48
  msgstr ""
49
 
50
- #: inc/classes/class-form-admin.php:148
51
  msgid "Form submitted."
52
  msgstr ""
53
 
54
- #: inc/classes/class-form-admin.php:149
55
  msgid "Form scheduled."
56
  msgstr ""
57
 
58
- #: inc/classes/class-form-admin.php:150
59
  msgid "Form draft updated."
60
  msgstr ""
61
 
62
- #: inc/classes/class-form-admin.php:173
63
  msgid "%s form updated."
64
  msgid_plural "%s forms updated."
65
  msgstr[0] ""
66
  msgstr[1] ""
67
 
68
- #: inc/classes/class-form-admin.php:174
69
  msgid "%s form not updated, somebody is editing it."
70
  msgid_plural "%s forms not updated, somebody is editing them."
71
  msgstr[0] ""
72
  msgstr[1] ""
73
 
74
- #: inc/classes/class-form-admin.php:175
75
  msgid "%s form permanently deleted."
76
  msgid_plural "%s forms permanently deleted."
77
  msgstr[0] ""
78
  msgstr[1] ""
79
 
80
- #: inc/classes/class-form-admin.php:176
81
  msgid "%s form moved to the Trash."
82
  msgid_plural "%s forms moved to the Trash."
83
  msgstr[0] ""
84
  msgstr[1] ""
85
 
86
- #: inc/classes/class-form-admin.php:177
87
  msgid "%s form restored from the Trash."
88
  msgid_plural "%s forms restored from the Trash."
89
  msgstr[0] ""
90
  msgstr[1] ""
91
 
92
- #: inc/classes/class-form-admin.php:230
93
  msgid "Shortcode"
94
  msgstr ""
95
 
96
- #: inc/classes/class-form-admin.php:231
97
  msgid "Author"
98
  msgstr ""
99
 
100
- #: inc/classes/class-form-admin.php:280
101
  msgid "Copy to clipboard"
102
  msgstr ""
103
 
104
- #: inc/classes/class-form-admin.php:334 inc/classes/class-message-admin.php:624
105
  msgid "Edit"
106
  msgstr ""
107
 
108
- #: inc/classes/class-form-admin.php:338
109
  #: inc/templates/customize-form-item.php:27
110
  #: inc/templates/customize-form-part-footer.php:4
111
  msgid "Duplicate"
112
  msgstr ""
113
 
114
- #: inc/classes/class-form-admin.php:342 inc/classes/class-message-admin.php:552
115
  #: inc/classes/class-message-admin.php:805
116
  msgid "Trash"
117
  msgstr ""
118
 
119
- #: inc/classes/class-form-admin.php:387
120
  msgid "Form duplicated succesfully."
121
  msgstr ""
122
 
123
- #: inc/classes/class-form-admin.php:411
124
  msgid " Copy"
125
  msgstr ""
126
 
127
- #: inc/classes/class-form-controller.php:68
128
- #: inc/classes/class-form-controller.php:78
129
  #: inc/classes/class-happyforms-plugin.php:144
130
  #: inc/classes/class-happyforms-plugin.php:145
131
  msgid "All Forms"
132
  msgstr ""
133
 
134
- #: inc/classes/class-form-controller.php:69
135
  #: inc/classes/class-message-admin.php:317
136
  #: inc/classes/class-message-admin.php:790
137
  msgid "Form"
138
  msgstr ""
139
 
140
- #: inc/classes/class-form-controller.php:70
141
- #: inc/classes/class-form-controller.php:72
142
  msgid "Build form"
143
  msgstr ""
144
 
145
- #: inc/classes/class-form-controller.php:71
146
  msgid "Edit form"
147
  msgstr ""
148
 
149
- #: inc/classes/class-form-controller.php:74
150
  msgid "View forms"
151
  msgstr ""
152
 
153
- #: inc/classes/class-form-controller.php:75
154
  msgid "Search Forms"
155
  msgstr ""
156
 
157
- #: inc/classes/class-form-controller.php:76
158
  msgid "No form found"
159
  msgstr ""
160
 
161
- #: inc/classes/class-form-controller.php:77
162
  msgid "No forms found in Trash"
163
  msgstr ""
164
 
165
- #: inc/classes/class-form-controller.php:163
166
  msgid "Untitled form"
167
  msgstr ""
168
 
169
- #: inc/classes/class-form-controller.php:188
170
  msgid "You received a new message"
171
  msgstr ""
172
 
173
- #: inc/classes/class-form-controller.php:192
174
- #: inc/classes/class-form-controller.php:200
175
  msgid ""
176
  "Your message has been successfully sent. We appreciate you contacting us "
177
  "and we’ll be in touch soon."
178
  msgstr ""
179
 
180
- #: inc/classes/class-form-controller.php:196
181
  msgid "We received your message"
182
  msgstr ""
183
 
184
- #: inc/classes/class-form-controller.php:212
185
  msgid "Submit Form"
186
  msgstr ""
187
 
188
- #: inc/classes/class-form-controller.php:728
 
189
  msgid "Your submission contains errors."
190
  msgstr ""
191
 
@@ -222,6 +223,7 @@ msgstr ""
222
  #: inc/classes/class-form-styles.php:91 inc/classes/class-form-styles.php:120
223
  #: inc/classes/class-form-styles.php:168 inc/classes/class-form-styles.php:252
224
  #: inc/templates/parts/customize-date.php:30
 
225
  msgid "Show"
226
  msgstr ""
227
 
@@ -486,16 +488,16 @@ msgstr ""
486
  #: inc/classes/class-form-styles.php:663
487
  #: inc/templates/parts/customize-address.php:74
488
  #: inc/templates/parts/customize-checkbox.php:51
489
- #: inc/templates/parts/customize-date.php:82
490
  #: inc/templates/parts/customize-email.php:42
491
  #: inc/templates/parts/customize-legal.php:4
492
  #: inc/templates/parts/customize-multi-line-text.php:42
493
  #: inc/templates/parts/customize-number.php:71
494
- #: inc/templates/parts/customize-phone.php:62
495
  #: inc/templates/parts/customize-placeholder.php:26
496
  #: inc/templates/parts/customize-radio.php:51
497
  #: inc/templates/parts/customize-rating.php:36
498
- #: inc/templates/parts/customize-scale.php:68
499
  #: inc/templates/parts/customize-select.php:45
500
  #: inc/templates/parts/customize-single-line-text.php:42
501
  #: inc/templates/parts/customize-title.php:36
@@ -516,8 +518,8 @@ msgid "Background on hover"
516
  msgstr ""
517
 
518
  #: inc/classes/class-form-styles.php:707
519
- #: inc/classes/parts/class-part-multi-line-text.php:26
520
- #: inc/classes/parts/class-part-single-line-text.php:26
521
  #: inc/templates/parts/customize-placeholder.php:21
522
  msgid "Text"
523
  msgstr ""
@@ -740,10 +742,6 @@ msgstr ""
740
  msgid "No response found in Trash"
741
  msgstr ""
742
 
743
- #: inc/classes/class-message-controller.php:193
744
- msgid "Bad request."
745
- msgstr ""
746
-
747
  #: inc/classes/class-tracking.php:168
748
  msgid "Sorry, you are not allowed to access this page."
749
  msgstr ""
@@ -774,59 +772,59 @@ msgstr ""
774
  msgid "Error description"
775
  msgstr ""
776
 
777
- #: inc/classes/class-wp-customize-form-manager.php:167
778
  msgid "Now, there are couple of ways to embed it to your content. Here goes..."
779
  msgstr ""
780
 
781
- #: inc/classes/class-wp-customize-form-manager.php:168
782
  msgid "Add to your page / post content"
783
  msgstr ""
784
 
785
- #: inc/classes/class-wp-customize-form-manager.php:169
786
  msgid ""
787
  "In your Edit Post / Edit Page screen, click the <b>Add HappyForms</b> "
788
  "button right above your toolbar. A modal window will appear."
789
  msgstr ""
790
 
791
- #: inc/classes/class-wp-customize-form-manager.php:169
792
  msgid "Select a form in the dropdown, then click <b>Insert</b>."
793
  msgstr ""
794
 
795
- #: inc/classes/class-wp-customize-form-manager.php:169
796
  msgid ""
797
  "That's it! You'll notice the shortcode was added to your content. Your form "
798
  "will show up there."
799
  msgstr ""
800
 
801
- #: inc/classes/class-wp-customize-form-manager.php:170
802
  msgid "Use the HappyForms widget"
803
  msgstr ""
804
 
805
- #: inc/classes/class-wp-customize-form-manager.php:172
806
  msgid ""
807
  "Head over to <b>Appearance</b> &rarr; <b><a href=\"%s\">Widgets</a></b> "
808
  "screen."
809
  msgstr ""
810
 
811
- #: inc/classes/class-wp-customize-form-manager.php:173
812
  msgid "Drag the HappyForms widget to your sidebar."
813
  msgstr ""
814
 
815
- #: inc/classes/class-wp-customize-form-manager.php:174
816
  msgid "Select a form in the Form dropdown."
817
  msgstr ""
818
 
819
- #: inc/classes/class-wp-customize-form-manager.php:175
820
  msgid "All done!"
821
  msgstr ""
822
 
823
- #: inc/classes/class-wp-customize-form-manager.php:177
824
  msgid ""
825
  "Looking for a full documentation? Head over to our <a href=\"%s\" "
826
  "target=\"_blank\">Help Guide</a>."
827
  msgstr ""
828
 
829
- #: inc/classes/class-wp-customize-form-manager.php:184
830
  msgid ""
831
  "Form saved. You can add this form to any Page, Post and Widget area. Have "
832
  "questions? <a href=\"%s\" target=\"_blank\">Ask for help in our support "
@@ -834,7 +832,7 @@ msgid ""
834
  msgstr ""
835
 
836
  #: inc/classes/parts/class-part-address.php:13
837
- #: inc/classes/parts/class-part-address.php:39
838
  msgid "Address"
839
  msgstr ""
840
 
@@ -842,21 +840,24 @@ msgstr ""
842
  msgid "For geographical locations. Includes Google Maps intergration."
843
  msgstr ""
844
 
845
- #: inc/classes/parts/class-part-address.php:127
846
- #: inc/classes/parts/class-part-checkbox.php:133
847
- #: inc/classes/parts/class-part-date.php:130
848
- #: inc/classes/parts/class-part-email.php:109
849
- #: inc/classes/parts/class-part-legal.php:88
850
- #: inc/classes/parts/class-part-multi-line-text.php:99
851
- #: inc/classes/parts/class-part-number.php:134
852
- #: inc/classes/parts/class-part-phone.php:118
853
- #: inc/classes/parts/class-part-radio.php:142
854
- #: inc/classes/parts/class-part-rating.php:100
855
- #: inc/classes/parts/class-part-scale.php:122
856
- #: inc/classes/parts/class-part-select.php:134
857
- #: inc/classes/parts/class-part-single-line-text.php:99
858
- #: inc/classes/parts/class-part-title.php:130
859
- #: inc/classes/parts/class-part-website-url.php:99
 
 
 
860
  msgid "This field is required."
861
  msgstr ""
862
 
@@ -868,7 +869,7 @@ msgstr ""
868
  msgid "For checkboxes allowing multiple selections."
869
  msgstr ""
870
 
871
- #: inc/classes/parts/class-part-checkbox.php:28
872
  #: inc/classes/parts/class-part-radio.php:29
873
  #: inc/templates/parts/customize-checkbox.php:36
874
  #: inc/templates/parts/customize-radio.php:36
@@ -876,7 +877,7 @@ msgstr ""
876
  msgid "Options"
877
  msgstr ""
878
 
879
- #: inc/classes/parts/class-part-checkbox.php:137
880
  msgid "Checkbox values are not valid."
881
  msgstr ""
882
 
@@ -888,25 +889,25 @@ msgstr ""
888
  msgid "For formatted day, month, year and or time fields."
889
  msgstr ""
890
 
891
- #: inc/classes/parts/class-part-date.php:29
892
  #: inc/templates/parts/customize-date.php:32
893
  msgid "Date"
894
  msgstr ""
895
 
896
- #: inc/classes/parts/class-part-date.php:134
897
  msgid "Not a valid date."
898
  msgstr ""
899
 
900
- #: inc/classes/parts/class-part-date.php:138
901
  msgid "Hour input does not match minimum and maximum value allowed."
902
  msgstr ""
903
 
904
- #: inc/classes/parts/class-part-date.php:142
905
  msgid "Year input does not match maximum value allowed."
906
  msgstr ""
907
 
908
  #: inc/classes/parts/class-part-email.php:8
909
- #: inc/classes/parts/class-part-email.php:28
910
  msgid "Email"
911
  msgstr ""
912
 
@@ -914,21 +915,15 @@ msgstr ""
914
  msgid "For formatted email addresses. The '@' symbol is required."
915
  msgstr ""
916
 
917
- #: inc/classes/parts/class-part-email.php:48
918
  msgid "Confirm Email"
919
  msgstr ""
920
 
921
- #: inc/classes/parts/class-part-email.php:113
922
  msgid "Not a valid e-mail address."
923
  msgstr ""
924
 
925
- #: inc/classes/parts/class-part-email.php:117
926
- #: inc/classes/parts/class-part-number.php:142
927
- #: inc/classes/parts/class-part-phone.php:122
928
- msgid "Confirmation field is required."
929
- msgstr ""
930
-
931
- #: inc/classes/parts/class-part-email.php:121
932
  msgid "Email and confirmation email are not matching."
933
  msgstr ""
934
 
@@ -945,7 +940,7 @@ msgstr ""
945
  msgid "I accept terms and conditions."
946
  msgstr ""
947
 
948
- #: inc/classes/parts/class-part-legal.php:92
949
  msgid "Please accept terms before proceeding."
950
  msgstr ""
951
 
@@ -958,7 +953,7 @@ msgid "For paragraph text fields."
958
  msgstr ""
959
 
960
  #: inc/classes/parts/class-part-number.php:8
961
- #: inc/classes/parts/class-part-number.php:29
962
  msgid "Number"
963
  msgstr ""
964
 
@@ -966,26 +961,17 @@ msgstr ""
966
  msgid "For numeric fields."
967
  msgstr ""
968
 
969
- #: inc/classes/parts/class-part-number.php:85
970
- #: inc/classes/parts/class-part-phone.php:69
971
  msgid "Confirm Number"
972
  msgstr ""
973
 
974
- #: inc/classes/parts/class-part-number.php:138
975
- msgid "This field requires a numeric value."
976
- msgstr ""
977
-
978
- #: inc/classes/parts/class-part-number.php:146
979
- msgid "Confirmation number is not a valid number."
980
- msgstr ""
981
-
982
- #: inc/classes/parts/class-part-number.php:150
983
- #: inc/classes/parts/class-part-phone.php:126
984
  msgid "Number and confirmation number are not matching."
985
  msgstr ""
986
 
987
  #: inc/classes/parts/class-part-phone.php:8
988
- #: inc/classes/parts/class-part-phone.php:29
989
  msgid "Phone"
990
  msgstr ""
991
 
@@ -993,6 +979,10 @@ msgstr ""
993
  msgid "For phone numbers. Includes country specific formatting."
994
  msgstr ""
995
 
 
 
 
 
996
  #: inc/classes/parts/class-part-placeholder.php:9
997
  msgid "For adding helper text, horizontal rules and extra space."
998
  msgstr ""
@@ -1005,12 +995,12 @@ msgstr ""
1005
  msgid "For radio buttons allowing one selection."
1006
  msgstr ""
1007
 
1008
- #: inc/classes/parts/class-part-radio.php:146
1009
  msgid "Radio values are not valid."
1010
  msgstr ""
1011
 
1012
  #: inc/classes/parts/class-part-rating.php:9
1013
- #: inc/classes/parts/class-part-rating.php:27
1014
  msgid "Rating"
1015
  msgstr ""
1016
 
@@ -1018,12 +1008,12 @@ msgstr ""
1018
  msgid "For collecting opinions using a zero to five star scale."
1019
  msgstr ""
1020
 
1021
- #: inc/classes/parts/class-part-rating.php:104
1022
  msgid "Value should be between 1 and 5."
1023
  msgstr ""
1024
 
1025
  #: inc/classes/parts/class-part-scale.php:8
1026
- #: inc/classes/parts/class-part-scale.php:29
1027
  msgid "Scale"
1028
  msgstr ""
1029
 
@@ -1031,10 +1021,6 @@ msgstr ""
1031
  msgid "For collecting opinions using a horizontal slider."
1032
  msgstr ""
1033
 
1034
- #: inc/classes/parts/class-part-scale.php:126
1035
- msgid "This field requires numeric value."
1036
- msgstr ""
1037
-
1038
  #: inc/classes/parts/class-part-select.php:8
1039
  #: inc/classes/parts/class-part-select.php:26
1040
  msgid "Dropdown"
@@ -1044,7 +1030,7 @@ msgstr ""
1044
  msgid "For selecting one option from a long list. Default value adjustable."
1045
  msgstr ""
1046
 
1047
- #: inc/classes/parts/class-part-select.php:138
1048
  msgid "Select values are not valid."
1049
  msgstr ""
1050
 
@@ -1060,36 +1046,36 @@ msgstr ""
1060
  msgid "For displaying personal honorifics."
1061
  msgstr ""
1062
 
1063
- #: inc/classes/parts/class-part-title.php:93
1064
  msgid "Mr."
1065
  msgstr ""
1066
 
1067
- #: inc/classes/parts/class-part-title.php:94
1068
  msgid "Mrs."
1069
  msgstr ""
1070
 
1071
- #: inc/classes/parts/class-part-title.php:95
1072
  msgid "Ms."
1073
  msgstr ""
1074
 
1075
- #: inc/classes/parts/class-part-title.php:96
1076
  msgid "Miss"
1077
  msgstr ""
1078
 
1079
- #: inc/classes/parts/class-part-title.php:97
1080
  msgid "Prof."
1081
  msgstr ""
1082
 
1083
- #: inc/classes/parts/class-part-title.php:98
1084
  msgid "Dr."
1085
  msgstr ""
1086
 
1087
- #: inc/classes/parts/class-part-title.php:134
1088
  msgid "Values is not valid."
1089
  msgstr ""
1090
 
1091
  #: inc/classes/parts/class-part-website-url.php:8
1092
- #: inc/classes/parts/class-part-website-url.php:26
1093
  msgid "Website Link"
1094
  msgstr ""
1095
 
@@ -1097,1031 +1083,1079 @@ msgstr ""
1097
  msgid "For formatted website URLs."
1098
  msgstr ""
1099
 
1100
- #: inc/classes/parts/class-part-website-url.php:103
1101
  msgid "Not a valid URL."
1102
  msgstr ""
1103
 
1104
- #: inc/helpers/helper-activation.php:48
1105
  msgid "Sample Contact Form"
1106
  msgstr ""
1107
 
1108
- #: inc/helpers/helper-activation.php:59
1109
  msgid "First name"
1110
  msgstr ""
1111
 
1112
- #: inc/helpers/helper-activation.php:64
1113
  msgid "Last name"
1114
  msgstr ""
1115
 
1116
- #: inc/helpers/helper-activation.php:69
1117
  msgid "What's your reason for contacting us?"
1118
  msgstr ""
1119
 
1120
- #: inc/helpers/helper-activation.php:72
1121
  msgid "Need technical help"
1122
  msgstr ""
1123
 
1124
- #: inc/helpers/helper-activation.php:75
1125
  msgid "Want to suggest a feature"
1126
  msgstr ""
1127
 
1128
- #: inc/helpers/helper-activation.php:78
1129
  msgid "Asking about my account"
1130
  msgstr ""
1131
 
1132
- #: inc/helpers/helper-activation.php:84
1133
  msgid "Age"
1134
  msgstr ""
1135
 
1136
- #: inc/helpers/helper-activation.php:89
1137
  msgid "Your message"
1138
  msgstr ""
1139
 
1140
- #: inc/helpers/helper-activation.php:121
1141
  msgid "It would be great if I could use Google ReCaptcha instead of Honeypot."
1142
  msgstr ""
1143
 
1144
- #: inc/helpers/helper-activation.php:128
1145
  msgid "How do I embed a HappyForm in my sidebar?"
1146
  msgstr ""
1147
 
1148
- #: inc/helpers/helper-activation.php:135
1149
  msgid "How can I access my premium upgrade credentials?"
1150
  msgstr ""
1151
 
1152
- #: inc/helpers/helper-form-templates.php:715
1153
  msgid "Get my location"
1154
  msgstr ""
1155
 
1156
- #: inc/helpers/helper-form-templates.php:715
1157
  msgid "Fetching location…"
1158
  msgstr ""
1159
 
1160
- #: inc/helpers/helper-misc.php:144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1161
  msgid "How are we doing? Please rate"
1162
  msgstr ""
1163
 
1164
- #: inc/helpers/helper-misc.php:144
1165
  msgid "on"
1166
  msgstr ""
1167
 
1168
- #: inc/helpers/helper-misc.php:144
1169
  msgid "to help us spread the word."
1170
  msgstr ""
1171
 
1172
- #: inc/helpers/helper-misc.php:198
1173
  msgid "Afghanistan"
1174
  msgstr ""
1175
 
1176
- #: inc/helpers/helper-misc.php:199
1177
  msgid "Albania"
1178
  msgstr ""
1179
 
1180
- #: inc/helpers/helper-misc.php:200
1181
  msgid "Algeria"
1182
  msgstr ""
1183
 
1184
- #: inc/helpers/helper-misc.php:201
1185
  msgid "American Samoa"
1186
  msgstr ""
1187
 
1188
- #: inc/helpers/helper-misc.php:202
1189
  msgid "Andorra"
1190
  msgstr ""
1191
 
1192
- #: inc/helpers/helper-misc.php:203
1193
  msgid "Angola"
1194
  msgstr ""
1195
 
1196
- #: inc/helpers/helper-misc.php:204
1197
  msgid "Anguilla"
1198
  msgstr ""
1199
 
1200
- #: inc/helpers/helper-misc.php:205
1201
  msgid "Antarctica"
1202
  msgstr ""
1203
 
1204
- #: inc/helpers/helper-misc.php:206
1205
  msgid "Antigua and Barbuda"
1206
  msgstr ""
1207
 
1208
- #: inc/helpers/helper-misc.php:207
1209
  msgid "Argentina"
1210
  msgstr ""
1211
 
1212
- #: inc/helpers/helper-misc.php:208
1213
  msgid "Armenia"
1214
  msgstr ""
1215
 
1216
- #: inc/helpers/helper-misc.php:209
1217
  msgid "Aruba"
1218
  msgstr ""
1219
 
1220
- #: inc/helpers/helper-misc.php:210
1221
  msgid "Australia"
1222
  msgstr ""
1223
 
1224
- #: inc/helpers/helper-misc.php:211
1225
  msgid "Austria"
1226
  msgstr ""
1227
 
1228
- #: inc/helpers/helper-misc.php:212
1229
  msgid "Azerbaijan"
1230
  msgstr ""
1231
 
1232
- #: inc/helpers/helper-misc.php:213
1233
  msgid "Bahamas"
1234
  msgstr ""
1235
 
1236
- #: inc/helpers/helper-misc.php:214
1237
  msgid "Bahrain"
1238
  msgstr ""
1239
 
1240
- #: inc/helpers/helper-misc.php:215
1241
  msgid "Bangladesh"
1242
  msgstr ""
1243
 
1244
- #: inc/helpers/helper-misc.php:216
1245
  msgid "Barbados"
1246
  msgstr ""
1247
 
1248
- #: inc/helpers/helper-misc.php:217
1249
  msgid "Belarus"
1250
  msgstr ""
1251
 
1252
- #: inc/helpers/helper-misc.php:218
1253
  msgid "Belgium"
1254
  msgstr ""
1255
 
1256
- #: inc/helpers/helper-misc.php:219
1257
  msgid "Belize"
1258
  msgstr ""
1259
 
1260
- #: inc/helpers/helper-misc.php:220
1261
  msgid "Benin"
1262
  msgstr ""
1263
 
1264
- #: inc/helpers/helper-misc.php:221
1265
  msgid "Bermuda"
1266
  msgstr ""
1267
 
1268
- #: inc/helpers/helper-misc.php:222
1269
  msgid "Bhutan"
1270
  msgstr ""
1271
 
1272
- #: inc/helpers/helper-misc.php:223
1273
  msgid "Bolivia"
1274
  msgstr ""
1275
 
1276
- #: inc/helpers/helper-misc.php:224
1277
  msgid "Bosnia and Herzegowina"
1278
  msgstr ""
1279
 
1280
- #: inc/helpers/helper-misc.php:225
1281
  msgid "Botswana"
1282
  msgstr ""
1283
 
1284
- #: inc/helpers/helper-misc.php:226
1285
  msgid "Bouvet Island"
1286
  msgstr ""
1287
 
1288
- #: inc/helpers/helper-misc.php:227
1289
  msgid "Brazil"
1290
  msgstr ""
1291
 
1292
- #: inc/helpers/helper-misc.php:228
1293
  msgid "British Indian Ocean Territory"
1294
  msgstr ""
1295
 
1296
- #: inc/helpers/helper-misc.php:229
1297
  msgid "Brunei Darussalam"
1298
  msgstr ""
1299
 
1300
- #: inc/helpers/helper-misc.php:230
1301
  msgid "Bulgaria"
1302
  msgstr ""
1303
 
1304
- #: inc/helpers/helper-misc.php:231
1305
  msgid "Burkina Faso"
1306
  msgstr ""
1307
 
1308
- #: inc/helpers/helper-misc.php:232
1309
  msgid "Burundi"
1310
  msgstr ""
1311
 
1312
- #: inc/helpers/helper-misc.php:233
1313
  msgid "Cambodia"
1314
  msgstr ""
1315
 
1316
- #: inc/helpers/helper-misc.php:234
1317
  msgid "Cameroon"
1318
  msgstr ""
1319
 
1320
- #: inc/helpers/helper-misc.php:235
1321
  msgid "Canada"
1322
  msgstr ""
1323
 
1324
- #: inc/helpers/helper-misc.php:236
1325
  msgid "Cape Verde"
1326
  msgstr ""
1327
 
1328
- #: inc/helpers/helper-misc.php:237
1329
  msgid "Cayman Islands"
1330
  msgstr ""
1331
 
1332
- #: inc/helpers/helper-misc.php:238
1333
  msgid "Central African Republic"
1334
  msgstr ""
1335
 
1336
- #: inc/helpers/helper-misc.php:239
1337
  msgid "Chad"
1338
  msgstr ""
1339
 
1340
- #: inc/helpers/helper-misc.php:240
1341
  msgid "Chile"
1342
  msgstr ""
1343
 
1344
- #: inc/helpers/helper-misc.php:241
1345
  msgid "China"
1346
  msgstr ""
1347
 
1348
- #: inc/helpers/helper-misc.php:242
1349
  msgid "Christmas Island"
1350
  msgstr ""
1351
 
1352
- #: inc/helpers/helper-misc.php:243
1353
  msgid "Cocos (Keeling) Islands"
1354
  msgstr ""
1355
 
1356
- #: inc/helpers/helper-misc.php:244
1357
  msgid "Colombia"
1358
  msgstr ""
1359
 
1360
- #: inc/helpers/helper-misc.php:245
1361
  msgid "Comoros"
1362
  msgstr ""
1363
 
1364
- #: inc/helpers/helper-misc.php:246
1365
  msgid "Congo"
1366
  msgstr ""
1367
 
1368
- #: inc/helpers/helper-misc.php:247
1369
  msgid "Congo, the Democratic Republic of the"
1370
  msgstr ""
1371
 
1372
- #: inc/helpers/helper-misc.php:248
1373
  msgid "Cook Islands"
1374
  msgstr ""
1375
 
1376
- #: inc/helpers/helper-misc.php:249
1377
  msgid "Costa Rica"
1378
  msgstr ""
1379
 
1380
- #: inc/helpers/helper-misc.php:250
1381
  msgid "Cote d'Ivoire"
1382
  msgstr ""
1383
 
1384
- #: inc/helpers/helper-misc.php:251
1385
  msgid "Croatia (Hrvatska)"
1386
  msgstr ""
1387
 
1388
- #: inc/helpers/helper-misc.php:252
1389
  msgid "Cuba"
1390
  msgstr ""
1391
 
1392
- #: inc/helpers/helper-misc.php:253
1393
  msgid "Cyprus"
1394
  msgstr ""
1395
 
1396
- #: inc/helpers/helper-misc.php:254
1397
  msgid "Czech Republic"
1398
  msgstr ""
1399
 
1400
- #: inc/helpers/helper-misc.php:255
1401
  msgid "Denmark"
1402
  msgstr ""
1403
 
1404
- #: inc/helpers/helper-misc.php:256
1405
  msgid "Djibouti"
1406
  msgstr ""
1407
 
1408
- #: inc/helpers/helper-misc.php:257
1409
  msgid "Dominica"
1410
  msgstr ""
1411
 
1412
- #: inc/helpers/helper-misc.php:258
1413
  msgid "Dominican Republic"
1414
  msgstr ""
1415
 
1416
- #: inc/helpers/helper-misc.php:259
1417
  msgid "East Timor"
1418
  msgstr ""
1419
 
1420
- #: inc/helpers/helper-misc.php:260
1421
  msgid "Ecuador"
1422
  msgstr ""
1423
 
1424
- #: inc/helpers/helper-misc.php:261
1425
  msgid "Egypt"
1426
  msgstr ""
1427
 
1428
- #: inc/helpers/helper-misc.php:262
1429
  msgid "El Salvador"
1430
  msgstr ""
1431
 
1432
- #: inc/helpers/helper-misc.php:263
1433
  msgid "Equatorial Guinea"
1434
  msgstr ""
1435
 
1436
- #: inc/helpers/helper-misc.php:264
1437
  msgid "Eritrea"
1438
  msgstr ""
1439
 
1440
- #: inc/helpers/helper-misc.php:265
1441
  msgid "Estonia"
1442
  msgstr ""
1443
 
1444
- #: inc/helpers/helper-misc.php:266
1445
  msgid "Ethiopia"
1446
  msgstr ""
1447
 
1448
- #: inc/helpers/helper-misc.php:267
1449
  msgid "Falkland Islands (Malvinas)"
1450
  msgstr ""
1451
 
1452
- #: inc/helpers/helper-misc.php:268
1453
  msgid "Faroe Islands"
1454
  msgstr ""
1455
 
1456
- #: inc/helpers/helper-misc.php:269
1457
  msgid "Fiji"
1458
  msgstr ""
1459
 
1460
- #: inc/helpers/helper-misc.php:270
1461
  msgid "Finland"
1462
  msgstr ""
1463
 
1464
- #: inc/helpers/helper-misc.php:271
1465
  msgid "France"
1466
  msgstr ""
1467
 
1468
- #: inc/helpers/helper-misc.php:272
1469
  msgid "France Metropolitan"
1470
  msgstr ""
1471
 
1472
- #: inc/helpers/helper-misc.php:273
1473
  msgid "French Guiana"
1474
  msgstr ""
1475
 
1476
- #: inc/helpers/helper-misc.php:274
1477
  msgid "French Polynesia"
1478
  msgstr ""
1479
 
1480
- #: inc/helpers/helper-misc.php:275
1481
  msgid "French Southern Territories"
1482
  msgstr ""
1483
 
1484
- #: inc/helpers/helper-misc.php:276
1485
  msgid "Gabon"
1486
  msgstr ""
1487
 
1488
- #: inc/helpers/helper-misc.php:277
1489
  msgid "Gambia"
1490
  msgstr ""
1491
 
1492
- #: inc/helpers/helper-misc.php:278
1493
  msgid "Georgia"
1494
  msgstr ""
1495
 
1496
- #: inc/helpers/helper-misc.php:279
1497
  msgid "Germany"
1498
  msgstr ""
1499
 
1500
- #: inc/helpers/helper-misc.php:280
1501
  msgid "Ghana"
1502
  msgstr ""
1503
 
1504
- #: inc/helpers/helper-misc.php:281
1505
  msgid "Gibraltar"
1506
  msgstr ""
1507
 
1508
- #: inc/helpers/helper-misc.php:282
1509
  msgid "Greece"
1510
  msgstr ""
1511
 
1512
- #: inc/helpers/helper-misc.php:283
1513
  msgid "Greenland"
1514
  msgstr ""
1515
 
1516
- #: inc/helpers/helper-misc.php:284
1517
  msgid "Grenada"
1518
  msgstr ""
1519
 
1520
- #: inc/helpers/helper-misc.php:285
1521
  msgid "Guadeloupe"
1522
  msgstr ""
1523
 
1524
- #: inc/helpers/helper-misc.php:286
1525
  msgid "Guam"
1526
  msgstr ""
1527
 
1528
- #: inc/helpers/helper-misc.php:287
1529
  msgid "Guatemala"
1530
  msgstr ""
1531
 
1532
- #: inc/helpers/helper-misc.php:288
1533
  msgid "Guinea"
1534
  msgstr ""
1535
 
1536
- #: inc/helpers/helper-misc.php:289
1537
  msgid "Guinea-Bissau"
1538
  msgstr ""
1539
 
1540
- #: inc/helpers/helper-misc.php:290
1541
  msgid "Guyana"
1542
  msgstr ""
1543
 
1544
- #: inc/helpers/helper-misc.php:291
1545
  msgid "Haiti"
1546
  msgstr ""
1547
 
1548
- #: inc/helpers/helper-misc.php:292
1549
  msgid "Heard and Mc Donald Islands"
1550
  msgstr ""
1551
 
1552
- #: inc/helpers/helper-misc.php:293
1553
  msgid "Holy See (Vatican City State)"
1554
  msgstr ""
1555
 
1556
- #: inc/helpers/helper-misc.php:294
1557
  msgid "Honduras"
1558
  msgstr ""
1559
 
1560
- #: inc/helpers/helper-misc.php:295
1561
  msgid "Hong Kong"
1562
  msgstr ""
1563
 
1564
- #: inc/helpers/helper-misc.php:296
1565
  msgid "Hungary"
1566
  msgstr ""
1567
 
1568
- #: inc/helpers/helper-misc.php:297
1569
  msgid "Iceland"
1570
  msgstr ""
1571
 
1572
- #: inc/helpers/helper-misc.php:298
1573
  msgid "India"
1574
  msgstr ""
1575
 
1576
- #: inc/helpers/helper-misc.php:299
1577
  msgid "Indonesia"
1578
  msgstr ""
1579
 
1580
- #: inc/helpers/helper-misc.php:300
1581
  msgid "Iran (Islamic Republic of)"
1582
  msgstr ""
1583
 
1584
- #: inc/helpers/helper-misc.php:301
1585
  msgid "Iraq"
1586
  msgstr ""
1587
 
1588
- #: inc/helpers/helper-misc.php:302
1589
  msgid "Ireland"
1590
  msgstr ""
1591
 
1592
- #: inc/helpers/helper-misc.php:303
1593
  msgid "Israel"
1594
  msgstr ""
1595
 
1596
- #: inc/helpers/helper-misc.php:304
1597
  msgid "Italy"
1598
  msgstr ""
1599
 
1600
- #: inc/helpers/helper-misc.php:305
1601
  msgid "Jamaica"
1602
  msgstr ""
1603
 
1604
- #: inc/helpers/helper-misc.php:306
1605
  msgid "Japan"
1606
  msgstr ""
1607
 
1608
- #: inc/helpers/helper-misc.php:307
1609
  msgid "Jordan"
1610
  msgstr ""
1611
 
1612
- #: inc/helpers/helper-misc.php:308
1613
  msgid "Kazakhstan"
1614
  msgstr ""
1615
 
1616
- #: inc/helpers/helper-misc.php:309
1617
  msgid "Kenya"
1618
  msgstr ""
1619
 
1620
- #: inc/helpers/helper-misc.php:310
1621
  msgid "Kiribati"
1622
  msgstr ""
1623
 
1624
- #: inc/helpers/helper-misc.php:311
1625
  msgid "Korea, Democratic People's Republic of"
1626
  msgstr ""
1627
 
1628
- #: inc/helpers/helper-misc.php:312
1629
  msgid "Korea, Republic of"
1630
  msgstr ""
1631
 
1632
- #: inc/helpers/helper-misc.php:313
1633
  msgid "Kuwait"
1634
  msgstr ""
1635
 
1636
- #: inc/helpers/helper-misc.php:314
1637
  msgid "Kyrgyzstan"
1638
  msgstr ""
1639
 
1640
- #: inc/helpers/helper-misc.php:315
1641
  msgid "Lao, People's Democratic Republic"
1642
  msgstr ""
1643
 
1644
- #: inc/helpers/helper-misc.php:316
1645
  msgid "Latvia"
1646
  msgstr ""
1647
 
1648
- #: inc/helpers/helper-misc.php:317
1649
  msgid "Lebanon"
1650
  msgstr ""
1651
 
1652
- #: inc/helpers/helper-misc.php:318
1653
  msgid "Lesotho"
1654
  msgstr ""
1655
 
1656
- #: inc/helpers/helper-misc.php:319
1657
  msgid "Liberia"
1658
  msgstr ""
1659
 
1660
- #: inc/helpers/helper-misc.php:320
1661
  msgid "Libyan Arab Jamahiriya"
1662
  msgstr ""
1663
 
1664
- #: inc/helpers/helper-misc.php:321
1665
  msgid "Liechtenstein"
1666
  msgstr ""
1667
 
1668
- #: inc/helpers/helper-misc.php:322
1669
  msgid "Lithuania"
1670
  msgstr ""
1671
 
1672
- #: inc/helpers/helper-misc.php:323
1673
  msgid "Luxembourg"
1674
  msgstr ""
1675
 
1676
- #: inc/helpers/helper-misc.php:324
1677
  msgid "Macau"
1678
  msgstr ""
1679
 
1680
- #: inc/helpers/helper-misc.php:325
1681
  msgid "Macedonia, The Former Yugoslav Republic of"
1682
  msgstr ""
1683
 
1684
- #: inc/helpers/helper-misc.php:326
1685
  msgid "Madagascar"
1686
  msgstr ""
1687
 
1688
- #: inc/helpers/helper-misc.php:327
1689
  msgid "Malawi"
1690
  msgstr ""
1691
 
1692
- #: inc/helpers/helper-misc.php:328
1693
  msgid "Malaysia"
1694
  msgstr ""
1695
 
1696
- #: inc/helpers/helper-misc.php:329
1697
  msgid "Maldives"
1698
  msgstr ""
1699
 
1700
- #: inc/helpers/helper-misc.php:330
1701
  msgid "Mali"
1702
  msgstr ""
1703
 
1704
- #: inc/helpers/helper-misc.php:331
1705
  msgid "Malta"
1706
  msgstr ""
1707
 
1708
- #: inc/helpers/helper-misc.php:332
1709
  msgid "Marshall Islands"
1710
  msgstr ""
1711
 
1712
- #: inc/helpers/helper-misc.php:333
1713
  msgid "Martinique"
1714
  msgstr ""
1715
 
1716
- #: inc/helpers/helper-misc.php:334
1717
  msgid "Mauritania"
1718
  msgstr ""
1719
 
1720
- #: inc/helpers/helper-misc.php:335
1721
  msgid "Mauritius"
1722
  msgstr ""
1723
 
1724
- #: inc/helpers/helper-misc.php:336
1725
  msgid "Mayotte"
1726
  msgstr ""
1727
 
1728
- #: inc/helpers/helper-misc.php:337
1729
  msgid "Mexico"
1730
  msgstr ""
1731
 
1732
- #: inc/helpers/helper-misc.php:338
1733
  msgid "Micronesia, Federated States of"
1734
  msgstr ""
1735
 
1736
- #: inc/helpers/helper-misc.php:339
1737
  msgid "Moldova, Republic of"
1738
  msgstr ""
1739
 
1740
- #: inc/helpers/helper-misc.php:340
1741
  msgid "Monaco"
1742
  msgstr ""
1743
 
1744
- #: inc/helpers/helper-misc.php:341
1745
  msgid "Mongolia"
1746
  msgstr ""
1747
 
1748
- #: inc/helpers/helper-misc.php:342
1749
  msgid "Montserrat"
1750
  msgstr ""
1751
 
1752
- #: inc/helpers/helper-misc.php:343
1753
  msgid "Morocco"
1754
  msgstr ""
1755
 
1756
- #: inc/helpers/helper-misc.php:344
1757
  msgid "Mozambique"
1758
  msgstr ""
1759
 
1760
- #: inc/helpers/helper-misc.php:345
1761
  msgid "Myanmar"
1762
  msgstr ""
1763
 
1764
- #: inc/helpers/helper-misc.php:346
1765
  msgid "Namibia"
1766
  msgstr ""
1767
 
1768
- #: inc/helpers/helper-misc.php:347
1769
  msgid "Nauru"
1770
  msgstr ""
1771
 
1772
- #: inc/helpers/helper-misc.php:348
1773
  msgid "Nepal"
1774
  msgstr ""
1775
 
1776
- #: inc/helpers/helper-misc.php:349
1777
  msgid "Netherlands"
1778
  msgstr ""
1779
 
1780
- #: inc/helpers/helper-misc.php:350
1781
  msgid "Netherlands Antilles"
1782
  msgstr ""
1783
 
1784
- #: inc/helpers/helper-misc.php:351
1785
  msgid "New Caledonia"
1786
  msgstr ""
1787
 
1788
- #: inc/helpers/helper-misc.php:352
1789
  msgid "New Zealand"
1790
  msgstr ""
1791
 
1792
- #: inc/helpers/helper-misc.php:353
1793
  msgid "Nicaragua"
1794
  msgstr ""
1795
 
1796
- #: inc/helpers/helper-misc.php:354
1797
  msgid "Niger"
1798
  msgstr ""
1799
 
1800
- #: inc/helpers/helper-misc.php:355
1801
  msgid "Nigeria"
1802
  msgstr ""
1803
 
1804
- #: inc/helpers/helper-misc.php:356
1805
  msgid "Niue"
1806
  msgstr ""
1807
 
1808
- #: inc/helpers/helper-misc.php:357
1809
  msgid "Norfolk Island"
1810
  msgstr ""
1811
 
1812
- #: inc/helpers/helper-misc.php:358
1813
  msgid "Northern Mariana Islands"
1814
  msgstr ""
1815
 
1816
- #: inc/helpers/helper-misc.php:359
1817
  msgid "Norway"
1818
  msgstr ""
1819
 
1820
- #: inc/helpers/helper-misc.php:360
1821
  msgid "Oman"
1822
  msgstr ""
1823
 
1824
- #: inc/helpers/helper-misc.php:361
1825
  msgid "Pakistan"
1826
  msgstr ""
1827
 
1828
- #: inc/helpers/helper-misc.php:362
1829
  msgid "Palau"
1830
  msgstr ""
1831
 
1832
- #: inc/helpers/helper-misc.php:363
1833
  msgid "Panama"
1834
  msgstr ""
1835
 
1836
- #: inc/helpers/helper-misc.php:364
1837
  msgid "Papua New Guinea"
1838
  msgstr ""
1839
 
1840
- #: inc/helpers/helper-misc.php:365
1841
  msgid "Paraguay"
1842
  msgstr ""
1843
 
1844
- #: inc/helpers/helper-misc.php:366
1845
  msgid "Peru"
1846
  msgstr ""
1847
 
1848
- #: inc/helpers/helper-misc.php:367
1849
  msgid "Philippines"
1850
  msgstr ""
1851
 
1852
- #: inc/helpers/helper-misc.php:368
1853
  msgid "Pitcairn"
1854
  msgstr ""
1855
 
1856
- #: inc/helpers/helper-misc.php:369
1857
  msgid "Poland"
1858
  msgstr ""
1859
 
1860
- #: inc/helpers/helper-misc.php:370
1861
  msgid "Portugal"
1862
  msgstr ""
1863
 
1864
- #: inc/helpers/helper-misc.php:371
1865
  msgid "Puerto Rico"
1866
  msgstr ""
1867
 
1868
- #: inc/helpers/helper-misc.php:372
1869
  msgid "Qatar"
1870
  msgstr ""
1871
 
1872
- #: inc/helpers/helper-misc.php:373
1873
  msgid "Reunion"
1874
  msgstr ""
1875
 
1876
- #: inc/helpers/helper-misc.php:374
1877
  msgid "Romania"
1878
  msgstr ""
1879
 
1880
- #: inc/helpers/helper-misc.php:375
1881
  msgid "Russian Federation"
1882
  msgstr ""
1883
 
1884
- #: inc/helpers/helper-misc.php:376
1885
  msgid "Rwanda"
1886
  msgstr ""
1887
 
1888
- #: inc/helpers/helper-misc.php:377
1889
  msgid "Saint Kitts and Nevis"
1890
  msgstr ""
1891
 
1892
- #: inc/helpers/helper-misc.php:378
1893
  msgid "Saint Lucia"
1894
  msgstr ""
1895
 
1896
- #: inc/helpers/helper-misc.php:379
1897
  msgid "Saint Vincent and the Grenadines"
1898
  msgstr ""
1899
 
1900
- #: inc/helpers/helper-misc.php:380
1901
  msgid "Samoa"
1902
  msgstr ""
1903
 
1904
- #: inc/helpers/helper-misc.php:381
1905
  msgid "San Marino"
1906
  msgstr ""
1907
 
1908
- #: inc/helpers/helper-misc.php:382
1909
  msgid "Sao Tome and Principe"
1910
  msgstr ""
1911
 
1912
- #: inc/helpers/helper-misc.php:383
1913
  msgid "Saudi Arabia"
1914
  msgstr ""
1915
 
1916
- #: inc/helpers/helper-misc.php:384
1917
  msgid "Senegal"
1918
  msgstr ""
1919
 
1920
- #: inc/helpers/helper-misc.php:385
1921
  msgid "Seychelles"
1922
  msgstr ""
1923
 
1924
- #: inc/helpers/helper-misc.php:386
1925
  msgid "Sierra Leone"
1926
  msgstr ""
1927
 
1928
- #: inc/helpers/helper-misc.php:387
1929
  msgid "Singapore"
1930
  msgstr ""
1931
 
1932
- #: inc/helpers/helper-misc.php:388
1933
  msgid "Slovakia (Slovak Republic)"
1934
  msgstr ""
1935
 
1936
- #: inc/helpers/helper-misc.php:389
1937
  msgid "Slovenia"
1938
  msgstr ""
1939
 
1940
- #: inc/helpers/helper-misc.php:390
1941
  msgid "Solomon Islands"
1942
  msgstr ""
1943
 
1944
- #: inc/helpers/helper-misc.php:391
1945
  msgid "Somalia"
1946
  msgstr ""
1947
 
1948
- #: inc/helpers/helper-misc.php:392
1949
  msgid "South Africa"
1950
  msgstr ""
1951
 
1952
- #: inc/helpers/helper-misc.php:393
1953
  msgid "South Georgia and the South Sandwich Islands"
1954
  msgstr ""
1955
 
1956
- #: inc/helpers/helper-misc.php:394
1957
  msgid "Spain"
1958
  msgstr ""
1959
 
1960
- #: inc/helpers/helper-misc.php:395
1961
  msgid "Sri Lanka"
1962
  msgstr ""
1963
 
1964
- #: inc/helpers/helper-misc.php:396
1965
  msgid "St. Helena"
1966
  msgstr ""
1967
 
1968
- #: inc/helpers/helper-misc.php:397
1969
  msgid "St. Pierre and Miquelon"
1970
  msgstr ""
1971
 
1972
- #: inc/helpers/helper-misc.php:398
1973
  msgid "Sudan"
1974
  msgstr ""
1975
 
1976
- #: inc/helpers/helper-misc.php:399
1977
  msgid "Suriname"
1978
  msgstr ""
1979
 
1980
- #: inc/helpers/helper-misc.php:400
1981
  msgid "Svalbard and Jan Mayen Islands"
1982
  msgstr ""
1983
 
1984
- #: inc/helpers/helper-misc.php:401
1985
  msgid "Swaziland"
1986
  msgstr ""
1987
 
1988
- #: inc/helpers/helper-misc.php:402
1989
  msgid "Sweden"
1990
  msgstr ""
1991
 
1992
- #: inc/helpers/helper-misc.php:403
1993
  msgid "Switzerland"
1994
  msgstr ""
1995
 
1996
- #: inc/helpers/helper-misc.php:404
1997
  msgid "Syrian Arab Republic"
1998
  msgstr ""
1999
 
2000
- #: inc/helpers/helper-misc.php:405
2001
  msgid "Taiwan, Province of China"
2002
  msgstr ""
2003
 
2004
- #: inc/helpers/helper-misc.php:406
2005
  msgid "Tajikistan"
2006
  msgstr ""
2007
 
2008
- #: inc/helpers/helper-misc.php:407
2009
  msgid "Tanzania, United Republic of"
2010
  msgstr ""
2011
 
2012
- #: inc/helpers/helper-misc.php:408
2013
  msgid "Thailand"
2014
  msgstr ""
2015
 
2016
- #: inc/helpers/helper-misc.php:409
2017
  msgid "Togo"
2018
  msgstr ""
2019
 
2020
- #: inc/helpers/helper-misc.php:410
2021
  msgid "Tokelau"
2022
  msgstr ""
2023
 
2024
- #: inc/helpers/helper-misc.php:411
2025
  msgid "Tonga"
2026
  msgstr ""
2027
 
2028
- #: inc/helpers/helper-misc.php:412
2029
  msgid "Trinidad and Tobago"
2030
  msgstr ""
2031
 
2032
- #: inc/helpers/helper-misc.php:413
2033
  msgid "Tunisia"
2034
  msgstr ""
2035
 
2036
- #: inc/helpers/helper-misc.php:414
2037
  msgid "Turkey"
2038
  msgstr ""
2039
 
2040
- #: inc/helpers/helper-misc.php:415
2041
  msgid "Turkmenistan"
2042
  msgstr ""
2043
 
2044
- #: inc/helpers/helper-misc.php:416
2045
  msgid "Turks and Caicos Islands"
2046
  msgstr ""
2047
 
2048
- #: inc/helpers/helper-misc.php:417
2049
  msgid "Tuvalu"
2050
  msgstr ""
2051
 
2052
- #: inc/helpers/helper-misc.php:418
2053
  msgid "Uganda"
2054
  msgstr ""
2055
 
2056
- #: inc/helpers/helper-misc.php:419
2057
  msgid "Ukraine"
2058
  msgstr ""
2059
 
2060
- #: inc/helpers/helper-misc.php:420
2061
  msgid "United Arab Emirates"
2062
  msgstr ""
2063
 
2064
- #: inc/helpers/helper-misc.php:421
2065
  msgid "United Kingdom"
2066
  msgstr ""
2067
 
2068
- #: inc/helpers/helper-misc.php:422
2069
  msgid "United States"
2070
  msgstr ""
2071
 
2072
- #: inc/helpers/helper-misc.php:423
2073
  msgid "United States Minor Outlying Islands"
2074
  msgstr ""
2075
 
2076
- #: inc/helpers/helper-misc.php:424
2077
  msgid "Uruguay"
2078
  msgstr ""
2079
 
2080
- #: inc/helpers/helper-misc.php:425
2081
  msgid "Uzbekistan"
2082
  msgstr ""
2083
 
2084
- #: inc/helpers/helper-misc.php:426
2085
  msgid "Vanuatu"
2086
  msgstr ""
2087
 
2088
- #: inc/helpers/helper-misc.php:427
2089
  msgid "Venezuela"
2090
  msgstr ""
2091
 
2092
- #: inc/helpers/helper-misc.php:428
2093
  msgid "Vietnam"
2094
  msgstr ""
2095
 
2096
- #: inc/helpers/helper-misc.php:429
2097
  msgid "Virgin Islands (British)"
2098
  msgstr ""
2099
 
2100
- #: inc/helpers/helper-misc.php:430
2101
  msgid "Virgin Islands (U.S.)"
2102
  msgstr ""
2103
 
2104
- #: inc/helpers/helper-misc.php:431
2105
  msgid "Wallis and Futuna Islands"
2106
  msgstr ""
2107
 
2108
- #: inc/helpers/helper-misc.php:432
2109
  msgid "Western Sahara"
2110
  msgstr ""
2111
 
2112
- #: inc/helpers/helper-misc.php:433
2113
  msgid "Yemen"
2114
  msgstr ""
2115
 
2116
- #: inc/helpers/helper-misc.php:434
2117
  msgid "Yugoslavia"
2118
  msgstr ""
2119
 
2120
- #: inc/helpers/helper-misc.php:435
2121
  msgid "Zambia"
2122
  msgstr ""
2123
 
2124
- #: inc/helpers/helper-misc.php:436
2125
  msgid "Zimbabwe"
2126
  msgstr ""
2127
 
@@ -2137,11 +2171,11 @@ msgstr ""
2137
  msgid "Insert HappyForm"
2138
  msgstr ""
2139
 
2140
- #: inc/templates/admin-message-edit.php:19
2141
  msgid "Previous response"
2142
  msgstr ""
2143
 
2144
- #: inc/templates/admin-message-edit.php:21
2145
  msgid "Next response"
2146
  msgstr ""
2147
 
@@ -2355,7 +2389,7 @@ msgid "Save form"
2355
  msgstr ""
2356
 
2357
  #: inc/templates/customize-form-steps.php:9
2358
- #: inc/templates/parts/customize-scale.php:60
2359
  msgid "Step"
2360
  msgstr ""
2361
 
@@ -2457,7 +2491,7 @@ msgstr ""
2457
  #: inc/templates/parts/customize-checkbox.php:17
2458
  #: inc/templates/parts/customize-checkbox.php:60
2459
  #: inc/templates/parts/customize-date.php:17
2460
- #: inc/templates/parts/customize-date.php:91
2461
  #: inc/templates/parts/customize-email.php:19
2462
  #: inc/templates/parts/customize-email.php:51
2463
  #: inc/templates/parts/customize-multi-line-text.php:19
@@ -2465,7 +2499,7 @@ msgstr ""
2465
  #: inc/templates/parts/customize-number.php:19
2466
  #: inc/templates/parts/customize-number.php:80
2467
  #: inc/templates/parts/customize-phone.php:19
2468
- #: inc/templates/parts/customize-phone.php:71
2469
  #: inc/templates/parts/customize-placeholder.php:17
2470
  #: inc/templates/parts/customize-placeholder.php:35
2471
  #: inc/templates/parts/customize-radio.php:17
@@ -2473,7 +2507,7 @@ msgstr ""
2473
  #: inc/templates/parts/customize-rating.php:17
2474
  #: inc/templates/parts/customize-rating.php:45
2475
  #: inc/templates/parts/customize-scale.php:17
2476
- #: inc/templates/parts/customize-scale.php:77
2477
  #: inc/templates/parts/customize-select.php:17
2478
  #: inc/templates/parts/customize-select.php:54
2479
  #: inc/templates/parts/customize-single-line-text.php:19
@@ -2527,16 +2561,16 @@ msgstr ""
2527
  #: inc/templates/parts/customize-address.php:38
2528
  #: inc/templates/parts/customize-address.php:76
2529
  #: inc/templates/parts/customize-checkbox.php:53
2530
- #: inc/templates/parts/customize-date.php:84
2531
  #: inc/templates/parts/customize-email.php:44
2532
  #: inc/templates/parts/customize-legal.php:6
2533
  #: inc/templates/parts/customize-multi-line-text.php:44
2534
  #: inc/templates/parts/customize-number.php:73
2535
- #: inc/templates/parts/customize-phone.php:64
2536
  #: inc/templates/parts/customize-placeholder.php:28
2537
  #: inc/templates/parts/customize-radio.php:53
2538
  #: inc/templates/parts/customize-rating.php:38
2539
- #: inc/templates/parts/customize-scale.php:70
2540
  #: inc/templates/parts/customize-select.php:47
2541
  #: inc/templates/parts/customize-single-line-text.php:44
2542
  #: inc/templates/parts/customize-title.php:38
@@ -2589,7 +2623,7 @@ msgstr ""
2589
  #: inc/templates/parts/customize-phone.php:37
2590
  #: inc/templates/parts/customize-radio.php:31
2591
  #: inc/templates/parts/customize-rating.php:31
2592
- #: inc/templates/parts/customize-scale.php:45
2593
  #: inc/templates/parts/customize-select.php:31
2594
  #: inc/templates/parts/customize-single-line-text.php:37
2595
  #: inc/templates/parts/customize-title.php:31
@@ -2599,16 +2633,16 @@ msgstr ""
2599
 
2600
  #: inc/templates/parts/customize-address.php:77
2601
  #: inc/templates/parts/customize-checkbox.php:54
2602
- #: inc/templates/parts/customize-date.php:85
2603
  #: inc/templates/parts/customize-email.php:45
2604
  #: inc/templates/parts/customize-legal.php:7
2605
  #: inc/templates/parts/customize-multi-line-text.php:45
2606
  #: inc/templates/parts/customize-number.php:74
2607
- #: inc/templates/parts/customize-phone.php:65
2608
  #: inc/templates/parts/customize-placeholder.php:29
2609
  #: inc/templates/parts/customize-radio.php:54
2610
  #: inc/templates/parts/customize-rating.php:39
2611
- #: inc/templates/parts/customize-scale.php:71
2612
  #: inc/templates/parts/customize-select.php:48
2613
  #: inc/templates/parts/customize-single-line-text.php:45
2614
  #: inc/templates/parts/customize-title.php:39
@@ -2618,16 +2652,16 @@ msgstr ""
2618
 
2619
  #: inc/templates/parts/customize-address.php:78
2620
  #: inc/templates/parts/customize-checkbox.php:55
2621
- #: inc/templates/parts/customize-date.php:86
2622
  #: inc/templates/parts/customize-email.php:46
2623
  #: inc/templates/parts/customize-legal.php:8
2624
  #: inc/templates/parts/customize-multi-line-text.php:46
2625
  #: inc/templates/parts/customize-number.php:75
2626
- #: inc/templates/parts/customize-phone.php:66
2627
  #: inc/templates/parts/customize-placeholder.php:30
2628
  #: inc/templates/parts/customize-radio.php:55
2629
  #: inc/templates/parts/customize-rating.php:40
2630
- #: inc/templates/parts/customize-scale.php:72
2631
  #: inc/templates/parts/customize-select.php:49
2632
  #: inc/templates/parts/customize-single-line-text.php:46
2633
  #: inc/templates/parts/customize-title.php:40
@@ -2637,16 +2671,16 @@ msgstr ""
2637
 
2638
  #: inc/templates/parts/customize-address.php:82
2639
  #: inc/templates/parts/customize-checkbox.php:64
2640
- #: inc/templates/parts/customize-date.php:95
2641
  #: inc/templates/parts/customize-email.php:55
2642
  #: inc/templates/parts/customize-legal.php:17
2643
  #: inc/templates/parts/customize-multi-line-text.php:55
2644
  #: inc/templates/parts/customize-number.php:84
2645
- #: inc/templates/parts/customize-phone.php:75
2646
  #: inc/templates/parts/customize-placeholder.php:39
2647
  #: inc/templates/parts/customize-radio.php:64
2648
  #: inc/templates/parts/customize-rating.php:49
2649
- #: inc/templates/parts/customize-scale.php:81
2650
  #: inc/templates/parts/customize-select.php:58
2651
  #: inc/templates/parts/customize-single-line-text.php:55
2652
  #: inc/templates/parts/customize-title.php:49
@@ -2700,7 +2734,7 @@ msgid "Time"
2700
  msgstr ""
2701
 
2702
  #: inc/templates/parts/customize-date.php:38
2703
- #: inc/templates/parts/customize-scale.php:30
2704
  msgid "Default value"
2705
  msgstr ""
2706
 
@@ -2712,35 +2746,51 @@ msgstr ""
2712
  msgid "Current date and time"
2713
  msgstr ""
2714
 
2715
- #: inc/templates/parts/customize-date.php:52
2716
- msgid "Min year"
 
 
 
 
 
 
 
 
 
 
 
 
2717
  msgstr ""
2718
 
2719
- #: inc/templates/parts/customize-date.php:56
2720
- msgid "Max year"
2721
  msgstr ""
2722
 
2723
- #: inc/templates/parts/customize-date.php:62
 
 
 
 
2724
  msgid "Min hour"
2725
  msgstr ""
2726
 
2727
- #: inc/templates/parts/customize-date.php:66
2728
  msgid "Max hour"
2729
  msgstr ""
2730
 
2731
- #: inc/templates/parts/customize-date.php:71
2732
  msgid "Minute step"
2733
  msgstr ""
2734
 
2735
- #: inc/templates/parts/customize-date.php:75
2736
  msgid "Time format"
2737
  msgstr ""
2738
 
2739
- #: inc/templates/parts/customize-date.php:77
2740
  msgid "12h"
2741
  msgstr ""
2742
 
2743
- #: inc/templates/parts/customize-date.php:78
2744
  msgid "24h"
2745
  msgstr ""
2746
 
@@ -2753,13 +2803,13 @@ msgstr ""
2753
 
2754
  #: inc/templates/parts/customize-email.php:60
2755
  #: inc/templates/parts/customize-number.php:89
2756
- #: inc/templates/parts/customize-phone.php:80
2757
  msgid "Require confirmation of the value"
2758
  msgstr ""
2759
 
2760
  #: inc/templates/parts/customize-email.php:64
2761
  #: inc/templates/parts/customize-number.php:93
2762
- #: inc/templates/parts/customize-phone.php:84
2763
  msgid "Confirmation field title"
2764
  msgstr ""
2765
 
@@ -2768,12 +2818,10 @@ msgid "Legal text"
2768
  msgstr ""
2769
 
2770
  #: inc/templates/parts/customize-number.php:37
2771
- #: inc/templates/parts/customize-scale.php:35
2772
  msgid "Minimum accepted value"
2773
  msgstr ""
2774
 
2775
  #: inc/templates/parts/customize-number.php:41
2776
- #: inc/templates/parts/customize-scale.php:39
2777
  msgid "Maximum accepted value"
2778
  msgstr ""
2779
 
@@ -2798,21 +2846,36 @@ msgstr ""
2798
  msgid "Pre-format phone number region"
2799
  msgstr ""
2800
 
2801
- #: inc/templates/parts/customize-phone.php:50
2802
- #: inc/templates/parts/frontend-title.php:7
2803
- msgid "Select"
2804
- msgstr ""
2805
-
2806
  #: inc/templates/parts/customize-radio.php:81
2807
  #: inc/templates/parts/customize-select.php:71
2808
  msgid "Make this option default"
2809
  msgstr ""
2810
 
2811
- #: inc/templates/parts/customize-scale.php:51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2812
  msgid "Minimum value label"
2813
  msgstr ""
2814
 
2815
- #: inc/templates/parts/customize-scale.php:55
2816
  msgid "Maximum value label"
2817
  msgstr ""
2818
 
@@ -2833,37 +2896,40 @@ msgstr ""
2833
  msgid "City"
2834
  msgstr ""
2835
 
2836
- #: inc/templates/parts/frontend-date.php:16
2837
- msgid "Month"
2838
  msgstr ""
2839
 
2840
- #: inc/templates/parts/frontend-date.php:27
2841
- msgid "Day"
2842
  msgstr ""
2843
 
2844
- #: inc/templates/parts/frontend-date.php:38
2845
  msgid "Year"
2846
  msgstr ""
2847
 
2848
- #: inc/templates/parts/frontend-date.php:83
2849
- msgid "AM"
2850
  msgstr ""
2851
 
2852
- #: inc/templates/parts/frontend-date.php:84
2853
- msgid "PM"
2854
  msgstr ""
2855
 
2856
- #: inc/templates/parts/frontend-email.php:22
2857
- #: inc/templates/parts/frontend-number.php:26
2858
- #: inc/templates/parts/frontend-phone.php:22
2859
- msgid "Fields do not match."
2860
  msgstr ""
2861
 
2862
  #: inc/templates/parts/frontend-rating.php:10
2863
  msgid "Stars"
2864
  msgstr ""
2865
 
2866
- #: inc/templates/preview-form-edit.php:11
 
 
 
 
 
2867
  msgid ""
2868
  "This is a preview of your new HappyForm. Once you’ve finished building, you "
2869
  "can add this form to any Page, Post and Widget area. Have questions? <a "
2
  # This file is distributed under the same license as the HappyForms package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: HappyForms 1.5.0\n"
6
  "Report-Msgid-Bugs-To: https://thethemefoundry.com/support/\n"
7
+ "POT-Creation-Date: 2018-06-21 13:17:32+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
13
  "Language-Team: The Theme Foundry\n"
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
+ #: inc/classes/class-form-admin.php:155
17
+ #: inc/classes/class-form-controller.php:74
18
  msgid "View form"
19
  msgstr ""
20
 
21
+ #: inc/classes/class-form-admin.php:160
22
  msgid "Preview form"
23
  msgstr ""
24
 
25
+ #: inc/classes/class-form-admin.php:165 inc/classes/class-form-admin.php:168
26
  msgid "Form updated."
27
  msgstr ""
28
 
29
+ #: inc/classes/class-form-admin.php:166 inc/classes/class-message-admin.php:193
30
  msgid "Custom field updated."
31
  msgstr ""
32
 
33
+ #: inc/classes/class-form-admin.php:167 inc/classes/class-message-admin.php:194
34
  msgid "Custom field deleted."
35
  msgstr ""
36
 
37
+ #: inc/classes/class-form-admin.php:169
38
  msgid "Form restored to revision from %s."
39
  msgstr ""
40
 
41
+ #: inc/classes/class-form-admin.php:170
42
  msgid "Form published."
43
  msgstr ""
44
 
45
+ #: inc/classes/class-form-admin.php:171
46
+ #: inc/classes/class-wp-customize-form-manager.php:164
47
  msgid "Form saved."
48
  msgstr ""
49
 
50
+ #: inc/classes/class-form-admin.php:172
51
  msgid "Form submitted."
52
  msgstr ""
53
 
54
+ #: inc/classes/class-form-admin.php:173
55
  msgid "Form scheduled."
56
  msgstr ""
57
 
58
+ #: inc/classes/class-form-admin.php:174
59
  msgid "Form draft updated."
60
  msgstr ""
61
 
62
+ #: inc/classes/class-form-admin.php:197
63
  msgid "%s form updated."
64
  msgid_plural "%s forms updated."
65
  msgstr[0] ""
66
  msgstr[1] ""
67
 
68
+ #: inc/classes/class-form-admin.php:198
69
  msgid "%s form not updated, somebody is editing it."
70
  msgid_plural "%s forms not updated, somebody is editing them."
71
  msgstr[0] ""
72
  msgstr[1] ""
73
 
74
+ #: inc/classes/class-form-admin.php:199
75
  msgid "%s form permanently deleted."
76
  msgid_plural "%s forms permanently deleted."
77
  msgstr[0] ""
78
  msgstr[1] ""
79
 
80
+ #: inc/classes/class-form-admin.php:200
81
  msgid "%s form moved to the Trash."
82
  msgid_plural "%s forms moved to the Trash."
83
  msgstr[0] ""
84
  msgstr[1] ""
85
 
86
+ #: inc/classes/class-form-admin.php:201
87
  msgid "%s form restored from the Trash."
88
  msgid_plural "%s forms restored from the Trash."
89
  msgstr[0] ""
90
  msgstr[1] ""
91
 
92
+ #: inc/classes/class-form-admin.php:254
93
  msgid "Shortcode"
94
  msgstr ""
95
 
96
+ #: inc/classes/class-form-admin.php:255
97
  msgid "Author"
98
  msgstr ""
99
 
100
+ #: inc/classes/class-form-admin.php:304
101
  msgid "Copy to clipboard"
102
  msgstr ""
103
 
104
+ #: inc/classes/class-form-admin.php:358 inc/classes/class-message-admin.php:624
105
  msgid "Edit"
106
  msgstr ""
107
 
108
+ #: inc/classes/class-form-admin.php:362
109
  #: inc/templates/customize-form-item.php:27
110
  #: inc/templates/customize-form-part-footer.php:4
111
  msgid "Duplicate"
112
  msgstr ""
113
 
114
+ #: inc/classes/class-form-admin.php:366 inc/classes/class-message-admin.php:552
115
  #: inc/classes/class-message-admin.php:805
116
  msgid "Trash"
117
  msgstr ""
118
 
119
+ #: inc/classes/class-form-admin.php:411
120
  msgid "Form duplicated succesfully."
121
  msgstr ""
122
 
123
+ #: inc/classes/class-form-admin.php:435
124
  msgid " Copy"
125
  msgstr ""
126
 
127
+ #: inc/classes/class-form-controller.php:69
128
+ #: inc/classes/class-form-controller.php:79
129
  #: inc/classes/class-happyforms-plugin.php:144
130
  #: inc/classes/class-happyforms-plugin.php:145
131
  msgid "All Forms"
132
  msgstr ""
133
 
134
+ #: inc/classes/class-form-controller.php:70
135
  #: inc/classes/class-message-admin.php:317
136
  #: inc/classes/class-message-admin.php:790
137
  msgid "Form"
138
  msgstr ""
139
 
140
+ #: inc/classes/class-form-controller.php:71
141
+ #: inc/classes/class-form-controller.php:73
142
  msgid "Build form"
143
  msgstr ""
144
 
145
+ #: inc/classes/class-form-controller.php:72
146
  msgid "Edit form"
147
  msgstr ""
148
 
149
+ #: inc/classes/class-form-controller.php:75
150
  msgid "View forms"
151
  msgstr ""
152
 
153
+ #: inc/classes/class-form-controller.php:76
154
  msgid "Search Forms"
155
  msgstr ""
156
 
157
+ #: inc/classes/class-form-controller.php:77
158
  msgid "No form found"
159
  msgstr ""
160
 
161
+ #: inc/classes/class-form-controller.php:78
162
  msgid "No forms found in Trash"
163
  msgstr ""
164
 
165
+ #: inc/classes/class-form-controller.php:173
166
  msgid "Untitled form"
167
  msgstr ""
168
 
169
+ #: inc/classes/class-form-controller.php:198
170
  msgid "You received a new message"
171
  msgstr ""
172
 
173
+ #: inc/classes/class-form-controller.php:202
174
+ #: inc/classes/class-form-controller.php:210
175
  msgid ""
176
  "Your message has been successfully sent. We appreciate you contacting us "
177
  "and we’ll be in touch soon."
178
  msgstr ""
179
 
180
+ #: inc/classes/class-form-controller.php:206
181
  msgid "We received your message"
182
  msgstr ""
183
 
184
+ #: inc/classes/class-form-controller.php:222
185
  msgid "Submit Form"
186
  msgstr ""
187
 
188
+ #: inc/classes/class-form-controller.php:738
189
+ #: inc/classes/class-message-controller.php:236
190
  msgid "Your submission contains errors."
191
  msgstr ""
192
 
223
  #: inc/classes/class-form-styles.php:91 inc/classes/class-form-styles.php:120
224
  #: inc/classes/class-form-styles.php:168 inc/classes/class-form-styles.php:252
225
  #: inc/templates/parts/customize-date.php:30
226
+ #: inc/templates/parts/customize-date.php:51
227
  msgid "Show"
228
  msgstr ""
229
 
488
  #: inc/classes/class-form-styles.php:663
489
  #: inc/templates/parts/customize-address.php:74
490
  #: inc/templates/parts/customize-checkbox.php:51
491
+ #: inc/templates/parts/customize-date.php:97
492
  #: inc/templates/parts/customize-email.php:42
493
  #: inc/templates/parts/customize-legal.php:4
494
  #: inc/templates/parts/customize-multi-line-text.php:42
495
  #: inc/templates/parts/customize-number.php:71
496
+ #: inc/templates/parts/customize-phone.php:60
497
  #: inc/templates/parts/customize-placeholder.php:26
498
  #: inc/templates/parts/customize-radio.php:51
499
  #: inc/templates/parts/customize-rating.php:36
500
+ #: inc/templates/parts/customize-scale.php:83
501
  #: inc/templates/parts/customize-select.php:45
502
  #: inc/templates/parts/customize-single-line-text.php:42
503
  #: inc/templates/parts/customize-title.php:36
518
  msgstr ""
519
 
520
  #: inc/classes/class-form-styles.php:707
521
+ #: inc/classes/parts/class-part-multi-line-text.php:28
522
+ #: inc/classes/parts/class-part-single-line-text.php:28
523
  #: inc/templates/parts/customize-placeholder.php:21
524
  msgid "Text"
525
  msgstr ""
742
  msgid "No response found in Trash"
743
  msgstr ""
744
 
 
 
 
 
745
  #: inc/classes/class-tracking.php:168
746
  msgid "Sorry, you are not allowed to access this page."
747
  msgstr ""
772
  msgid "Error description"
773
  msgstr ""
774
 
775
+ #: inc/classes/class-wp-customize-form-manager.php:165
776
  msgid "Now, there are couple of ways to embed it to your content. Here goes..."
777
  msgstr ""
778
 
779
+ #: inc/classes/class-wp-customize-form-manager.php:166
780
  msgid "Add to your page / post content"
781
  msgstr ""
782
 
783
+ #: inc/classes/class-wp-customize-form-manager.php:167
784
  msgid ""
785
  "In your Edit Post / Edit Page screen, click the <b>Add HappyForms</b> "
786
  "button right above your toolbar. A modal window will appear."
787
  msgstr ""
788
 
789
+ #: inc/classes/class-wp-customize-form-manager.php:167
790
  msgid "Select a form in the dropdown, then click <b>Insert</b>."
791
  msgstr ""
792
 
793
+ #: inc/classes/class-wp-customize-form-manager.php:167
794
  msgid ""
795
  "That's it! You'll notice the shortcode was added to your content. Your form "
796
  "will show up there."
797
  msgstr ""
798
 
799
+ #: inc/classes/class-wp-customize-form-manager.php:168
800
  msgid "Use the HappyForms widget"
801
  msgstr ""
802
 
803
+ #: inc/classes/class-wp-customize-form-manager.php:170
804
  msgid ""
805
  "Head over to <b>Appearance</b> &rarr; <b><a href=\"%s\">Widgets</a></b> "
806
  "screen."
807
  msgstr ""
808
 
809
+ #: inc/classes/class-wp-customize-form-manager.php:171
810
  msgid "Drag the HappyForms widget to your sidebar."
811
  msgstr ""
812
 
813
+ #: inc/classes/class-wp-customize-form-manager.php:172
814
  msgid "Select a form in the Form dropdown."
815
  msgstr ""
816
 
817
+ #: inc/classes/class-wp-customize-form-manager.php:173
818
  msgid "All done!"
819
  msgstr ""
820
 
821
+ #: inc/classes/class-wp-customize-form-manager.php:175
822
  msgid ""
823
  "Looking for a full documentation? Head over to our <a href=\"%s\" "
824
  "target=\"_blank\">Help Guide</a>."
825
  msgstr ""
826
 
827
+ #: inc/classes/class-wp-customize-form-manager.php:182
828
  msgid ""
829
  "Form saved. You can add this form to any Page, Post and Widget area. Have "
830
  "questions? <a href=\"%s\" target=\"_blank\">Ask for help in our support "
832
  msgstr ""
833
 
834
  #: inc/classes/parts/class-part-address.php:13
835
+ #: inc/classes/parts/class-part-address.php:42
836
  msgid "Address"
837
  msgstr ""
838
 
840
  msgid "For geographical locations. Includes Google Maps intergration."
841
  msgstr ""
842
 
843
+ #: inc/classes/parts/class-part-address.php:192
844
+ #: inc/classes/parts/class-part-checkbox.php:165
845
+ #: inc/classes/parts/class-part-date.php:193
846
+ #: inc/classes/parts/class-part-email.php:142
847
+ #: inc/classes/parts/class-part-email.php:146
848
+ #: inc/classes/parts/class-part-legal.php:111
849
+ #: inc/classes/parts/class-part-multi-line-text.php:141
850
+ #: inc/classes/parts/class-part-number.php:175
851
+ #: inc/classes/parts/class-part-number.php:179
852
+ #: inc/classes/parts/class-part-phone.php:404
853
+ #: inc/classes/parts/class-part-phone.php:408
854
+ #: inc/classes/parts/class-part-radio.php:165
855
+ #: inc/classes/parts/class-part-rating.php:125
856
+ #: inc/classes/parts/class-part-scale.php:163
857
+ #: inc/classes/parts/class-part-select.php:157
858
+ #: inc/classes/parts/class-part-single-line-text.php:124
859
+ #: inc/classes/parts/class-part-title.php:154
860
+ #: inc/classes/parts/class-part-website-url.php:124
861
  msgid "This field is required."
862
  msgstr ""
863
 
869
  msgid "For checkboxes allowing multiple selections."
870
  msgstr ""
871
 
872
+ #: inc/classes/parts/class-part-checkbox.php:29
873
  #: inc/classes/parts/class-part-radio.php:29
874
  #: inc/templates/parts/customize-checkbox.php:36
875
  #: inc/templates/parts/customize-radio.php:36
877
  msgid "Options"
878
  msgstr ""
879
 
880
+ #: inc/classes/parts/class-part-checkbox.php:174
881
  msgid "Checkbox values are not valid."
882
  msgstr ""
883
 
889
  msgid "For formatted day, month, year and or time fields."
890
  msgstr ""
891
 
892
+ #: inc/classes/parts/class-part-date.php:31
893
  #: inc/templates/parts/customize-date.php:32
894
  msgid "Date"
895
  msgstr ""
896
 
897
+ #: inc/classes/parts/class-part-date.php:225
898
  msgid "Not a valid date."
899
  msgstr ""
900
 
901
+ #: inc/classes/parts/class-part-date.php:237
902
  msgid "Hour input does not match minimum and maximum value allowed."
903
  msgstr ""
904
 
905
+ #: inc/classes/parts/class-part-date.php:250
906
  msgid "Year input does not match maximum value allowed."
907
  msgstr ""
908
 
909
  #: inc/classes/parts/class-part-email.php:8
910
+ #: inc/classes/parts/class-part-email.php:30
911
  msgid "Email"
912
  msgstr ""
913
 
915
  msgid "For formatted email addresses. The '@' symbol is required."
916
  msgstr ""
917
 
918
+ #: inc/classes/parts/class-part-email.php:50
919
  msgid "Confirm Email"
920
  msgstr ""
921
 
922
+ #: inc/classes/parts/class-part-email.php:150
923
  msgid "Not a valid e-mail address."
924
  msgstr ""
925
 
926
+ #: inc/classes/parts/class-part-email.php:154
 
 
 
 
 
 
927
  msgid "Email and confirmation email are not matching."
928
  msgstr ""
929
 
940
  msgid "I accept terms and conditions."
941
  msgstr ""
942
 
943
+ #: inc/classes/parts/class-part-legal.php:116
944
  msgid "Please accept terms before proceeding."
945
  msgstr ""
946
 
953
  msgstr ""
954
 
955
  #: inc/classes/parts/class-part-number.php:8
956
+ #: inc/classes/parts/class-part-number.php:31
957
  msgid "Number"
958
  msgstr ""
959
 
961
  msgid "For numeric fields."
962
  msgstr ""
963
 
964
+ #: inc/classes/parts/class-part-number.php:87
 
965
  msgid "Confirm Number"
966
  msgstr ""
967
 
968
+ #: inc/classes/parts/class-part-number.php:183
969
+ #: inc/classes/parts/class-part-phone.php:412
 
 
 
 
 
 
 
 
970
  msgid "Number and confirmation number are not matching."
971
  msgstr ""
972
 
973
  #: inc/classes/parts/class-part-phone.php:8
974
+ #: inc/classes/parts/class-part-phone.php:31
975
  msgid "Phone"
976
  msgstr ""
977
 
979
  msgid "For phone numbers. Includes country specific formatting."
980
  msgstr ""
981
 
982
+ #: inc/classes/parts/class-part-phone.php:71
983
+ msgid "Confirm Phone"
984
+ msgstr ""
985
+
986
  #: inc/classes/parts/class-part-placeholder.php:9
987
  msgid "For adding helper text, horizontal rules and extra space."
988
  msgstr ""
995
  msgid "For radio buttons allowing one selection."
996
  msgstr ""
997
 
998
+ #: inc/classes/parts/class-part-radio.php:172
999
  msgid "Radio values are not valid."
1000
  msgstr ""
1001
 
1002
  #: inc/classes/parts/class-part-rating.php:9
1003
+ #: inc/classes/parts/class-part-rating.php:29
1004
  msgid "Rating"
1005
  msgstr ""
1006
 
1008
  msgid "For collecting opinions using a zero to five star scale."
1009
  msgstr ""
1010
 
1011
+ #: inc/classes/parts/class-part-rating.php:130
1012
  msgid "Value should be between 1 and 5."
1013
  msgstr ""
1014
 
1015
  #: inc/classes/parts/class-part-scale.php:8
1016
+ #: inc/classes/parts/class-part-scale.php:30
1017
  msgid "Scale"
1018
  msgstr ""
1019
 
1021
  msgid "For collecting opinions using a horizontal slider."
1022
  msgstr ""
1023
 
 
 
 
 
1024
  #: inc/classes/parts/class-part-select.php:8
1025
  #: inc/classes/parts/class-part-select.php:26
1026
  msgid "Dropdown"
1030
  msgid "For selecting one option from a long list. Default value adjustable."
1031
  msgstr ""
1032
 
1033
+ #: inc/classes/parts/class-part-select.php:164
1034
  msgid "Select values are not valid."
1035
  msgstr ""
1036
 
1046
  msgid "For displaying personal honorifics."
1047
  msgstr ""
1048
 
1049
+ #: inc/classes/parts/class-part-title.php:94
1050
  msgid "Mr."
1051
  msgstr ""
1052
 
1053
+ #: inc/classes/parts/class-part-title.php:95
1054
  msgid "Mrs."
1055
  msgstr ""
1056
 
1057
+ #: inc/classes/parts/class-part-title.php:96
1058
  msgid "Ms."
1059
  msgstr ""
1060
 
1061
+ #: inc/classes/parts/class-part-title.php:97
1062
  msgid "Miss"
1063
  msgstr ""
1064
 
1065
+ #: inc/classes/parts/class-part-title.php:98
1066
  msgid "Prof."
1067
  msgstr ""
1068
 
1069
+ #: inc/classes/parts/class-part-title.php:99
1070
  msgid "Dr."
1071
  msgstr ""
1072
 
1073
+ #: inc/classes/parts/class-part-title.php:161
1074
  msgid "Values is not valid."
1075
  msgstr ""
1076
 
1077
  #: inc/classes/parts/class-part-website-url.php:8
1078
+ #: inc/classes/parts/class-part-website-url.php:28
1079
  msgid "Website Link"
1080
  msgstr ""
1081
 
1083
  msgid "For formatted website URLs."
1084
  msgstr ""
1085
 
1086
+ #: inc/classes/parts/class-part-website-url.php:129
1087
  msgid "Not a valid URL."
1088
  msgstr ""
1089
 
1090
+ #: inc/helpers/helper-activation.php:44
1091
  msgid "Sample Contact Form"
1092
  msgstr ""
1093
 
1094
+ #: inc/helpers/helper-activation.php:55
1095
  msgid "First name"
1096
  msgstr ""
1097
 
1098
+ #: inc/helpers/helper-activation.php:60
1099
  msgid "Last name"
1100
  msgstr ""
1101
 
1102
+ #: inc/helpers/helper-activation.php:65
1103
  msgid "What's your reason for contacting us?"
1104
  msgstr ""
1105
 
1106
+ #: inc/helpers/helper-activation.php:68
1107
  msgid "Need technical help"
1108
  msgstr ""
1109
 
1110
+ #: inc/helpers/helper-activation.php:71
1111
  msgid "Want to suggest a feature"
1112
  msgstr ""
1113
 
1114
+ #: inc/helpers/helper-activation.php:74
1115
  msgid "Asking about my account"
1116
  msgstr ""
1117
 
1118
+ #: inc/helpers/helper-activation.php:80
1119
  msgid "Age"
1120
  msgstr ""
1121
 
1122
+ #: inc/helpers/helper-activation.php:85
1123
  msgid "Your message"
1124
  msgstr ""
1125
 
1126
+ #: inc/helpers/helper-activation.php:117
1127
  msgid "It would be great if I could use Google ReCaptcha instead of Honeypot."
1128
  msgstr ""
1129
 
1130
+ #: inc/helpers/helper-activation.php:124
1131
  msgid "How do I embed a HappyForm in my sidebar?"
1132
  msgstr ""
1133
 
1134
+ #: inc/helpers/helper-activation.php:131
1135
  msgid "How can I access my premium upgrade credentials?"
1136
  msgstr ""
1137
 
1138
+ #: inc/helpers/helper-form-templates.php:721
1139
  msgid "Get my location"
1140
  msgstr ""
1141
 
1142
+ #: inc/helpers/helper-form-templates.php:721
1143
  msgid "Fetching location…"
1144
  msgstr ""
1145
 
1146
+ #: inc/helpers/helper-form-templates.php:732
1147
+ msgid "January"
1148
+ msgstr ""
1149
+
1150
+ #: inc/helpers/helper-form-templates.php:733
1151
+ msgid "February"
1152
+ msgstr ""
1153
+
1154
+ #: inc/helpers/helper-form-templates.php:734
1155
+ msgid "March"
1156
+ msgstr ""
1157
+
1158
+ #: inc/helpers/helper-form-templates.php:735
1159
+ msgid "April"
1160
+ msgstr ""
1161
+
1162
+ #: inc/helpers/helper-form-templates.php:736
1163
+ msgid "May"
1164
+ msgstr ""
1165
+
1166
+ #: inc/helpers/helper-form-templates.php:737
1167
+ msgid "June"
1168
+ msgstr ""
1169
+
1170
+ #: inc/helpers/helper-form-templates.php:738
1171
+ msgid "July"
1172
+ msgstr ""
1173
+
1174
+ #: inc/helpers/helper-form-templates.php:739
1175
+ msgid "August"
1176
+ msgstr ""
1177
+
1178
+ #: inc/helpers/helper-form-templates.php:740
1179
+ msgid "September"
1180
+ msgstr ""
1181
+
1182
+ #: inc/helpers/helper-form-templates.php:741
1183
+ msgid "October"
1184
+ msgstr ""
1185
+
1186
+ #: inc/helpers/helper-form-templates.php:742
1187
+ msgid "November"
1188
+ msgstr ""
1189
+
1190
+ #: inc/helpers/helper-form-templates.php:743
1191
+ msgid "December"
1192
+ msgstr ""
1193
+
1194
+ #: inc/helpers/helper-misc.php:166
1195
  msgid "How are we doing? Please rate"
1196
  msgstr ""
1197
 
1198
+ #: inc/helpers/helper-misc.php:166
1199
  msgid "on"
1200
  msgstr ""
1201
 
1202
+ #: inc/helpers/helper-misc.php:166
1203
  msgid "to help us spread the word."
1204
  msgstr ""
1205
 
1206
+ #: inc/helpers/helper-misc.php:220
1207
  msgid "Afghanistan"
1208
  msgstr ""
1209
 
1210
+ #: inc/helpers/helper-misc.php:221
1211
  msgid "Albania"
1212
  msgstr ""
1213
 
1214
+ #: inc/helpers/helper-misc.php:222
1215
  msgid "Algeria"
1216
  msgstr ""
1217
 
1218
+ #: inc/helpers/helper-misc.php:223
1219
  msgid "American Samoa"
1220
  msgstr ""
1221
 
1222
+ #: inc/helpers/helper-misc.php:224
1223
  msgid "Andorra"
1224
  msgstr ""
1225
 
1226
+ #: inc/helpers/helper-misc.php:225
1227
  msgid "Angola"
1228
  msgstr ""
1229
 
1230
+ #: inc/helpers/helper-misc.php:226
1231
  msgid "Anguilla"
1232
  msgstr ""
1233
 
1234
+ #: inc/helpers/helper-misc.php:227
1235
  msgid "Antarctica"
1236
  msgstr ""
1237
 
1238
+ #: inc/helpers/helper-misc.php:228
1239
  msgid "Antigua and Barbuda"
1240
  msgstr ""
1241
 
1242
+ #: inc/helpers/helper-misc.php:229
1243
  msgid "Argentina"
1244
  msgstr ""
1245
 
1246
+ #: inc/helpers/helper-misc.php:230
1247
  msgid "Armenia"
1248
  msgstr ""
1249
 
1250
+ #: inc/helpers/helper-misc.php:231
1251
  msgid "Aruba"
1252
  msgstr ""
1253
 
1254
+ #: inc/helpers/helper-misc.php:232
1255
  msgid "Australia"
1256
  msgstr ""
1257
 
1258
+ #: inc/helpers/helper-misc.php:233
1259
  msgid "Austria"
1260
  msgstr ""
1261
 
1262
+ #: inc/helpers/helper-misc.php:234
1263
  msgid "Azerbaijan"
1264
  msgstr ""
1265
 
1266
+ #: inc/helpers/helper-misc.php:235
1267
  msgid "Bahamas"
1268
  msgstr ""
1269
 
1270
+ #: inc/helpers/helper-misc.php:236
1271
  msgid "Bahrain"
1272
  msgstr ""
1273
 
1274
+ #: inc/helpers/helper-misc.php:237
1275
  msgid "Bangladesh"
1276
  msgstr ""
1277
 
1278
+ #: inc/helpers/helper-misc.php:238
1279
  msgid "Barbados"
1280
  msgstr ""
1281
 
1282
+ #: inc/helpers/helper-misc.php:239
1283
  msgid "Belarus"
1284
  msgstr ""
1285
 
1286
+ #: inc/helpers/helper-misc.php:240
1287
  msgid "Belgium"
1288
  msgstr ""
1289
 
1290
+ #: inc/helpers/helper-misc.php:241
1291
  msgid "Belize"
1292
  msgstr ""
1293
 
1294
+ #: inc/helpers/helper-misc.php:242
1295
  msgid "Benin"
1296
  msgstr ""
1297
 
1298
+ #: inc/helpers/helper-misc.php:243
1299
  msgid "Bermuda"
1300
  msgstr ""
1301
 
1302
+ #: inc/helpers/helper-misc.php:244
1303
  msgid "Bhutan"
1304
  msgstr ""
1305
 
1306
+ #: inc/helpers/helper-misc.php:245
1307
  msgid "Bolivia"
1308
  msgstr ""
1309
 
1310
+ #: inc/helpers/helper-misc.php:246
1311
  msgid "Bosnia and Herzegowina"
1312
  msgstr ""
1313
 
1314
+ #: inc/helpers/helper-misc.php:247
1315
  msgid "Botswana"
1316
  msgstr ""
1317
 
1318
+ #: inc/helpers/helper-misc.php:248
1319
  msgid "Bouvet Island"
1320
  msgstr ""
1321
 
1322
+ #: inc/helpers/helper-misc.php:249
1323
  msgid "Brazil"
1324
  msgstr ""
1325
 
1326
+ #: inc/helpers/helper-misc.php:250
1327
  msgid "British Indian Ocean Territory"
1328
  msgstr ""
1329
 
1330
+ #: inc/helpers/helper-misc.php:251
1331
  msgid "Brunei Darussalam"
1332
  msgstr ""
1333
 
1334
+ #: inc/helpers/helper-misc.php:252
1335
  msgid "Bulgaria"
1336
  msgstr ""
1337
 
1338
+ #: inc/helpers/helper-misc.php:253
1339
  msgid "Burkina Faso"
1340
  msgstr ""
1341
 
1342
+ #: inc/helpers/helper-misc.php:254
1343
  msgid "Burundi"
1344
  msgstr ""
1345
 
1346
+ #: inc/helpers/helper-misc.php:255
1347
  msgid "Cambodia"
1348
  msgstr ""
1349
 
1350
+ #: inc/helpers/helper-misc.php:256
1351
  msgid "Cameroon"
1352
  msgstr ""
1353
 
1354
+ #: inc/helpers/helper-misc.php:257
1355
  msgid "Canada"
1356
  msgstr ""
1357
 
1358
+ #: inc/helpers/helper-misc.php:258
1359
  msgid "Cape Verde"
1360
  msgstr ""
1361
 
1362
+ #: inc/helpers/helper-misc.php:259
1363
  msgid "Cayman Islands"
1364
  msgstr ""
1365
 
1366
+ #: inc/helpers/helper-misc.php:260
1367
  msgid "Central African Republic"
1368
  msgstr ""
1369
 
1370
+ #: inc/helpers/helper-misc.php:261
1371
  msgid "Chad"
1372
  msgstr ""
1373
 
1374
+ #: inc/helpers/helper-misc.php:262
1375
  msgid "Chile"
1376
  msgstr ""
1377
 
1378
+ #: inc/helpers/helper-misc.php:263
1379
  msgid "China"
1380
  msgstr ""
1381
 
1382
+ #: inc/helpers/helper-misc.php:264
1383
  msgid "Christmas Island"
1384
  msgstr ""
1385
 
1386
+ #: inc/helpers/helper-misc.php:265
1387
  msgid "Cocos (Keeling) Islands"
1388
  msgstr ""
1389
 
1390
+ #: inc/helpers/helper-misc.php:266
1391
  msgid "Colombia"
1392
  msgstr ""
1393
 
1394
+ #: inc/helpers/helper-misc.php:267
1395
  msgid "Comoros"
1396
  msgstr ""
1397
 
1398
+ #: inc/helpers/helper-misc.php:268
1399
  msgid "Congo"
1400
  msgstr ""
1401
 
1402
+ #: inc/helpers/helper-misc.php:269
1403
  msgid "Congo, the Democratic Republic of the"
1404
  msgstr ""
1405
 
1406
+ #: inc/helpers/helper-misc.php:270
1407
  msgid "Cook Islands"
1408
  msgstr ""
1409
 
1410
+ #: inc/helpers/helper-misc.php:271
1411
  msgid "Costa Rica"
1412
  msgstr ""
1413
 
1414
+ #: inc/helpers/helper-misc.php:272
1415
  msgid "Cote d'Ivoire"
1416
  msgstr ""
1417
 
1418
+ #: inc/helpers/helper-misc.php:273
1419
  msgid "Croatia (Hrvatska)"
1420
  msgstr ""
1421
 
1422
+ #: inc/helpers/helper-misc.php:274
1423
  msgid "Cuba"
1424
  msgstr ""
1425
 
1426
+ #: inc/helpers/helper-misc.php:275
1427
  msgid "Cyprus"
1428
  msgstr ""
1429
 
1430
+ #: inc/helpers/helper-misc.php:276
1431
  msgid "Czech Republic"
1432
  msgstr ""
1433
 
1434
+ #: inc/helpers/helper-misc.php:277
1435
  msgid "Denmark"
1436
  msgstr ""
1437
 
1438
+ #: inc/helpers/helper-misc.php:278
1439
  msgid "Djibouti"
1440
  msgstr ""
1441
 
1442
+ #: inc/helpers/helper-misc.php:279
1443
  msgid "Dominica"
1444
  msgstr ""
1445
 
1446
+ #: inc/helpers/helper-misc.php:280
1447
  msgid "Dominican Republic"
1448
  msgstr ""
1449
 
1450
+ #: inc/helpers/helper-misc.php:281
1451
  msgid "East Timor"
1452
  msgstr ""
1453
 
1454
+ #: inc/helpers/helper-misc.php:282
1455
  msgid "Ecuador"
1456
  msgstr ""
1457
 
1458
+ #: inc/helpers/helper-misc.php:283
1459
  msgid "Egypt"
1460
  msgstr ""
1461
 
1462
+ #: inc/helpers/helper-misc.php:284
1463
  msgid "El Salvador"
1464
  msgstr ""
1465
 
1466
+ #: inc/helpers/helper-misc.php:285
1467
  msgid "Equatorial Guinea"
1468
  msgstr ""
1469
 
1470
+ #: inc/helpers/helper-misc.php:286
1471
  msgid "Eritrea"
1472
  msgstr ""
1473
 
1474
+ #: inc/helpers/helper-misc.php:287
1475
  msgid "Estonia"
1476
  msgstr ""
1477
 
1478
+ #: inc/helpers/helper-misc.php:288
1479
  msgid "Ethiopia"
1480
  msgstr ""
1481
 
1482
+ #: inc/helpers/helper-misc.php:289
1483
  msgid "Falkland Islands (Malvinas)"
1484
  msgstr ""
1485
 
1486
+ #: inc/helpers/helper-misc.php:290
1487
  msgid "Faroe Islands"
1488
  msgstr ""
1489
 
1490
+ #: inc/helpers/helper-misc.php:291
1491
  msgid "Fiji"
1492
  msgstr ""
1493
 
1494
+ #: inc/helpers/helper-misc.php:292
1495
  msgid "Finland"
1496
  msgstr ""
1497
 
1498
+ #: inc/helpers/helper-misc.php:293
1499
  msgid "France"
1500
  msgstr ""
1501
 
1502
+ #: inc/helpers/helper-misc.php:294
1503
  msgid "France Metropolitan"
1504
  msgstr ""
1505
 
1506
+ #: inc/helpers/helper-misc.php:295
1507
  msgid "French Guiana"
1508
  msgstr ""
1509
 
1510
+ #: inc/helpers/helper-misc.php:296
1511
  msgid "French Polynesia"
1512
  msgstr ""
1513
 
1514
+ #: inc/helpers/helper-misc.php:297
1515
  msgid "French Southern Territories"
1516
  msgstr ""
1517
 
1518
+ #: inc/helpers/helper-misc.php:298
1519
  msgid "Gabon"
1520
  msgstr ""
1521
 
1522
+ #: inc/helpers/helper-misc.php:299
1523
  msgid "Gambia"
1524
  msgstr ""
1525
 
1526
+ #: inc/helpers/helper-misc.php:300
1527
  msgid "Georgia"
1528
  msgstr ""
1529
 
1530
+ #: inc/helpers/helper-misc.php:301
1531
  msgid "Germany"
1532
  msgstr ""
1533
 
1534
+ #: inc/helpers/helper-misc.php:302
1535
  msgid "Ghana"
1536
  msgstr ""
1537
 
1538
+ #: inc/helpers/helper-misc.php:303
1539
  msgid "Gibraltar"
1540
  msgstr ""
1541
 
1542
+ #: inc/helpers/helper-misc.php:304
1543
  msgid "Greece"
1544
  msgstr ""
1545
 
1546
+ #: inc/helpers/helper-misc.php:305
1547
  msgid "Greenland"
1548
  msgstr ""
1549
 
1550
+ #: inc/helpers/helper-misc.php:306
1551
  msgid "Grenada"
1552
  msgstr ""
1553
 
1554
+ #: inc/helpers/helper-misc.php:307
1555
  msgid "Guadeloupe"
1556
  msgstr ""
1557
 
1558
+ #: inc/helpers/helper-misc.php:308
1559
  msgid "Guam"
1560
  msgstr ""
1561
 
1562
+ #: inc/helpers/helper-misc.php:309
1563
  msgid "Guatemala"
1564
  msgstr ""
1565
 
1566
+ #: inc/helpers/helper-misc.php:310
1567
  msgid "Guinea"
1568
  msgstr ""
1569
 
1570
+ #: inc/helpers/helper-misc.php:311
1571
  msgid "Guinea-Bissau"
1572
  msgstr ""
1573
 
1574
+ #: inc/helpers/helper-misc.php:312
1575
  msgid "Guyana"
1576
  msgstr ""
1577
 
1578
+ #: inc/helpers/helper-misc.php:313
1579
  msgid "Haiti"
1580
  msgstr ""
1581
 
1582
+ #: inc/helpers/helper-misc.php:314
1583
  msgid "Heard and Mc Donald Islands"
1584
  msgstr ""
1585
 
1586
+ #: inc/helpers/helper-misc.php:315
1587
  msgid "Holy See (Vatican City State)"
1588
  msgstr ""
1589
 
1590
+ #: inc/helpers/helper-misc.php:316
1591
  msgid "Honduras"
1592
  msgstr ""
1593
 
1594
+ #: inc/helpers/helper-misc.php:317
1595
  msgid "Hong Kong"
1596
  msgstr ""
1597
 
1598
+ #: inc/helpers/helper-misc.php:318
1599
  msgid "Hungary"
1600
  msgstr ""
1601
 
1602
+ #: inc/helpers/helper-misc.php:319
1603
  msgid "Iceland"
1604
  msgstr ""
1605
 
1606
+ #: inc/helpers/helper-misc.php:320
1607
  msgid "India"
1608
  msgstr ""
1609
 
1610
+ #: inc/helpers/helper-misc.php:321
1611
  msgid "Indonesia"
1612
  msgstr ""
1613
 
1614
+ #: inc/helpers/helper-misc.php:322
1615
  msgid "Iran (Islamic Republic of)"
1616
  msgstr ""
1617
 
1618
+ #: inc/helpers/helper-misc.php:323
1619
  msgid "Iraq"
1620
  msgstr ""
1621
 
1622
+ #: inc/helpers/helper-misc.php:324
1623
  msgid "Ireland"
1624
  msgstr ""
1625
 
1626
+ #: inc/helpers/helper-misc.php:325
1627
  msgid "Israel"
1628
  msgstr ""
1629
 
1630
+ #: inc/helpers/helper-misc.php:326
1631
  msgid "Italy"
1632
  msgstr ""
1633
 
1634
+ #: inc/helpers/helper-misc.php:327
1635
  msgid "Jamaica"
1636
  msgstr ""
1637
 
1638
+ #: inc/helpers/helper-misc.php:328
1639
  msgid "Japan"
1640
  msgstr ""
1641
 
1642
+ #: inc/helpers/helper-misc.php:329
1643
  msgid "Jordan"
1644
  msgstr ""
1645
 
1646
+ #: inc/helpers/helper-misc.php:330
1647
  msgid "Kazakhstan"
1648
  msgstr ""
1649
 
1650
+ #: inc/helpers/helper-misc.php:331
1651
  msgid "Kenya"
1652
  msgstr ""
1653
 
1654
+ #: inc/helpers/helper-misc.php:332
1655
  msgid "Kiribati"
1656
  msgstr ""
1657
 
1658
+ #: inc/helpers/helper-misc.php:333
1659
  msgid "Korea, Democratic People's Republic of"
1660
  msgstr ""
1661
 
1662
+ #: inc/helpers/helper-misc.php:334
1663
  msgid "Korea, Republic of"
1664
  msgstr ""
1665
 
1666
+ #: inc/helpers/helper-misc.php:335
1667
  msgid "Kuwait"
1668
  msgstr ""
1669
 
1670
+ #: inc/helpers/helper-misc.php:336
1671
  msgid "Kyrgyzstan"
1672
  msgstr ""
1673
 
1674
+ #: inc/helpers/helper-misc.php:337
1675
  msgid "Lao, People's Democratic Republic"
1676
  msgstr ""
1677
 
1678
+ #: inc/helpers/helper-misc.php:338
1679
  msgid "Latvia"
1680
  msgstr ""
1681
 
1682
+ #: inc/helpers/helper-misc.php:339
1683
  msgid "Lebanon"
1684
  msgstr ""
1685
 
1686
+ #: inc/helpers/helper-misc.php:340
1687
  msgid "Lesotho"
1688
  msgstr ""
1689
 
1690
+ #: inc/helpers/helper-misc.php:341
1691
  msgid "Liberia"
1692
  msgstr ""
1693
 
1694
+ #: inc/helpers/helper-misc.php:342
1695
  msgid "Libyan Arab Jamahiriya"
1696
  msgstr ""
1697
 
1698
+ #: inc/helpers/helper-misc.php:343
1699
  msgid "Liechtenstein"
1700
  msgstr ""
1701
 
1702
+ #: inc/helpers/helper-misc.php:344
1703
  msgid "Lithuania"
1704
  msgstr ""
1705
 
1706
+ #: inc/helpers/helper-misc.php:345
1707
  msgid "Luxembourg"
1708
  msgstr ""
1709
 
1710
+ #: inc/helpers/helper-misc.php:346
1711
  msgid "Macau"
1712
  msgstr ""
1713
 
1714
+ #: inc/helpers/helper-misc.php:347
1715
  msgid "Macedonia, The Former Yugoslav Republic of"
1716
  msgstr ""
1717
 
1718
+ #: inc/helpers/helper-misc.php:348
1719
  msgid "Madagascar"
1720
  msgstr ""
1721
 
1722
+ #: inc/helpers/helper-misc.php:349
1723
  msgid "Malawi"
1724
  msgstr ""
1725
 
1726
+ #: inc/helpers/helper-misc.php:350
1727
  msgid "Malaysia"
1728
  msgstr ""
1729
 
1730
+ #: inc/helpers/helper-misc.php:351
1731
  msgid "Maldives"
1732
  msgstr ""
1733
 
1734
+ #: inc/helpers/helper-misc.php:352
1735
  msgid "Mali"
1736
  msgstr ""
1737
 
1738
+ #: inc/helpers/helper-misc.php:353
1739
  msgid "Malta"
1740
  msgstr ""
1741
 
1742
+ #: inc/helpers/helper-misc.php:354
1743
  msgid "Marshall Islands"
1744
  msgstr ""
1745
 
1746
+ #: inc/helpers/helper-misc.php:355
1747
  msgid "Martinique"
1748
  msgstr ""
1749
 
1750
+ #: inc/helpers/helper-misc.php:356
1751
  msgid "Mauritania"
1752
  msgstr ""
1753
 
1754
+ #: inc/helpers/helper-misc.php:357
1755
  msgid "Mauritius"
1756
  msgstr ""
1757
 
1758
+ #: inc/helpers/helper-misc.php:358
1759
  msgid "Mayotte"
1760
  msgstr ""
1761
 
1762
+ #: inc/helpers/helper-misc.php:359
1763
  msgid "Mexico"
1764
  msgstr ""
1765
 
1766
+ #: inc/helpers/helper-misc.php:360
1767
  msgid "Micronesia, Federated States of"
1768
  msgstr ""
1769
 
1770
+ #: inc/helpers/helper-misc.php:361
1771
  msgid "Moldova, Republic of"
1772
  msgstr ""
1773
 
1774
+ #: inc/helpers/helper-misc.php:362
1775
  msgid "Monaco"
1776
  msgstr ""
1777
 
1778
+ #: inc/helpers/helper-misc.php:363
1779
  msgid "Mongolia"
1780
  msgstr ""
1781
 
1782
+ #: inc/helpers/helper-misc.php:364
1783
  msgid "Montserrat"
1784
  msgstr ""
1785
 
1786
+ #: inc/helpers/helper-misc.php:365
1787
  msgid "Morocco"
1788
  msgstr ""
1789
 
1790
+ #: inc/helpers/helper-misc.php:366
1791
  msgid "Mozambique"
1792
  msgstr ""
1793
 
1794
+ #: inc/helpers/helper-misc.php:367
1795
  msgid "Myanmar"
1796
  msgstr ""
1797
 
1798
+ #: inc/helpers/helper-misc.php:368
1799
  msgid "Namibia"
1800
  msgstr ""
1801
 
1802
+ #: inc/helpers/helper-misc.php:369
1803
  msgid "Nauru"
1804
  msgstr ""
1805
 
1806
+ #: inc/helpers/helper-misc.php:370
1807
  msgid "Nepal"
1808
  msgstr ""
1809
 
1810
+ #: inc/helpers/helper-misc.php:371
1811
  msgid "Netherlands"
1812
  msgstr ""
1813
 
1814
+ #: inc/helpers/helper-misc.php:372
1815
  msgid "Netherlands Antilles"
1816
  msgstr ""
1817
 
1818
+ #: inc/helpers/helper-misc.php:373
1819
  msgid "New Caledonia"
1820
  msgstr ""
1821
 
1822
+ #: inc/helpers/helper-misc.php:374
1823
  msgid "New Zealand"
1824
  msgstr ""
1825
 
1826
+ #: inc/helpers/helper-misc.php:375
1827
  msgid "Nicaragua"
1828
  msgstr ""
1829
 
1830
+ #: inc/helpers/helper-misc.php:376
1831
  msgid "Niger"
1832
  msgstr ""
1833
 
1834
+ #: inc/helpers/helper-misc.php:377
1835
  msgid "Nigeria"
1836
  msgstr ""
1837
 
1838
+ #: inc/helpers/helper-misc.php:378
1839
  msgid "Niue"
1840
  msgstr ""
1841
 
1842
+ #: inc/helpers/helper-misc.php:379
1843
  msgid "Norfolk Island"
1844
  msgstr ""
1845
 
1846
+ #: inc/helpers/helper-misc.php:380
1847
  msgid "Northern Mariana Islands"
1848
  msgstr ""
1849
 
1850
+ #: inc/helpers/helper-misc.php:381
1851
  msgid "Norway"
1852
  msgstr ""
1853
 
1854
+ #: inc/helpers/helper-misc.php:382
1855
  msgid "Oman"
1856
  msgstr ""
1857
 
1858
+ #: inc/helpers/helper-misc.php:383
1859
  msgid "Pakistan"
1860
  msgstr ""
1861
 
1862
+ #: inc/helpers/helper-misc.php:384
1863
  msgid "Palau"
1864
  msgstr ""
1865
 
1866
+ #: inc/helpers/helper-misc.php:385
1867
  msgid "Panama"
1868
  msgstr ""
1869
 
1870
+ #: inc/helpers/helper-misc.php:386
1871
  msgid "Papua New Guinea"
1872
  msgstr ""
1873
 
1874
+ #: inc/helpers/helper-misc.php:387
1875
  msgid "Paraguay"
1876
  msgstr ""
1877
 
1878
+ #: inc/helpers/helper-misc.php:388
1879
  msgid "Peru"
1880
  msgstr ""
1881
 
1882
+ #: inc/helpers/helper-misc.php:389
1883
  msgid "Philippines"
1884
  msgstr ""
1885
 
1886
+ #: inc/helpers/helper-misc.php:390
1887
  msgid "Pitcairn"
1888
  msgstr ""
1889
 
1890
+ #: inc/helpers/helper-misc.php:391
1891
  msgid "Poland"
1892
  msgstr ""
1893
 
1894
+ #: inc/helpers/helper-misc.php:392
1895
  msgid "Portugal"
1896
  msgstr ""
1897
 
1898
+ #: inc/helpers/helper-misc.php:393
1899
  msgid "Puerto Rico"
1900
  msgstr ""
1901
 
1902
+ #: inc/helpers/helper-misc.php:394
1903
  msgid "Qatar"
1904
  msgstr ""
1905
 
1906
+ #: inc/helpers/helper-misc.php:395
1907
  msgid "Reunion"
1908
  msgstr ""
1909
 
1910
+ #: inc/helpers/helper-misc.php:396
1911
  msgid "Romania"
1912
  msgstr ""
1913
 
1914
+ #: inc/helpers/helper-misc.php:397
1915
  msgid "Russian Federation"
1916
  msgstr ""
1917
 
1918
+ #: inc/helpers/helper-misc.php:398
1919
  msgid "Rwanda"
1920
  msgstr ""
1921
 
1922
+ #: inc/helpers/helper-misc.php:399
1923
  msgid "Saint Kitts and Nevis"
1924
  msgstr ""
1925
 
1926
+ #: inc/helpers/helper-misc.php:400
1927
  msgid "Saint Lucia"
1928
  msgstr ""
1929
 
1930
+ #: inc/helpers/helper-misc.php:401
1931
  msgid "Saint Vincent and the Grenadines"
1932
  msgstr ""
1933
 
1934
+ #: inc/helpers/helper-misc.php:402
1935
  msgid "Samoa"
1936
  msgstr ""
1937
 
1938
+ #: inc/helpers/helper-misc.php:403
1939
  msgid "San Marino"
1940
  msgstr ""
1941
 
1942
+ #: inc/helpers/helper-misc.php:404
1943
  msgid "Sao Tome and Principe"
1944
  msgstr ""
1945
 
1946
+ #: inc/helpers/helper-misc.php:405
1947
  msgid "Saudi Arabia"
1948
  msgstr ""
1949
 
1950
+ #: inc/helpers/helper-misc.php:406
1951
  msgid "Senegal"
1952
  msgstr ""
1953
 
1954
+ #: inc/helpers/helper-misc.php:407
1955
  msgid "Seychelles"
1956
  msgstr ""
1957
 
1958
+ #: inc/helpers/helper-misc.php:408
1959
  msgid "Sierra Leone"
1960
  msgstr ""
1961
 
1962
+ #: inc/helpers/helper-misc.php:409
1963
  msgid "Singapore"
1964
  msgstr ""
1965
 
1966
+ #: inc/helpers/helper-misc.php:410
1967
  msgid "Slovakia (Slovak Republic)"
1968
  msgstr ""
1969
 
1970
+ #: inc/helpers/helper-misc.php:411
1971
  msgid "Slovenia"
1972
  msgstr ""
1973
 
1974
+ #: inc/helpers/helper-misc.php:412
1975
  msgid "Solomon Islands"
1976
  msgstr ""
1977
 
1978
+ #: inc/helpers/helper-misc.php:413
1979
  msgid "Somalia"
1980
  msgstr ""
1981
 
1982
+ #: inc/helpers/helper-misc.php:414
1983
  msgid "South Africa"
1984
  msgstr ""
1985
 
1986
+ #: inc/helpers/helper-misc.php:415
1987
  msgid "South Georgia and the South Sandwich Islands"
1988
  msgstr ""
1989
 
1990
+ #: inc/helpers/helper-misc.php:416
1991
  msgid "Spain"
1992
  msgstr ""
1993
 
1994
+ #: inc/helpers/helper-misc.php:417
1995
  msgid "Sri Lanka"
1996
  msgstr ""
1997
 
1998
+ #: inc/helpers/helper-misc.php:418
1999
  msgid "St. Helena"
2000
  msgstr ""
2001
 
2002
+ #: inc/helpers/helper-misc.php:419
2003
  msgid "St. Pierre and Miquelon"
2004
  msgstr ""
2005
 
2006
+ #: inc/helpers/helper-misc.php:420
2007
  msgid "Sudan"
2008
  msgstr ""
2009
 
2010
+ #: inc/helpers/helper-misc.php:421
2011
  msgid "Suriname"
2012
  msgstr ""
2013
 
2014
+ #: inc/helpers/helper-misc.php:422
2015
  msgid "Svalbard and Jan Mayen Islands"
2016
  msgstr ""
2017
 
2018
+ #: inc/helpers/helper-misc.php:423
2019
  msgid "Swaziland"
2020
  msgstr ""
2021
 
2022
+ #: inc/helpers/helper-misc.php:424
2023
  msgid "Sweden"
2024
  msgstr ""
2025
 
2026
+ #: inc/helpers/helper-misc.php:425
2027
  msgid "Switzerland"
2028
  msgstr ""
2029
 
2030
+ #: inc/helpers/helper-misc.php:426
2031
  msgid "Syrian Arab Republic"
2032
  msgstr ""
2033
 
2034
+ #: inc/helpers/helper-misc.php:427
2035
  msgid "Taiwan, Province of China"
2036
  msgstr ""
2037
 
2038
+ #: inc/helpers/helper-misc.php:428
2039
  msgid "Tajikistan"
2040
  msgstr ""
2041
 
2042
+ #: inc/helpers/helper-misc.php:429
2043
  msgid "Tanzania, United Republic of"
2044
  msgstr ""
2045
 
2046
+ #: inc/helpers/helper-misc.php:430
2047
  msgid "Thailand"
2048
  msgstr ""
2049
 
2050
+ #: inc/helpers/helper-misc.php:431
2051
  msgid "Togo"
2052
  msgstr ""
2053
 
2054
+ #: inc/helpers/helper-misc.php:432
2055
  msgid "Tokelau"
2056
  msgstr ""
2057
 
2058
+ #: inc/helpers/helper-misc.php:433
2059
  msgid "Tonga"
2060
  msgstr ""
2061
 
2062
+ #: inc/helpers/helper-misc.php:434
2063
  msgid "Trinidad and Tobago"
2064
  msgstr ""
2065
 
2066
+ #: inc/helpers/helper-misc.php:435
2067
  msgid "Tunisia"
2068
  msgstr ""
2069
 
2070
+ #: inc/helpers/helper-misc.php:436
2071
  msgid "Turkey"
2072
  msgstr ""
2073
 
2074
+ #: inc/helpers/helper-misc.php:437
2075
  msgid "Turkmenistan"
2076
  msgstr ""
2077
 
2078
+ #: inc/helpers/helper-misc.php:438
2079
  msgid "Turks and Caicos Islands"
2080
  msgstr ""
2081
 
2082
+ #: inc/helpers/helper-misc.php:439
2083
  msgid "Tuvalu"
2084
  msgstr ""
2085
 
2086
+ #: inc/helpers/helper-misc.php:440
2087
  msgid "Uganda"
2088
  msgstr ""
2089
 
2090
+ #: inc/helpers/helper-misc.php:441
2091
  msgid "Ukraine"
2092
  msgstr ""
2093
 
2094
+ #: inc/helpers/helper-misc.php:442
2095
  msgid "United Arab Emirates"
2096
  msgstr ""
2097
 
2098
+ #: inc/helpers/helper-misc.php:443
2099
  msgid "United Kingdom"
2100
  msgstr ""
2101
 
2102
+ #: inc/helpers/helper-misc.php:444
2103
  msgid "United States"
2104
  msgstr ""
2105
 
2106
+ #: inc/helpers/helper-misc.php:445
2107
  msgid "United States Minor Outlying Islands"
2108
  msgstr ""
2109
 
2110
+ #: inc/helpers/helper-misc.php:446
2111
  msgid "Uruguay"
2112
  msgstr ""
2113
 
2114
+ #: inc/helpers/helper-misc.php:447
2115
  msgid "Uzbekistan"
2116
  msgstr ""
2117
 
2118
+ #: inc/helpers/helper-misc.php:448
2119
  msgid "Vanuatu"
2120
  msgstr ""
2121
 
2122
+ #: inc/helpers/helper-misc.php:449
2123
  msgid "Venezuela"
2124
  msgstr ""
2125
 
2126
+ #: inc/helpers/helper-misc.php:450
2127
  msgid "Vietnam"
2128
  msgstr ""
2129
 
2130
+ #: inc/helpers/helper-misc.php:451
2131
  msgid "Virgin Islands (British)"
2132
  msgstr ""
2133
 
2134
+ #: inc/helpers/helper-misc.php:452
2135
  msgid "Virgin Islands (U.S.)"
2136
  msgstr ""
2137
 
2138
+ #: inc/helpers/helper-misc.php:453
2139
  msgid "Wallis and Futuna Islands"
2140
  msgstr ""
2141
 
2142
+ #: inc/helpers/helper-misc.php:454
2143
  msgid "Western Sahara"
2144
  msgstr ""
2145
 
2146
+ #: inc/helpers/helper-misc.php:455
2147
  msgid "Yemen"
2148
  msgstr ""
2149
 
2150
+ #: inc/helpers/helper-misc.php:456
2151
  msgid "Yugoslavia"
2152
  msgstr ""
2153
 
2154
+ #: inc/helpers/helper-misc.php:457
2155
  msgid "Zambia"
2156
  msgstr ""
2157
 
2158
+ #: inc/helpers/helper-misc.php:458
2159
  msgid "Zimbabwe"
2160
  msgstr ""
2161
 
2171
  msgid "Insert HappyForm"
2172
  msgstr ""
2173
 
2174
+ #: inc/templates/admin-message-edit.php:25
2175
  msgid "Previous response"
2176
  msgstr ""
2177
 
2178
+ #: inc/templates/admin-message-edit.php:27
2179
  msgid "Next response"
2180
  msgstr ""
2181
 
2389
  msgstr ""
2390
 
2391
  #: inc/templates/customize-form-steps.php:9
2392
+ #: inc/templates/parts/customize-scale.php:75
2393
  msgid "Step"
2394
  msgstr ""
2395
 
2491
  #: inc/templates/parts/customize-checkbox.php:17
2492
  #: inc/templates/parts/customize-checkbox.php:60
2493
  #: inc/templates/parts/customize-date.php:17
2494
+ #: inc/templates/parts/customize-date.php:106
2495
  #: inc/templates/parts/customize-email.php:19
2496
  #: inc/templates/parts/customize-email.php:51
2497
  #: inc/templates/parts/customize-multi-line-text.php:19
2499
  #: inc/templates/parts/customize-number.php:19
2500
  #: inc/templates/parts/customize-number.php:80
2501
  #: inc/templates/parts/customize-phone.php:19
2502
+ #: inc/templates/parts/customize-phone.php:69
2503
  #: inc/templates/parts/customize-placeholder.php:17
2504
  #: inc/templates/parts/customize-placeholder.php:35
2505
  #: inc/templates/parts/customize-radio.php:17
2507
  #: inc/templates/parts/customize-rating.php:17
2508
  #: inc/templates/parts/customize-rating.php:45
2509
  #: inc/templates/parts/customize-scale.php:17
2510
+ #: inc/templates/parts/customize-scale.php:92
2511
  #: inc/templates/parts/customize-select.php:17
2512
  #: inc/templates/parts/customize-select.php:54
2513
  #: inc/templates/parts/customize-single-line-text.php:19
2561
  #: inc/templates/parts/customize-address.php:38
2562
  #: inc/templates/parts/customize-address.php:76
2563
  #: inc/templates/parts/customize-checkbox.php:53
2564
+ #: inc/templates/parts/customize-date.php:99
2565
  #: inc/templates/parts/customize-email.php:44
2566
  #: inc/templates/parts/customize-legal.php:6
2567
  #: inc/templates/parts/customize-multi-line-text.php:44
2568
  #: inc/templates/parts/customize-number.php:73
2569
+ #: inc/templates/parts/customize-phone.php:62
2570
  #: inc/templates/parts/customize-placeholder.php:28
2571
  #: inc/templates/parts/customize-radio.php:53
2572
  #: inc/templates/parts/customize-rating.php:38
2573
+ #: inc/templates/parts/customize-scale.php:85
2574
  #: inc/templates/parts/customize-select.php:47
2575
  #: inc/templates/parts/customize-single-line-text.php:44
2576
  #: inc/templates/parts/customize-title.php:38
2623
  #: inc/templates/parts/customize-phone.php:37
2624
  #: inc/templates/parts/customize-radio.php:31
2625
  #: inc/templates/parts/customize-rating.php:31
2626
+ #: inc/templates/parts/customize-scale.php:41
2627
  #: inc/templates/parts/customize-select.php:31
2628
  #: inc/templates/parts/customize-single-line-text.php:37
2629
  #: inc/templates/parts/customize-title.php:31
2633
 
2634
  #: inc/templates/parts/customize-address.php:77
2635
  #: inc/templates/parts/customize-checkbox.php:54
2636
+ #: inc/templates/parts/customize-date.php:100
2637
  #: inc/templates/parts/customize-email.php:45
2638
  #: inc/templates/parts/customize-legal.php:7
2639
  #: inc/templates/parts/customize-multi-line-text.php:45
2640
  #: inc/templates/parts/customize-number.php:74
2641
+ #: inc/templates/parts/customize-phone.php:63
2642
  #: inc/templates/parts/customize-placeholder.php:29
2643
  #: inc/templates/parts/customize-radio.php:54
2644
  #: inc/templates/parts/customize-rating.php:39
2645
+ #: inc/templates/parts/customize-scale.php:86
2646
  #: inc/templates/parts/customize-select.php:48
2647
  #: inc/templates/parts/customize-single-line-text.php:45
2648
  #: inc/templates/parts/customize-title.php:39
2652
 
2653
  #: inc/templates/parts/customize-address.php:78
2654
  #: inc/templates/parts/customize-checkbox.php:55
2655
+ #: inc/templates/parts/customize-date.php:101
2656
  #: inc/templates/parts/customize-email.php:46
2657
  #: inc/templates/parts/customize-legal.php:8
2658
  #: inc/templates/parts/customize-multi-line-text.php:46
2659
  #: inc/templates/parts/customize-number.php:75
2660
+ #: inc/templates/parts/customize-phone.php:64
2661
  #: inc/templates/parts/customize-placeholder.php:30
2662
  #: inc/templates/parts/customize-radio.php:55
2663
  #: inc/templates/parts/customize-rating.php:40
2664
+ #: inc/templates/parts/customize-scale.php:87
2665
  #: inc/templates/parts/customize-select.php:49
2666
  #: inc/templates/parts/customize-single-line-text.php:46
2667
  #: inc/templates/parts/customize-title.php:40
2671
 
2672
  #: inc/templates/parts/customize-address.php:82
2673
  #: inc/templates/parts/customize-checkbox.php:64
2674
+ #: inc/templates/parts/customize-date.php:110
2675
  #: inc/templates/parts/customize-email.php:55
2676
  #: inc/templates/parts/customize-legal.php:17
2677
  #: inc/templates/parts/customize-multi-line-text.php:55
2678
  #: inc/templates/parts/customize-number.php:84
2679
+ #: inc/templates/parts/customize-phone.php:73
2680
  #: inc/templates/parts/customize-placeholder.php:39
2681
  #: inc/templates/parts/customize-radio.php:64
2682
  #: inc/templates/parts/customize-rating.php:49
2683
+ #: inc/templates/parts/customize-scale.php:96
2684
  #: inc/templates/parts/customize-select.php:58
2685
  #: inc/templates/parts/customize-single-line-text.php:55
2686
  #: inc/templates/parts/customize-title.php:49
2734
  msgstr ""
2735
 
2736
  #: inc/templates/parts/customize-date.php:38
2737
+ #: inc/templates/parts/customize-scale.php:61
2738
  msgid "Default value"
2739
  msgstr ""
2740
 
2746
  msgid "Current date and time"
2747
  msgstr ""
2748
 
2749
+ #: inc/templates/parts/customize-date.php:53
2750
+ msgid "All years"
2751
+ msgstr ""
2752
+
2753
+ #: inc/templates/parts/customize-date.php:54
2754
+ msgid "Past years only"
2755
+ msgstr ""
2756
+
2757
+ #: inc/templates/parts/customize-date.php:55
2758
+ msgid "Future years only"
2759
+ msgstr ""
2760
+
2761
+ #: inc/templates/parts/customize-date.php:60
2762
+ msgid "Start from"
2763
  msgstr ""
2764
 
2765
+ #: inc/templates/parts/customize-date.php:64
2766
+ msgid "End at"
2767
  msgstr ""
2768
 
2769
+ #: inc/templates/parts/customize-date.php:69
2770
+ msgid "Years order"
2771
+ msgstr ""
2772
+
2773
+ #: inc/templates/parts/customize-date.php:77
2774
  msgid "Min hour"
2775
  msgstr ""
2776
 
2777
+ #: inc/templates/parts/customize-date.php:81
2778
  msgid "Max hour"
2779
  msgstr ""
2780
 
2781
+ #: inc/templates/parts/customize-date.php:86
2782
  msgid "Minute step"
2783
  msgstr ""
2784
 
2785
+ #: inc/templates/parts/customize-date.php:90
2786
  msgid "Time format"
2787
  msgstr ""
2788
 
2789
+ #: inc/templates/parts/customize-date.php:92
2790
  msgid "12h"
2791
  msgstr ""
2792
 
2793
+ #: inc/templates/parts/customize-date.php:93
2794
  msgid "24h"
2795
  msgstr ""
2796
 
2803
 
2804
  #: inc/templates/parts/customize-email.php:60
2805
  #: inc/templates/parts/customize-number.php:89
2806
+ #: inc/templates/parts/customize-phone.php:78
2807
  msgid "Require confirmation of the value"
2808
  msgstr ""
2809
 
2810
  #: inc/templates/parts/customize-email.php:64
2811
  #: inc/templates/parts/customize-number.php:93
2812
+ #: inc/templates/parts/customize-phone.php:82
2813
  msgid "Confirmation field title"
2814
  msgstr ""
2815
 
2818
  msgstr ""
2819
 
2820
  #: inc/templates/parts/customize-number.php:37
 
2821
  msgid "Minimum accepted value"
2822
  msgstr ""
2823
 
2824
  #: inc/templates/parts/customize-number.php:41
 
2825
  msgid "Maximum accepted value"
2826
  msgstr ""
2827
 
2846
  msgid "Pre-format phone number region"
2847
  msgstr ""
2848
 
 
 
 
 
 
2849
  #: inc/templates/parts/customize-radio.php:81
2850
  #: inc/templates/parts/customize-select.php:71
2851
  msgid "Make this option default"
2852
  msgstr ""
2853
 
2854
+ #: inc/templates/parts/customize-scale.php:31
2855
+ msgid "Minimum value"
2856
+ msgstr ""
2857
+
2858
+ #: inc/templates/parts/customize-scale.php:35
2859
+ msgid "Maximum value"
2860
+ msgstr ""
2861
+
2862
+ #: inc/templates/parts/customize-scale.php:47
2863
+ msgid "Allow range select"
2864
+ msgstr ""
2865
+
2866
+ #: inc/templates/parts/customize-scale.php:52
2867
+ msgid "Default range from"
2868
+ msgstr ""
2869
+
2870
+ #: inc/templates/parts/customize-scale.php:56
2871
+ msgid "Default range to"
2872
+ msgstr ""
2873
+
2874
+ #: inc/templates/parts/customize-scale.php:66
2875
  msgid "Minimum value label"
2876
  msgstr ""
2877
 
2878
+ #: inc/templates/parts/customize-scale.php:70
2879
  msgid "Maximum value label"
2880
  msgstr ""
2881
 
2896
  msgid "City"
2897
  msgstr ""
2898
 
2899
+ #: inc/templates/parts/frontend-date-day.php:5
2900
+ msgid "Day"
2901
  msgstr ""
2902
 
2903
+ #: inc/templates/parts/frontend-date-month.php:5
2904
+ msgid "Month"
2905
  msgstr ""
2906
 
2907
+ #: inc/templates/parts/frontend-date.php:25
2908
  msgid "Year"
2909
  msgstr ""
2910
 
2911
+ #: inc/templates/parts/frontend-date.php:86
2912
+ msgid "Period"
2913
  msgstr ""
2914
 
2915
+ #: inc/templates/parts/frontend-date.php:87
2916
+ msgid "AM"
2917
  msgstr ""
2918
 
2919
+ #: inc/templates/parts/frontend-date.php:88
2920
+ msgid "PM"
 
 
2921
  msgstr ""
2922
 
2923
  #: inc/templates/parts/frontend-rating.php:10
2924
  msgid "Stars"
2925
  msgstr ""
2926
 
2927
+ #: inc/templates/parts/frontend-select.php:10
2928
+ #: inc/templates/parts/frontend-title.php:7
2929
+ msgid "Select"
2930
+ msgstr ""
2931
+
2932
+ #: inc/templates/preview-form-edit.php:10
2933
  msgid ""
2934
  "This is a preview of your new HappyForm. Once you’ve finished building, you "
2935
  "can add this form to any Page, Post and Widget area. Have questions? <a "
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: contact, contact form, email, feedback form, form, form builder, custom fo
5
  Requires at least: 4.8
6
  Tested up to: 4.9.6
7
  Requires PHP: 5.2.4
8
- Stable tag: 1.4.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -53,7 +53,7 @@ HappyForms is the simplest way for you to manage and respond to conversations wi
53
  * Dropdown — For long lists and single selection.
54
  * Number — For formatted numeric fields, like phone and price.
55
  * Phone - For formatted contact details.
56
- * Date — Includes day and year picker for easy use.
57
  * Address — A dropdown listing all available countries.
58
  * Scale — Collect opinions using a numeric slider.
59
  * Title — Include personal honorific list.
@@ -74,6 +74,18 @@ Absolutely! HappyForms gets out of the way and is designed to work with any them
74
 
75
  == Changelog ==
76
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  = 1.4.6 =
78
  * Improvement: scripts and styles are now versioned to avoid cache problems after an update.
79
  * Bug fix: Permalinks are now flushed upon activation to avoid 404 errors.
@@ -154,6 +166,9 @@ Absolutely! HappyForms gets out of the way and is designed to work with any them
154
 
155
  == Upgrade Notice ==
156
 
 
 
 
157
  = 1.4.6 =
158
  * Improvements and bug fixes.
159
 
5
  Requires at least: 4.8
6
  Tested up to: 4.9.6
7
  Requires PHP: 5.2.4
8
+ Stable tag: 1.5.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
53
  * Dropdown — For long lists and single selection.
54
  * Number — For formatted numeric fields, like phone and price.
55
  * Phone - For formatted contact details.
56
+ * Date & Time — Includes date dropdowns and time input spinners.
57
  * Address — A dropdown listing all available countries.
58
  * Scale — Collect opinions using a numeric slider.
59
  * Title — Include personal honorific list.
74
 
75
  == Changelog ==
76
 
77
+ = 1.5.0 =
78
+ * Improvement: Forms are now submitted without page refresh.
79
+ * Improvement: Submitted values are preserved after an unsuccessful submission.
80
+ * Improvement: Added new filters for greater part rendering customization.
81
+ * Improvement: Added new actions for integration with third party plugins and tools.
82
+ * Improvement: Scale part now support range selection.
83
+ * Improvement: Better management of years displayed in Date & Time part.
84
+ * Improvement: Order of month and day fields in Date & Time part now defaults to a date format setting in WordPress.
85
+ * Improvement: Month names in Date & Time part have been moved to an array and are now easy to translate.
86
+ * Bug fix: Various UI glitches affected form previews in Customize screen.
87
+ * Bug fix: Various UI glitches affected part rendering of labels and preset values.
88
+
89
  = 1.4.6 =
90
  * Improvement: scripts and styles are now versioned to avoid cache problems after an update.
91
  * Bug fix: Permalinks are now flushed upon activation to avoid 404 errors.
166
 
167
  == Upgrade Notice ==
168
 
169
+ = 1.5.0 =
170
+ * Refresh-free forms, tons of new actions, filters and bugfixes.
171
+
172
  = 1.4.6 =
173
  * Improvements and bug fixes.
174