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

Version Description

  • New feature: "Hint" control for adding descriptive text to Radio and Checkbox field choices.
  • Improvement: Nicer vertical alignment of choices spanning multiple lines in Radio and Checkbox fields.
  • Improvement: "Align choices" control is now a button group for better usability.
  • Improvement: Exhausted choices are now always tagged with "(0 remaining)" to avoid confusion.
  • Improvement: All instances of "submit" type inputs have been replaced with buttons for easier styling.
  • Improvement: All custom form dropdowns have been replaced with their native counterparts for better performance and accessibility.
Download this release

Release Info

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

Code changes from version 1.14.0 to 1.14.1

core/assets/css/color.css CHANGED
@@ -95,7 +95,8 @@
95
  .happyforms-styles .happyforms-part input[type=tel],
96
  .happyforms-styles .happyforms-part input[type=number],
97
  .happyforms-styles .happyforms-part input[type=range],
98
- .happyforms-styles .happyforms-part textarea {
 
99
  margin: 0;
100
  padding: 10px;
101
  border-width: 1px;
@@ -143,7 +144,8 @@
143
  .happyforms-styles .happyforms-part input[type=email]:focus,
144
  .happyforms-styles .happyforms-part input[type=tel]:focus,
145
  .happyforms-styles .happyforms-part input[type=number]:focus,
146
- .happyforms-styles .happyforms-part textarea:focus {
 
147
  outline: 0;
148
  border-color: #7aa4ff !important;
149
  border-color: var(--happyforms-color-part-border-focus) !important;
@@ -225,7 +227,8 @@
225
 
226
  .happyforms-styles .happyforms-part .option-label {
227
  border-radius: 6px;
228
- line-height: 1;
 
229
  font-size: 16px;
230
  font-size: var(--happyforms-part-value-font-size);
231
  overflow-wrap: anywhere;
@@ -255,10 +258,16 @@
255
  top: 3px;
256
  }
257
 
258
- .happyforms-styles .happyforms-part .option-label {
 
259
  margin-bottom: 10px;
260
  }
261
 
 
 
 
 
 
262
  .happyforms-styles .happyforms-part .option-label .label,
263
  .happyforms-part .option-label .happyforms-remaining-choice {
264
  font-weight: normal;
@@ -274,9 +283,9 @@
274
  }
275
 
276
  .happyforms-styles .happyforms-part-option__description {
277
- font-size: 12px;
278
  color: #000;
279
- color: var(--happyforms-color-primary);
280
  }
281
 
282
  /* parts - radio, checkbox */
@@ -289,6 +298,7 @@
289
  width: 21px;
290
  min-width: 21px;
291
  height: 21px;
 
292
  border-radius: 50%;
293
  border: 1px solid;
294
  border-color: #dbdbdb;
@@ -375,8 +385,11 @@
375
  border-top-color: var(--happyforms-color-dropdown-item-text);
376
  }
377
 
378
- .happyforms-styles .happyforms-part--select select:focus,
379
- .happyforms-styles .happyforms-part--date select:focus {
 
 
 
380
  outline-width: 1px;
381
  outline-color: #000000;
382
  outline-color: var(--happyforms-color-part-value);
@@ -391,8 +404,8 @@
391
 
392
  /* submit button */
393
 
394
- .happyforms-styles input[type=submit].happyforms-button--submit,
395
- .happyforms-styles input[type=submit][disabled].happyforms-button--submit {
396
  -webkit-appearance: none;
397
  height: auto;
398
  padding: 15px 30px;
@@ -418,7 +431,7 @@
418
  overflow-wrap: anywhere;
419
  }
420
 
421
- .happyforms-styles input[type=submit]:not(:hover):not(:active):not(.has-background) {
422
  background-color: #000;
423
  background-color: var(--happyforms-color-submit-background);
424
  background: #000;
@@ -427,8 +440,8 @@
427
  color: var(--happyforms-color-submit-text);
428
  }
429
 
430
- .happyforms-styles input[type=submit].happyforms-button--submit:hover,
431
- .happyforms-styles input[type=submit].happyforms-button--submit:focus {
432
  cursor: pointer;
433
  border-radius: 4px;
434
  border-color: transparent !important;
@@ -443,8 +456,8 @@
443
  color: var(--happyforms-color-submit-text-hover);
444
  }
445
 
446
- .happyforms-styles input[type=submit][disabled].happyforms-button--submit:hover,
447
- .happyforms-styles input[type=submit][disabled].happyforms-button--submit:focus {
448
  cursor: default;
449
  background-color: #407fff;
450
  background-color: var(--happyforms-color-submit-background);
@@ -678,37 +691,37 @@
678
 
679
  /* submit button */
680
 
681
- .happyforms-styles.happyforms-form--submit-button-border-hide input[type=submit].happyforms-button--submit {
682
  border-width: 0 !important;
683
  }
684
 
685
- .happyforms-styles.happyforms-form--submit-button-border-radius-square input[type=submit].happyforms-button--submit,
686
- .happyforms-styles.happyforms-form--submit-button-border-radius-square input[type=submit].happyforms-button--submit:hover {
687
  border-radius: 0 !important;
688
  }
689
 
690
- .happyforms-styles.happyforms-form--submit-button-border-radius-pill input[type=submit].happyforms-button--submit,
691
- .happyforms-styles.happyforms-form--submit-button-border-radius-pill input[type=submit].happyforms-button--submit:hover {
692
  border-radius: 60px !important;
693
  }
694
 
695
- .happyforms-styles.happyforms-form--submit-button-bold .happyforms-part--submit input[type=submit] {
696
  font-weight: bold;
697
  }
698
 
699
- .happyforms-styles.happyforms-form--submit-button-disable-transitions input[type=submit] {
700
  transition-duration: 0s !important;
701
  }
702
 
703
- .happyforms-styles.happyforms-form--submit-button-padding-narrow input[type=submit].happyforms-button--submit {
704
  padding: 10px 20px;
705
  }
706
 
707
- .happyforms-styles.happyforms-form--submit-button-padding-wide input[type=submit].happyforms-button--submit {
708
  padding: 20px 50px;
709
  }
710
 
711
- .happyforms-styles.happyforms-form--submit-button-fullwidth input[type=submit].happyforms-button--submit {
712
  padding-left: 0;
713
  padding-right: 0;
714
  margin-right: 0;
@@ -718,10 +731,6 @@
718
  font-weight: bold;
719
  }
720
 
721
- /* new dropdowns */
722
- .happyforms-styles .happyforms-part select {
723
- display: none;
724
- }
725
  .happyforms-styles .happyforms-custom-select input[readonly="readonly"] {
726
  cursor: pointer;
727
  }
95
  .happyforms-styles .happyforms-part input[type=tel],
96
  .happyforms-styles .happyforms-part input[type=number],
97
  .happyforms-styles .happyforms-part input[type=range],
98
+ .happyforms-styles .happyforms-part textarea,
99
+ .happyforms-styles .happyforms-part select.happyforms-select {
100
  margin: 0;
101
  padding: 10px;
102
  border-width: 1px;
144
  .happyforms-styles .happyforms-part input[type=email]:focus,
145
  .happyforms-styles .happyforms-part input[type=tel]:focus,
146
  .happyforms-styles .happyforms-part input[type=number]:focus,
147
+ .happyforms-styles .happyforms-part textarea:focus,
148
+ .happyforms-styles .happyforms-part select.happyforms-select:focus {
149
  outline: 0;
150
  border-color: #7aa4ff !important;
151
  border-color: var(--happyforms-color-part-border-focus) !important;
227
 
228
  .happyforms-styles .happyforms-part .option-label {
229
  border-radius: 6px;
230
+ line-height: 1.3125;
231
+ line-height: calc(var(--happyforms-part-value-font-size) * 1.3125);
232
  font-size: 16px;
233
  font-size: var(--happyforms-part-value-font-size);
234
  overflow-wrap: anywhere;
258
  top: 3px;
259
  }
260
 
261
+ .happyforms-styles .happyforms-part--radio .happyforms-part-option,
262
+ .happyforms-styles .happyforms-part--checkbox .happyforms-part-option {
263
  margin-bottom: 10px;
264
  }
265
 
266
+ .happyforms-styles .happyforms-part--radio label.option-label,
267
+ .happyforms-styles .happyforms-part--checkbox label.option-label {
268
+ margin-bottom: 0px;
269
+ }
270
+
271
  .happyforms-styles .happyforms-part .option-label .label,
272
  .happyforms-part .option-label .happyforms-remaining-choice {
273
  font-weight: normal;
283
  }
284
 
285
  .happyforms-styles .happyforms-part-option__description {
286
+ font-size: var(--happyforms-part-description-font-size);
287
  color: #000;
288
+ color: var(--happyforms-color-part-description);
289
  }
290
 
291
  /* parts - radio, checkbox */
298
  width: 21px;
299
  min-width: 21px;
300
  height: 21px;
301
+ margin: calc((var(--happyforms-part-value-font-size) * 1.3125 - 21px) / 2) 0;
302
  border-radius: 50%;
303
  border: 1px solid;
304
  border-color: #dbdbdb;
385
  border-top-color: var(--happyforms-color-dropdown-item-text);
386
  }
387
 
388
+ .happyforms-styles .happyforms-part select.happyforms-select:invalid {
389
+ color: var(--happyforms-color-part-placeholder) !important;
390
+ }
391
+
392
+ .happyforms-styles .happyforms-part select.happyforms-select:focus {
393
  outline-width: 1px;
394
  outline-color: #000000;
395
  outline-color: var(--happyforms-color-part-value);
404
 
405
  /* submit button */
406
 
407
+ .happyforms-styles button[type=submit].happyforms-button--submit,
408
+ .happyforms-styles button[type=submit][disabled].happyforms-button--submit {
409
  -webkit-appearance: none;
410
  height: auto;
411
  padding: 15px 30px;
431
  overflow-wrap: anywhere;
432
  }
433
 
434
+ .happyforms-styles button[type=submit]:not(:hover):not(:active):not(.has-background) {
435
  background-color: #000;
436
  background-color: var(--happyforms-color-submit-background);
437
  background: #000;
440
  color: var(--happyforms-color-submit-text);
441
  }
442
 
443
+ .happyforms-styles button[type=submit].happyforms-button--submit:hover,
444
+ .happyforms-styles button[type=submit].happyforms-button--submit:focus {
445
  cursor: pointer;
446
  border-radius: 4px;
447
  border-color: transparent !important;
456
  color: var(--happyforms-color-submit-text-hover);
457
  }
458
 
459
+ .happyforms-styles button[type=submit][disabled].happyforms-button--submit:hover,
460
+ .happyforms-styles button[type=submit][disabled].happyforms-button--submit:focus {
461
  cursor: default;
462
  background-color: #407fff;
463
  background-color: var(--happyforms-color-submit-background);
691
 
692
  /* submit button */
693
 
694
+ .happyforms-styles.happyforms-form--submit-button-border-hide button[type=submit].happyforms-button--submit {
695
  border-width: 0 !important;
696
  }
697
 
698
+ .happyforms-styles.happyforms-form--submit-button-border-radius-square button[type=submit].happyforms-button--submit,
699
+ .happyforms-styles.happyforms-form--submit-button-border-radius-square button[type=submit].happyforms-button--submit:hover {
700
  border-radius: 0 !important;
701
  }
702
 
703
+ .happyforms-styles.happyforms-form--submit-button-border-radius-pill button[type=submit].happyforms-button--submit,
704
+ .happyforms-styles.happyforms-form--submit-button-border-radius-pill button[type=submit].happyforms-button--submit:hover {
705
  border-radius: 60px !important;
706
  }
707
 
708
+ .happyforms-styles.happyforms-form--submit-button-bold .happyforms-part--submit button[type=submit] {
709
  font-weight: bold;
710
  }
711
 
712
+ .happyforms-styles.happyforms-form--submit-button-disable-transitions button[type=submit] {
713
  transition-duration: 0s !important;
714
  }
715
 
716
+ .happyforms-styles.happyforms-form--submit-button-padding-narrow button[type=submit].happyforms-button--submit {
717
  padding: 10px 20px;
718
  }
719
 
720
+ .happyforms-styles.happyforms-form--submit-button-padding-wide button[type=submit].happyforms-button--submit {
721
  padding: 20px 50px;
722
  }
723
 
724
+ .happyforms-styles.happyforms-form--submit-button-fullwidth button[type=submit].happyforms-button--submit {
725
  padding-left: 0;
726
  padding-right: 0;
727
  margin-right: 0;
731
  font-weight: bold;
732
  }
733
 
 
 
 
 
734
  .happyforms-styles .happyforms-custom-select input[readonly="readonly"] {
735
  cursor: pointer;
736
  }
core/assets/css/customize.css CHANGED
@@ -865,6 +865,7 @@ body.adding-happyforms-parts #customize-preview iframe {
865
  }
866
 
867
  .customize-control .option-list li input,
 
868
  .customize-control .column-list li input,
869
  .customize-control .row-list li input {
870
  margin: 2px 0 5px;
@@ -1449,7 +1450,8 @@ li.customize-control.happyforms-range-control select.happyforms-unit-switch {
1449
  unicode-bidi: embed;
1450
  }
1451
 
1452
- .happyforms-widget-content textarea[data-bind=description] {
 
1453
  height: 90px;
1454
  }
1455
 
@@ -1706,6 +1708,15 @@ ul.happyforms-parts-list li[data-part-type="rich_text"] {
1706
  display: none;
1707
  }
1708
 
 
 
 
 
 
 
 
 
 
1709
  .happyforms-buttongroup-wrapper {
1710
  line-height: 1.5;
1711
  }
@@ -1782,4 +1793,8 @@ ul.happyforms-parts-list li[data-part-type="rich_text"] {
1782
 
1783
  .happyforms-buttongroup.happyforms-buttongroup-field_width {
1784
  margin-top: -1px;
1785
- }
 
 
 
 
865
  }
866
 
867
  .customize-control .option-list li input,
868
+ .customize-control .option-list li textarea,
869
  .customize-control .column-list li input,
870
  .customize-control .row-list li input {
871
  margin: 2px 0 5px;
1450
  unicode-bidi: embed;
1451
  }
1452
 
1453
+ .happyforms-widget-content textarea[data-bind=description],
1454
+ .happyforms-widget-content textarea[data-option-attribute=description] {
1455
  height: 90px;
1456
  }
1457
 
1708
  display: none;
1709
  }
1710
 
1711
+ /**
1712
+ *
1713
+ * Rank field part
1714
+ *
1715
+ */
1716
+ ul.happyforms-parts-list li[data-part-type="rank_order"] {
1717
+ display: none;
1718
+ }
1719
+
1720
  .happyforms-buttongroup-wrapper {
1721
  line-height: 1.5;
1722
  }
1793
 
1794
  .happyforms-buttongroup.happyforms-buttongroup-field_width {
1795
  margin-top: -1px;
1796
+ }
1797
+
1798
+ .happyforms-widget-content textarea[data-option-attribute=description] {
1799
+ margin-bottom: 5px;
1800
+ }
core/assets/css/layout.css CHANGED
@@ -142,8 +142,8 @@ h3.happyforms-form__title {
142
  top: -45px;
143
  }
144
 
145
- .happyforms-part--width-auto+.happyforms-part--submit input[type=submit],
146
- .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit] {
147
  width: 100%;
148
  padding: 17px 50px;
149
  }
@@ -168,30 +168,30 @@ h3.happyforms-form__title {
168
  padding-left: 0;
169
  }
170
 
171
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto+.happyforms-part--submit input[type=submit],
172
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit] {
173
  padding-top: 8px;
174
  padding-bottom: 9px;
175
  border-top-left-radius: 0;
176
  border-bottom-left-radius: 0;
177
  }
178
 
179
- .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-wide .happyforms-part--width-auto+.happyforms-part--submit input[type=submit],
180
- .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-wide .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit] {
181
  padding-top: 13px;
182
  padding-bottom: 15px;
183
  }
184
 
185
- .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-narrow .happyforms-part--width-auto+.happyforms-part--submit input[type=submit],
186
- .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-narrow .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit] {
187
  padding-top: 3px;
188
  padding-bottom: 4px;
189
  }
190
 
191
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-as_placeholder+.happyforms-part--submit input[type=submit],
192
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-inside+.happyforms-part--submit input[type=submit],
193
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-as_placeholder+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit],
194
- .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-inside+.happyforms-part--recaptcha+.happyforms-part--submit input[type=submit] {
195
  padding-top: 16px;
196
  padding-bottom: 18px;
197
  }
@@ -249,12 +249,20 @@ h3.happyforms-form__title {
249
  .happyforms-part input[type=tel],
250
  .happyforms-part input[type=number],
251
  .happyforms-part input[type=range],
252
- .happyforms-part textarea {
 
253
  width: 100%;
254
  box-sizing: border-box;
255
  max-width: none;
256
  }
257
 
 
 
 
 
 
 
 
258
  .happyforms-part textarea {
259
  height: auto;
260
  }
@@ -401,6 +409,14 @@ h3.happyforms-form__title {
401
  margin-right: 0;
402
  }
403
 
 
 
 
 
 
 
 
 
404
  @media screen and (max-width: 800px) {
405
  .happyforms-part--choice .option-label {
406
  margin-right: 0;
@@ -411,7 +427,7 @@ h3.happyforms-form__title {
411
  outline: 0;
412
  }
413
 
414
- .happyforms-part .option-label .label {
415
  position: relative;
416
  display: inline-block;
417
  padding: 0 10px;
@@ -431,8 +447,12 @@ h3.happyforms-form__title {
431
  display: block;
432
  width: 100%;
433
  max-width: 400px;
434
- margin-top: 3px;
435
- margin-right: 20px;
 
 
 
 
436
  }
437
 
438
  .happyforms-part--choice.display-type--block .happyforms-part-option__description {
@@ -442,6 +462,7 @@ h3.happyforms-form__title {
442
  .happyforms-part.display-type--block .option-label {
443
  display: flex;
444
  margin-right: 0;
 
445
  }
446
 
447
  /* parts - radio, checkbox */
@@ -534,11 +555,6 @@ h3.happyforms-form__title {
534
  margin-bottom: 0;
535
  }
536
 
537
- .happyforms-part.display-type--block .checkmark,
538
- .happyforms-part--legal .checkmark {
539
- margin-right: 5px;
540
- }
541
-
542
  .happyforms-part--label-below input,
543
  .happyforms-part--label-below textarea,
544
  .happyforms-part--label-below .happyforms-custom-select,
@@ -629,7 +645,7 @@ h3.happyforms-form__title {
629
  border-top: 6px solid;
630
  }
631
 
632
- .happyforms-part--select select:focus {
633
  outline-width: 1px;
634
  outline-color: #000000;
635
  }
@@ -891,11 +907,11 @@ form .happyforms-flex>.happyforms-message-notices .happyforms-message-notice a {
891
 
892
  /* submit button */
893
 
894
- .happyforms-form--submit-button-fullwidth input[type=submit].happyforms-button--submit {
895
  width: 100%;
896
  }
897
 
898
- input[type=submit][disabled].happyforms-button--submit {
899
  cursor: default;
900
  }
901
 
@@ -920,17 +936,12 @@ input[type=submit][disabled].happyforms-button--submit {
920
  }
921
 
922
  /* widget */
923
- .widget input[type=submit].happyforms-button--submit,
924
- .widget input[type=submit][disabled].happyforms-button--submit,
925
- .widget input[type=submit][disabled].happyforms-button--submit:hover {
926
  width: 100%;
927
  }
928
 
929
- /* new dropdowns */
930
- .happyforms-part select {
931
- display: none;
932
- }
933
-
934
  .happyforms-custom-select input[readonly="readonly"] {
935
  cursor: pointer;
936
  }
@@ -1094,9 +1105,10 @@ input[type=submit][disabled].happyforms-button--submit {
1094
  text-transform: lowercase;
1095
  }
1096
 
1097
- .happyforms-part--checkbox .option-label .label,
1098
- .happyforms-part--radio .option-label .label {
1099
  padding-right: 5px;
 
1100
  }
1101
 
1102
 
142
  top: -45px;
143
  }
144
 
145
+ .happyforms-part--width-auto+.happyforms-part--submit button[type=submit],
146
+ .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit] {
147
  width: 100%;
148
  padding: 17px 50px;
149
  }
168
  padding-left: 0;
169
  }
170
 
171
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto+.happyforms-part--submit button[type=submit],
172
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit] {
173
  padding-top: 8px;
174
  padding-bottom: 9px;
175
  border-top-left-radius: 0;
176
  border-bottom-left-radius: 0;
177
  }
178
 
179
+ .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-wide .happyforms-part--width-auto+.happyforms-part--submit button[type=submit],
180
+ .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-wide .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit] {
181
  padding-top: 13px;
182
  padding-bottom: 15px;
183
  }
184
 
185
+ .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-narrow .happyforms-part--width-auto+.happyforms-part--submit button[type=submit],
186
+ .happyforms-form--submit-part-of-input.happyforms-form--part-inner-padding-narrow .happyforms-part--width-auto+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit] {
187
  padding-top: 3px;
188
  padding-bottom: 4px;
189
  }
190
 
191
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-as_placeholder+.happyforms-part--submit button[type=submit],
192
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-inside+.happyforms-part--submit button[type=submit],
193
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-as_placeholder+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit],
194
+ .happyforms-form--submit-part-of-input .happyforms-part--width-auto.happyforms-part--label-inside+.happyforms-part--recaptcha+.happyforms-part--submit button[type=submit] {
195
  padding-top: 16px;
196
  padding-bottom: 18px;
197
  }
249
  .happyforms-part input[type=tel],
250
  .happyforms-part input[type=number],
251
  .happyforms-part input[type=range],
252
+ .happyforms-part textarea,
253
+ .happyforms-part.happyforms-part select.happyforms-select {
254
  width: 100%;
255
  box-sizing: border-box;
256
  max-width: none;
257
  }
258
 
259
+ .happyforms-part.happyforms-part select.happyforms-select {
260
+ appearance: none !important;
261
+ -moz-appearance: none !important;
262
+ -webkit-appearance: none !important;
263
+ background-image: none !important;
264
+ }
265
+
266
  .happyforms-part textarea {
267
  height: auto;
268
  }
409
  margin-right: 0;
410
  }
411
 
412
+ .happyforms-styles .happyforms-part .happyforms-part-option .option-label {
413
+ align-items: flex-start;
414
+ }
415
+
416
+ .happyforms-styles .happyforms-part .happyforms-part-option.disabled-option .option-label {
417
+ cursor: default;
418
+ }
419
+
420
  @media screen and (max-width: 800px) {
421
  .happyforms-part--choice .option-label {
422
  margin-right: 0;
427
  outline: 0;
428
  }
429
 
430
+ .happyforms-part .option-label .label-wrap {
431
  position: relative;
432
  display: inline-block;
433
  padding: 0 10px;
447
  display: block;
448
  width: 100%;
449
  max-width: 400px;
450
+ margin-top: 0px;
451
+ margin-left: 31px;
452
+ flex-basis: 100%;
453
+ font-weight: normal;
454
+ font-weight: var(--happyforms-form-font-weight);
455
+ line-height: 1.4;
456
  }
457
 
458
  .happyforms-part--choice.display-type--block .happyforms-part-option__description {
462
  .happyforms-part.display-type--block .option-label {
463
  display: flex;
464
  margin-right: 0;
465
+ flex-wrap: wrap;
466
  }
467
 
468
  /* parts - radio, checkbox */
555
  margin-bottom: 0;
556
  }
557
 
 
 
 
 
 
558
  .happyforms-part--label-below input,
559
  .happyforms-part--label-below textarea,
560
  .happyforms-part--label-below .happyforms-custom-select,
645
  border-top: 6px solid;
646
  }
647
 
648
+ .happyforms-part select:focus {
649
  outline-width: 1px;
650
  outline-color: #000000;
651
  }
907
 
908
  /* submit button */
909
 
910
+ .happyforms-form--submit-button-fullwidth button[type=submit].happyforms-button--submit {
911
  width: 100%;
912
  }
913
 
914
+ button[type=submit][disabled].happyforms-button--submit {
915
  cursor: default;
916
  }
917
 
936
  }
937
 
938
  /* widget */
939
+ .widget button[type=submit].happyforms-button--submit,
940
+ .widget button[type=submit][disabled].happyforms-button--submit,
941
+ .widget button[type=submit][disabled].happyforms-button--submit:hover {
942
  width: 100%;
943
  }
944
 
 
 
 
 
 
945
  .happyforms-custom-select input[readonly="readonly"] {
946
  cursor: pointer;
947
  }
1105
  text-transform: lowercase;
1106
  }
1107
 
1108
+ .happyforms-part--checkbox .option-label .label-wrap,
1109
+ .happyforms-part--radio .option-label .label-wrap {
1110
  padding-right: 5px;
1111
+ flex: 1;
1112
  }
1113
 
1114
 
core/assets/js/frontend/select.js CHANGED
@@ -5,24 +5,14 @@
5
  HappyForms.parts.select = {
6
  init: function( options ) {
7
  this.type = this.$el.data( 'happyforms-type' );
 
8
 
9
- this.$input = $( '[data-serialize]', this.$el );
10
- var $visualInput = $( 'input[type="text"]:not(.happyforms-select-dropdown-other)', this.$el );
11
- var $select = $( '.happyforms-custom-select-dropdown', this.$el );
12
-
13
- $visualInput.happyFormsSelect( {
14
- $input: this.$input,
15
- $select: $select,
16
- searchable: $visualInput.attr( 'data-searchable' ),
17
- required: 'undefined' === typeof this.$el.data( 'happyforms-required' ) ? false : true,
18
- });
19
-
20
- this.$input.on( 'blur', this.onBlur.bind(this) );
21
  },
22
 
23
  onBlur: function() {
24
  var $otherinput = $( '.happyforms-part-option--other input[type=text]', this.$el );
25
- if ( '999' === this.$input.val() ) {
26
  $otherinput.addClass( 'hf-show' );
27
  $otherinput.focus();
28
  } else {
@@ -33,23 +23,29 @@
33
  serialize: function() {
34
  var self = this;
35
 
36
- var serialized = this.$input.map( function( i, input ) {
37
- var $input = $( input, self.$el );
38
  var $customInput = 0;
39
 
40
- if ( 999 == $input.val() ) {
41
  $customInput = $( ' .happyforms-part-option--other input[type=text]', self.$el );
42
  }
43
 
 
 
 
 
 
 
44
  var keyValue = {
45
- name: $input.attr( 'name' ),
46
- value: $input.val()
47
  };
48
 
49
  if ( $customInput.length ) {
50
  var otherValue = $customInput.val();
51
 
52
- keyValue['value'] = [ $input.val(), otherValue ];
53
 
54
  keyValue['value'] = JSON.stringify( keyValue['value'] );
55
  }
5
  HappyForms.parts.select = {
6
  init: function( options ) {
7
  this.type = this.$el.data( 'happyforms-type' );
8
+ this.$select = $( '[data-serialize]', this.$el );
9
 
10
+ this.$select.on( 'blur', this.onBlur.bind(this) );
 
 
 
 
 
 
 
 
 
 
 
11
  },
12
 
13
  onBlur: function() {
14
  var $otherinput = $( '.happyforms-part-option--other input[type=text]', this.$el );
15
+ if ( '999' === this.$select.val() ) {
16
  $otherinput.addClass( 'hf-show' );
17
  $otherinput.focus();
18
  } else {
23
  serialize: function() {
24
  var self = this;
25
 
26
+ var serialized = this.$select.map( function( i, select ) {
27
+ var $select = $( select, self.$el );
28
  var $customInput = 0;
29
 
30
+ if ( 999 == $select.val() ) {
31
  $customInput = $( ' .happyforms-part-option--other input[type=text]', self.$el );
32
  }
33
 
34
+ var value = $select.val();
35
+
36
+ if ( null == value ) {
37
+ value = '';
38
+ }
39
+
40
  var keyValue = {
41
+ name: $select.attr( 'name' ),
42
+ value: value
43
  };
44
 
45
  if ( $customInput.length ) {
46
  var otherValue = $customInput.val();
47
 
48
+ keyValue['value'] = [ $select.val(), otherValue ];
49
 
50
  keyValue['value'] = JSON.stringify( keyValue['value'] );
51
  }
core/assets/js/lib/happyforms-select.js CHANGED
@@ -154,6 +154,10 @@
154
 
155
  var $li = $( e.currentTarget );
156
 
 
 
 
 
157
  if ( 'undefined' !== typeof $li.attr( 'data-value' ) ) {
158
  this.setValue( $li.data('value').toString() );
159
  }
@@ -520,4 +524,4 @@
520
  }
521
  });
522
  }
523
- } )( jQuery );
154
 
155
  var $li = $( e.currentTarget );
156
 
157
+ if ( 'undefined' !== typeof $li.attr( 'data-select-disabled' ) ) {
158
+ return;
159
+ }
160
+
161
  if ( 'undefined' !== typeof $li.attr( 'data-value' ) ) {
162
  this.setValue( $li.data('value').toString() );
163
  }
524
  }
525
  });
526
  }
527
+ } )( jQuery );
core/assets/js/parts/part-checkbox.js CHANGED
@@ -27,6 +27,7 @@
27
  defaults: {
28
  is_default: false,
29
  label: '',
 
30
  },
31
  } );
32
 
@@ -62,6 +63,7 @@
62
 
63
  onItemLimitSubmissionsChange: function( e ) {
64
  var isChecked = $( e.target ).is( ':checked' );
 
65
 
66
  if ( ! isChecked ) {
67
  this.model.set( 'show_submissions_amount', 0 );
@@ -70,6 +72,16 @@
70
 
71
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
72
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
 
 
 
 
 
 
 
 
 
 
73
  },
74
 
75
  onChangeShowSubmissions: function( e ) {
@@ -91,7 +103,7 @@
91
 
92
  var model = this.part;
93
 
94
- if ( 1 != this.model.get('show_submissions_amount') ) {
95
  return;
96
  }
97
 
@@ -167,15 +179,28 @@
167
  this.model.set( 'description', $( e.target ).val() );
168
  this.part.trigger( 'change' );
169
 
170
- var data = {
171
- id: this.part.get( 'id' ),
172
- callback: 'onCheckboxItemDescriptionChangeCallback',
173
- options: {
174
- itemID: this.model.get( 'id' ),
175
- }
176
- };
177
 
178
- happyForms.previewSend( 'happyforms-part-dom-update', data );
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  },
180
 
181
  onItemDefaultChange: function( e ) {
@@ -212,7 +237,7 @@
212
  'click .import-option': 'onImportOptionClick',
213
  'click .import-options': 'onImportOptionsClick',
214
  'click .add-options': 'onAddOptionsClick',
215
- 'change [name=display_type]': 'onDisplayTypeChange',
216
  'keyup [name=label]': 'onEnterKey',
217
  'keyup [name=description]': 'onEnterKey',
218
 
@@ -396,13 +421,6 @@
396
 
397
  this.model.set( attribute, $input.val() );
398
 
399
- $( '.part-options-width-setting select option', this.$el ).hide();
400
-
401
- var $supportedOptions = $( '.part-options-width-setting select option.display-type--' + value, this.$el );
402
- $supportedOptions.show();
403
-
404
- $( '.part-options-width-setting select' ).val( 'auto' ).trigger( 'change' );
405
-
406
  var data = {
407
  id: this.model.get( 'id' ),
408
  callback: 'onCheckboxDisplayTypeChangeCallback',
27
  defaults: {
28
  is_default: false,
29
  label: '',
30
+ description: '',
31
  },
32
  } );
33
 
63
 
64
  onItemLimitSubmissionsChange: function( e ) {
65
  var isChecked = $( e.target ).is( ':checked' );
66
+ var model = this.part;
67
 
68
  if ( ! isChecked ) {
69
  this.model.set( 'show_submissions_amount', 0 );
72
 
73
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
74
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
75
+
76
+ this.part.fetchHtml( function( response ) {
77
+ var data = {
78
+ id: model.get( 'id' ),
79
+ html: response,
80
+ };
81
+
82
+ happyForms.previewSend( 'happyforms-form-part-refresh', data );
83
+
84
+ } );
85
  },
86
 
87
  onChangeShowSubmissions: function( e ) {
103
 
104
  var model = this.part;
105
 
106
+ if ( 1 != this.model.get('limit_submissions') ) {
107
  return;
108
  }
109
 
179
  this.model.set( 'description', $( e.target ).val() );
180
  this.part.trigger( 'change' );
181
 
182
+ if ( '' == this.model.previousAttributes().description || '' == this.model.get( 'description' ) ) {
183
+ var self = this;
184
+ this.part.fetchHtml( function( response ) {
185
+ var data = {
186
+ id: self.part.get( 'id' ),
187
+ html: response,
188
+ };
189
 
190
+ happyForms.previewSend( 'happyforms-form-part-refresh', data );
191
+ } );
192
+ } else {
193
+
194
+ var data = {
195
+ id: this.part.get( 'id' ),
196
+ callback: 'onCheckboxItemDescriptionChangeCallback',
197
+ options: {
198
+ itemID: this.model.get( 'id' ),
199
+ }
200
+ };
201
+
202
+ happyForms.previewSend( 'happyforms-part-dom-update', data );
203
+ }
204
  },
205
 
206
  onItemDefaultChange: function( e ) {
237
  'click .import-option': 'onImportOptionClick',
238
  'click .import-options': 'onImportOptionsClick',
239
  'click .add-options': 'onAddOptionsClick',
240
+ 'change [data-bind=display_type]': 'onDisplayTypeChange',
241
  'keyup [name=label]': 'onEnterKey',
242
  'keyup [name=description]': 'onEnterKey',
243
 
421
 
422
  this.model.set( attribute, $input.val() );
423
 
 
 
 
 
 
 
 
424
  var data = {
425
  id: this.model.get( 'id' ),
426
  callback: 'onCheckboxDisplayTypeChangeCallback',
core/assets/js/parts/part-radio.js CHANGED
@@ -103,15 +103,28 @@
103
  this.model.set( 'description', $( e.target ).val() );
104
  this.part.trigger( 'change' );
105
 
106
- var data = {
107
- id: this.part.get( 'id' ),
108
- callback: 'onRadioItemDescriptionChangeCallback',
109
- options: {
110
- itemID: this.model.get( 'id' ),
111
- }
112
- };
113
 
114
- happyForms.previewSend( 'happyforms-part-dom-update', data );
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  },
116
 
117
  onItemDefaultChange: function( e ) {
@@ -141,6 +154,7 @@
141
 
142
  onItemLimitSubmissionsChange: function( e ) {
143
  var isChecked = $( e.target ).is( ':checked' );
 
144
 
145
  if ( ! isChecked ) {
146
  this.model.set( 'show_submissions_amount', 0 );
@@ -149,6 +163,16 @@
149
 
150
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
151
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
 
 
 
 
 
 
 
 
 
 
152
  },
153
 
154
  onChangeShowSubmissions: function( e ) {
@@ -170,7 +194,7 @@
170
 
171
  var model = this.part;
172
 
173
- if ( 1 != this.model.get('show_submissions_amount') ) {
174
  return;
175
  }
176
 
@@ -207,7 +231,7 @@
207
  'click .import-option': 'onImportOptionClick',
208
  'click .import-options': 'onImportOptionsClick',
209
  'click .add-options': 'onAddOptionsClick',
210
- 'change [name=display_type]': 'onDisplayTypeChange',
211
  'keyup [name=label]': 'onEnterKey',
212
  'keyup [name=description]': 'onEnterKey',
213
  } ),
@@ -381,13 +405,6 @@
381
 
382
  this.model.set( attribute, value );
383
 
384
- $( '.part-options-width-setting select option', this.$el ).hide();
385
-
386
- var $supportedOptions = $( '.part-options-width-setting select option.display-type--' + value, this.$el );
387
- $supportedOptions.show();
388
-
389
- $( '.part-options-width-setting select' ).val( 'auto' ).trigger( 'change' );
390
-
391
  var data = {
392
  id: this.model.get( 'id' ),
393
  callback: 'onRadioDisplayTypeChangeCallback',
103
  this.model.set( 'description', $( e.target ).val() );
104
  this.part.trigger( 'change' );
105
 
106
+ if ( '' == this.model.previousAttributes().description || '' == this.model.get( 'description' ) ) {
107
+ var self = this;
108
+ this.part.fetchHtml( function( response ) {
109
+ var data = {
110
+ id: self.part.get( 'id' ),
111
+ html: response,
112
+ };
113
 
114
+ happyForms.previewSend( 'happyforms-form-part-refresh', data );
115
+ } );
116
+ } else {
117
+ var data = {
118
+ id: this.part.get( 'id' ),
119
+ callback: 'onRadioItemDescriptionChangeCallback',
120
+ options: {
121
+ itemID: this.model.get( 'id' ),
122
+ }
123
+ };
124
+
125
+ happyForms.previewSend( 'happyforms-part-dom-update', data );
126
+
127
+ }
128
  },
129
 
130
  onItemDefaultChange: function( e ) {
154
 
155
  onItemLimitSubmissionsChange: function( e ) {
156
  var isChecked = $( e.target ).is( ':checked' );
157
+ var model = this.part;
158
 
159
  if ( ! isChecked ) {
160
  this.model.set( 'show_submissions_amount', 0 );
163
 
164
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
165
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
166
+
167
+ this.part.fetchHtml( function( response ) {
168
+ var data = {
169
+ id: model.get( 'id' ),
170
+ html: response,
171
+ };
172
+
173
+ happyForms.previewSend( 'happyforms-form-part-refresh', data );
174
+
175
+ } );
176
  },
177
 
178
  onChangeShowSubmissions: function( e ) {
194
 
195
  var model = this.part;
196
 
197
+ if ( 1 != this.model.get('limit_submissions') ) {
198
  return;
199
  }
200
 
231
  'click .import-option': 'onImportOptionClick',
232
  'click .import-options': 'onImportOptionsClick',
233
  'click .add-options': 'onAddOptionsClick',
234
+ 'change [data-bind=display_type]': 'onDisplayTypeChange',
235
  'keyup [name=label]': 'onEnterKey',
236
  'keyup [name=description]': 'onEnterKey',
237
  } ),
405
 
406
  this.model.set( attribute, value );
407
 
 
 
 
 
 
 
 
408
  var data = {
409
  id: this.model.get( 'id' ),
410
  callback: 'onRadioDisplayTypeChangeCallback',
core/assets/js/parts/part-select.js CHANGED
@@ -133,6 +133,7 @@
133
 
134
  onItemLimitSubmissionsChange: function( e ) {
135
  var isChecked = $( e.target ).is( ':checked' );
 
136
 
137
  if ( ! isChecked ) {
138
  this.model.set( 'show_submissions_amount', 0 );
@@ -141,6 +142,16 @@
141
 
142
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
143
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
 
 
 
 
 
 
 
 
 
 
144
  },
145
 
146
  onItemLimitSubmissionsAmountChange: function( e ) {
@@ -174,7 +185,7 @@
174
 
175
  var model = this.part;
176
 
177
- if ( 1 != this.model.get('show_submissions_amount') ) {
178
  return;
179
  }
180
 
@@ -566,8 +577,7 @@
566
  onSelectPlaceholderChangeCallback: function( id, html, options, $ ) {
567
  var $part = this.getPartElement( html );
568
 
569
- $( 'input', $part ).attr( 'placeholder', options.label );
570
- $( '.happyforms-custom-select-dropdown__placeholder', $part ).removeClass('preview-hidden').text( options.label );
571
  },
572
 
573
  onSelectOtherOptionLabelChangeCallback: function( id, html, options ) {
133
 
134
  onItemLimitSubmissionsChange: function( e ) {
135
  var isChecked = $( e.target ).is( ':checked' );
136
+ var model = this.part;
137
 
138
  if ( ! isChecked ) {
139
  this.model.set( 'show_submissions_amount', 0 );
142
 
143
  this.model.set( 'limit_submissions', isChecked ? 1 : 0 );
144
  $( '.happyforms-part-item-limit-submission-settings', this.$el ).toggle();
145
+
146
+ this.part.fetchHtml( function( response ) {
147
+ var data = {
148
+ id: model.get( 'id' ),
149
+ html: response,
150
+ };
151
+
152
+ happyForms.previewSend( 'happyforms-form-part-refresh', data );
153
+
154
+ } );
155
  },
156
 
157
  onItemLimitSubmissionsAmountChange: function( e ) {
185
 
186
  var model = this.part;
187
 
188
+ if ( 1 != this.model.get('limit_submissions') ) {
189
  return;
190
  }
191
 
577
  onSelectPlaceholderChangeCallback: function( id, html, options, $ ) {
578
  var $part = this.getPartElement( html );
579
 
580
+ $( 'select option.happyforms-placeholder-option', $part ).text( options.label );
 
581
  },
582
 
583
  onSelectOtherOptionLabelChangeCallback: function( id, html, options ) {
core/assets/svg/icons/rank.svg DELETED
@@ -1 +0,0 @@
1
- <svg enable-background="new 0 0 24 24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h24v24h-24z" fill="none"/><path d="m2 17h2v.5h-1v1h1v.5h-2v1h3v-4h-3zm1-9h1v-4h-2v1h1zm-1 3h1.8l-1.8 2.1v.9h3v-1h-1.8l1.8-2.1v-.9h-3zm5-6v2h14v-2zm0 14h14v-2h-14zm0-6h14v-2h-14z"/></svg>
 
core/classes/class-form-option-limiter.php CHANGED
@@ -17,7 +17,6 @@ class HappyForms_Form_Option_Limiter {
17
 
18
  public function hook() {
19
  add_filter( 'happyforms_part_options', array( $this, 'get_part_options' ), 10, 3 );
20
- add_filter( 'happyforms_get_form_parts', array( $this, 'get_form_parts' ), 10, 2 );
21
  add_action( 'happyforms_submission_success', array( $this, 'submission_success' ), 10, 3 );
22
  }
23
 
@@ -51,18 +50,9 @@ class HappyForms_Form_Option_Limiter {
51
  return $option;
52
  }, $options );
53
 
54
- // Remove exhausted choices
55
- $options = array_filter( $options, function( $option ) {
56
- if ( intval( $option['limit_submissions'] ) ) {
57
- return $option['submissions_left'] > 0;
58
- }
59
-
60
- return $option;
61
- } );
62
-
63
  // Add remaining choices labels
64
  $options = array_map( function( $option ) use( $form ) {
65
- if ( 1 == $option['show_submissions_amount'] ) {
66
  $submissions_left_label = $form['submissions_left_label'];
67
 
68
  if ( happyforms_is_preview() ) {
@@ -150,45 +140,6 @@ class HappyForms_Form_Option_Limiter {
150
  happyforms_update_meta( $form['ID'], $this->counter_key, $meta_counters );
151
  }
152
 
153
- public function get_form_parts( $parts, $form ) {
154
- $this->try_migrate_limit_count_options( $form );
155
-
156
- foreach( $parts as $p => $part ) {
157
- if ( ! in_array( $part['type'], $this->get_supported_parts() ) ) {
158
- continue;
159
- }
160
-
161
- $options_key = 'options';
162
-
163
- if ( 'table' === $part['type'] ) {
164
- $options_key = 'columns';
165
- }
166
-
167
- $options = $part[$options_key];
168
-
169
- foreach( $options as $o => $option ) {
170
- $option = wp_parse_args( $option, $this->get_option_fields() );
171
-
172
- if ( ! $option['limit_submissions'] ) {
173
- continue;
174
- }
175
-
176
- $limit = intval( $option['limit_submissions_amount'] );
177
- $count = $this->count_by_option( $form['ID'], $part['id'], $option['id'] );
178
-
179
- if ( $limit <= $count ) {
180
- unset( $part[$options_key][$o] );
181
- }
182
-
183
- if ( 0 === count( $part[$options_key] ) ) {
184
- unset( $parts[$p] );
185
- }
186
- }
187
- }
188
-
189
- return $parts;
190
- }
191
-
192
  public function count_by_option( $form_id, $part_id, $option_id ) {
193
  $count = 0;
194
  $counters = happyforms_get_meta( $form_id, $this->counter_key, true );
17
 
18
  public function hook() {
19
  add_filter( 'happyforms_part_options', array( $this, 'get_part_options' ), 10, 3 );
 
20
  add_action( 'happyforms_submission_success', array( $this, 'submission_success' ), 10, 3 );
21
  }
22
 
50
  return $option;
51
  }, $options );
52
 
 
 
 
 
 
 
 
 
 
53
  // Add remaining choices labels
54
  $options = array_map( function( $option ) use( $form ) {
55
+ if ( 1 == $option['show_submissions_amount'] || ( ( 0 == $option['submissions_left'] ) && ( 1 == $option['limit_submissions'] ) ) ) {
56
  $submissions_left_label = $form['submissions_left_label'];
57
 
58
  if ( happyforms_is_preview() ) {
140
  happyforms_update_meta( $form['ID'], $this->counter_key, $meta_counters );
141
  }
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  public function count_by_option( $form_id, $part_id, $option_id ) {
144
  $count = 0;
145
  $counters = happyforms_get_meta( $form_id, $this->counter_key, true );
core/classes/class-form-shuffle.php CHANGED
@@ -40,7 +40,7 @@ class HappyForms_Form_Shuffle_Parts {
40
  $setup_controls = array(
41
  1450 => array(
42
  'field' => 'shuffle_parts',
43
- 'label' => __( 'Randomize fields to prevent bias', 'happyforms' ),
44
  'type' => 'checkbox'
45
  ),
46
  );
40
  $setup_controls = array(
41
  1450 => array(
42
  'field' => 'shuffle_parts',
43
+ 'label' => __( 'Shuffle order of fields', 'happyforms' ),
44
  'type' => 'checkbox'
45
  ),
46
  );
core/classes/parts/class-part-select.php CHANGED
@@ -53,7 +53,7 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
53
  'sanitize' => 'sanitize_text_field'
54
  ),
55
  'placeholder' => array(
56
- 'default' => __( 'Choose', 'happyforms' ),
57
  'sanitize' => 'sanitize_text_field',
58
  ),
59
  'width' => array(
@@ -360,7 +360,7 @@ class HappyForms_Part_Select extends HappyForms_Form_Part {
360
  wp_register_script(
361
  'happyforms-dropdown',
362
  happyforms_get_plugin_url() . 'core/assets/js/frontend/select.js',
363
- array( 'happyforms-select' ), HAPPYFORMS_VERSION, true
364
  );
365
 
366
  $deps[] = 'happyforms-dropdown';
53
  'sanitize' => 'sanitize_text_field'
54
  ),
55
  'placeholder' => array(
56
+ 'default' => '',
57
  'sanitize' => 'sanitize_text_field',
58
  ),
59
  'width' => array(
360
  wp_register_script(
361
  'happyforms-dropdown',
362
  happyforms_get_plugin_url() . 'core/assets/js/frontend/select.js',
363
+ array(), HAPPYFORMS_VERSION, true
364
  );
365
 
366
  $deps[] = 'happyforms-dropdown';
core/templates/partials/form-submit.php CHANGED
@@ -5,6 +5,6 @@
5
  } ?>
6
  <div class="happyforms-form__part happyforms-part happyforms-part--submit">
7
  <?php do_action( 'happyforms_form_submit_before', $form ); ?>
8
- <input type="submit" class="happyforms-submit happyforms-button--submit <?php echo $submit_button_extra_class; ?>" value="<?php echo esc_attr( happyforms_get_form_property( $form, 'submit_button_label' ) ); ?>">
9
  <?php do_action( 'happyforms_form_submit_after', $form ); ?>
10
  </div>
5
  } ?>
6
  <div class="happyforms-form__part happyforms-part happyforms-part--submit">
7
  <?php do_action( 'happyforms_form_submit_before', $form ); ?>
8
+ <button type="submit" class="happyforms-submit happyforms-button--submit <?php echo $submit_button_extra_class; ?>"><?php echo esc_attr( happyforms_get_form_property( $form, 'submit_button_label' ) ); ?></button>
9
  <?php do_action( 'happyforms_form_submit_after', $form ); ?>
10
  </div>
core/templates/partials/happyforms-select.php CHANGED
@@ -1,7 +1,7 @@
1
  <ul class="happyforms-custom-select-dropdown">
2
  <li class="happyforms-custom-select-dropdown__placeholder" data-value="" data-label=""><?php echo $placeholder_value; ?></li>
3
  <?php foreach ( $options as $index => $option ) : ?>
4
- <li <?php echo ( isset( $option['id'] ) ) ? 'data-option-id="'. esc_attr( $option['id'] ) .'" ' : ''; ?>data-value="<?php echo ( isset( $option['value'] ) ) ? $option['value'] : $index; ?>" data-label="<?php echo esc_attr( $option['label'] ); ?>" class="happyforms-dropdown-item happyforms-custom-select-dropdown__item"><?php echo esc_attr( $option['label'] ); ?> <?php echo ( isset( $option['submissions_left_label'] ) ) ? $option['submissions_left_label'] : ''; ?></li>
5
  <?php endforeach; ?>
6
  <?php if ( count( $options ) > 5 ) : ?>
7
  <li class="happyforms-custom-select-dropdown__not-found"><?php echo esc_attr( $form['no_results_label'] ); ?></li>
1
  <ul class="happyforms-custom-select-dropdown">
2
  <li class="happyforms-custom-select-dropdown__placeholder" data-value="" data-label=""><?php echo $placeholder_value; ?></li>
3
  <?php foreach ( $options as $index => $option ) : ?>
4
+ <li <?php echo ( isset( $option['id'] ) ) ? 'data-option-id="'. esc_attr( $option['id'] ) .'" ' : ''; ?>data-value="<?php echo ( isset( $option['value'] ) ) ? $option['value'] : $index; ?>" data-label="<?php echo esc_attr( $option['label'] ); ?>" class="happyforms-dropdown-item happyforms-custom-select-dropdown__item" <?php echo ( empty( $option['submissions_left'] ) && ! empty( $option['limit_submissions'] ) ) ? 'data-select-disabled="1"' : ''; ?>><?php echo esc_attr( $option['label'] ); ?> <?php echo ( isset( $option['submissions_left_label'] ) ) ? $option['submissions_left_label'] : ''; ?></li>
5
  <?php endforeach; ?>
6
  <?php if ( count( $options ) > 5 ) : ?>
7
  <li class="happyforms-custom-select-dropdown__not-found"><?php echo esc_attr( $form['no_results_label'] ); ?></li>
core/templates/parts/customize-checkbox.php CHANGED
@@ -73,7 +73,7 @@
73
  <% } %>
74
  <p>
75
  <label>
76
- <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Randomize choices to prevent bias', 'happyforms' ); ?>
77
  </label>
78
  </p>
79
  <p>
@@ -92,11 +92,17 @@
92
  </p>
93
  </div>
94
  <p>
95
- <label for="<%= instance.id %>_display_type"><?php _e( 'Choices display', 'happyforms' ); ?></label>
96
- <select id="<%= instance.id %>_display_type" name="display_type" data-bind="display_type" class="widefat">
97
- <option value="inline"<%= (instance.display_type == 'inline') ? ' selected' : '' %>><?php _e( 'Horizontal', 'happyforms' ); ?></option>
98
- <option value="block"<%= (instance.display_type == 'block') ? ' selected' : '' %>><?php _e( 'Vertical', 'happyforms' ); ?></option>
99
- </select>
 
 
 
 
 
 
100
  </p>
101
 
102
  <?php happyforms_customize_part_width_control(); ?>
@@ -125,6 +131,10 @@
125
  <input type="text" class="widefat" name="label" value="<%= label %>">
126
  </label>
127
  <div class="happyforms-part-item-advanced">
 
 
 
 
128
  <label>
129
  <input type="checkbox" name="is_default" value="1" <% if (is_default == 1) { %> checked="checked"<% } %>> <?php _e( 'Make this choice default', 'happyforms' ); ?>
130
  </label><br>
73
  <% } %>
74
  <p>
75
  <label>
76
+ <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Shuffle order of choices', 'happyforms' ); ?>
77
  </label>
78
  </p>
79
  <p>
92
  </p>
93
  </div>
94
  <p>
95
+ <label for="<%= instance.id %>_display_type"><?php _e( 'Align choices', 'happyforms' ); ?></label>
96
+ <span class="happyforms-buttongroup">
97
+ <label for="<%= instance.id %>-display_type-vertical">
98
+ <input type="radio" id="<%= instance.id %>-display_type-vertical" value="block" name="<%= instance.id %>-display_type" data-bind="display_type" <%= ( instance.display_type == 'block' ) ? 'checked' : '' %> />
99
+ <span><?php _e( 'Vertically', 'happyforms' ); ?></span>
100
+ </label>
101
+ <label for="<%= instance.id %>-display_type-horizontal">
102
+ <input type="radio" id="<%= instance.id %>-display_type-horizontal" value="inline" name="<%= instance.id %>-display_type" data-bind="display_type" <%= ( instance.display_type == 'inline' ) ? 'checked' : '' %> />
103
+ <span><?php _e( 'Horizontally', 'happyforms' ); ?></span>
104
+ </label>
105
+ </span>
106
  </p>
107
 
108
  <?php happyforms_customize_part_width_control(); ?>
131
  <input type="text" class="widefat" name="label" value="<%= label %>">
132
  </label>
133
  <div class="happyforms-part-item-advanced">
134
+ <label>
135
+ <?php _e( 'Hint', 'happyforms' ); ?>:
136
+ <textarea name="description" data-option-attribute="description"><%= description %></textarea>
137
+ </label><br>
138
  <label>
139
  <input type="checkbox" name="is_default" value="1" <% if (is_default == 1) { %> checked="checked"<% } %>> <?php _e( 'Make this choice default', 'happyforms' ); ?>
140
  </label><br>
core/templates/parts/customize-radio.php CHANGED
@@ -73,15 +73,21 @@
73
  <% } %>
74
  <p>
75
  <label>
76
- <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Randomize choices to prevent bias', 'happyforms' ); ?>
77
  </label>
78
  </p>
79
  <p>
80
- <label for="<%= instance.id %>_display_type"><?php _e( 'Choices display', 'happyforms' ); ?></label>
81
- <select id="<%= instance.id %>_display_type" name="display_type" data-bind="display_type" class="widefat">
82
- <option value="inline"<%= (instance.display_type == 'inline') ? ' selected' : '' %>><?php _e( 'Horizontal', 'happyforms' ); ?></option>
83
- <option value="block"<%= (instance.display_type == 'block') ? ' selected' : '' %>><?php _e( 'Vertical', 'happyforms' ); ?></option>
84
- </select>
 
 
 
 
 
 
85
  </p>
86
 
87
  <?php happyforms_customize_part_width_control(); ?>
@@ -110,6 +116,10 @@
110
  <input type="text" class="widefat" name="label" value="<%= label %>" data-option-attribute="label">
111
  </label>
112
  <div class="happyforms-part-item-advanced">
 
 
 
 
113
  <label>
114
  <input type="checkbox" name="is_default" value="1" class="default-option-switch"<% if (is_default == 1) { %> checked="checked"<% } %>> <?php _e( 'Make this choice default', 'happyforms' ); ?>
115
  </label><br>
73
  <% } %>
74
  <p>
75
  <label>
76
+ <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Shuffle order of choices', 'happyforms' ); ?>
77
  </label>
78
  </p>
79
  <p>
80
+ <label for="<%= instance.id %>_display_type"><?php _e( 'Align choices', 'happyforms' ); ?></label>
81
+ <span class="happyforms-buttongroup">
82
+ <label for="<%= instance.id %>-display_type-vertical">
83
+ <input type="radio" id="<%= instance.id %>-display_type-vertical" value="block" name="<%= instance.id %>-display_type" data-bind="display_type" <%= ( instance.display_type == 'block' ) ? 'checked' : '' %> />
84
+ <span><?php _e( 'Vertically', 'happyforms' ); ?></span>
85
+ </label>
86
+ <label for="<%= instance.id %>-display_type-horizontal">
87
+ <input type="radio" id="<%= instance.id %>-display_type-horizontal" value="inline" name="<%= instance.id %>-display_type" data-bind="display_type" <%= ( instance.display_type == 'inline' ) ? 'checked' : '' %> />
88
+ <span><?php _e( 'Horizontally', 'happyforms' ); ?></span>
89
+ </label>
90
+ </span>
91
  </p>
92
 
93
  <?php happyforms_customize_part_width_control(); ?>
116
  <input type="text" class="widefat" name="label" value="<%= label %>" data-option-attribute="label">
117
  </label>
118
  <div class="happyforms-part-item-advanced">
119
+ <label>
120
+ <?php _e( 'Hint', 'happyforms' ); ?>:
121
+ <textarea name="description" data-option-attribute="description"><%= description %></textarea>
122
+ </label><br>
123
  <label>
124
  <input type="checkbox" name="is_default" value="1" class="default-option-switch"<% if (is_default == 1) { %> checked="checked"<% } %>> <?php _e( 'Make this choice default', 'happyforms' ); ?>
125
  </label><br>
core/templates/parts/customize-select.php CHANGED
@@ -79,7 +79,7 @@
79
 
80
  <p>
81
  <label>
82
- <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Randomize choices to prevent bias', 'happyforms' ); ?>
83
  </label>
84
  </p>
85
 
79
 
80
  <p>
81
  <label>
82
+ <input type="checkbox" class="checkbox" value="1" <% if ( instance.shuffle_options ) { %>checked="checked"<% } %> data-bind="shuffle_options" /> <?php _e( 'Shuffle order of choices', 'happyforms' ); ?>
83
  </label>
84
  </p>
85
 
core/templates/parts/frontend-checkbox.php CHANGED
@@ -16,20 +16,30 @@
16
  $value = happyforms_get_part_value( $part, $form );
17
 
18
  foreach( $options as $o => $option ) : ?>
19
- <div class="happyforms-part__option happyforms-part-option" id="<?php echo esc_attr( $option['id'] ); ?>">
20
  <?php
21
  $checked = in_array( $o, $value ) ? 'checked="checked"' : '';
 
22
 
23
  if ( empty( $checked ) ) {
24
  $checked = checked( 1, $option['is_default'], false );
25
  }
 
 
 
 
 
26
  ?>
 
27
  <label class="option-label">
28
- <input type="checkbox" class="happyforms-visuallyhidden happyforms-checkbox" name="<?php happyforms_the_part_name( $part, $form ); ?>[]" value="<?php echo $o; ?>" data-serialize <?php echo $checked; ?> <?php happyforms_the_part_attributes( $part, $form ); ?>>
29
  <span class="checkmark"><?php echo $checkmark_content; ?></span>
30
- <span class="label"><?php echo esc_attr( $option['label'] ); ?></span><?php echo $option['submissions_left_label']; ?>
 
 
31
  </label>
32
- <span class="happyforms-part-option__description"><?php echo esc_attr( $option['description'] ); ?></span>
 
 
33
  </div>
34
  <?php endforeach; ?>
35
 
16
  $value = happyforms_get_part_value( $part, $form );
17
 
18
  foreach( $options as $o => $option ) : ?>
 
19
  <?php
20
  $checked = in_array( $o, $value ) ? 'checked="checked"' : '';
21
+ $option_classes = 'happyforms-part__option happyforms-part-option';
22
 
23
  if ( empty( $checked ) ) {
24
  $checked = checked( 1, $option['is_default'], false );
25
  }
26
+
27
+ if ( 1 == $option['limit_submissions'] && 0 == $option['submissions_left'] ) {
28
+ $option_classes .= ' disabled-option';
29
+ }
30
+
31
  ?>
32
+ <div class="<?php echo $option_classes; ?>" id="<?php echo esc_attr( $option['id'] ); ?>">
33
  <label class="option-label">
34
+ <input type="checkbox" class="happyforms-visuallyhidden happyforms-checkbox" name="<?php happyforms_the_part_name( $part, $form ); ?>[]" value="<?php echo $o; ?>" data-serialize <?php echo $checked; ?> <?php happyforms_the_part_attributes( $part, $form ); ?> <?php echo ( empty( $option['submissions_left'] ) && $option['limit_submissions'] ) ? 'disabled' : '' ?> >
35
  <span class="checkmark"><?php echo $checkmark_content; ?></span>
36
+ <span class="label-wrap">
37
+ <span class="label"><?php echo esc_attr( $option['label'] ); ?></span><?php echo $option['submissions_left_label']; ?>
38
+ </span>
39
  </label>
40
+ <?php if ( ! empty( $option['description'] ) ) : ?>
41
+ <div class="happyforms-part-option__description"><?php echo esc_attr( $option['description'] ); ?></div>
42
+ <?php endif; ?>
43
  </div>
44
  <?php endforeach; ?>
45
 
core/templates/parts/frontend-radio.php CHANGED
@@ -13,25 +13,34 @@
13
  $checkmark_content = '<span class="happyforms-radio-circle"></span>';
14
 
15
  foreach( $options as $o => $option ) : ?>
16
- <?php
17
- $checked = false;
 
 
 
 
 
18
 
19
- if ( is_string( $value ) ) {
20
- $checked = checked( $value, $o, false );
21
- }
22
 
23
- if ( false === $checked ) {
24
- $checked = checked( 1, $option['is_default'], false );
25
- }
26
 
27
- ?>
28
- <div class="happyforms-part__option happyforms-part-option" id="<?php echo esc_attr( $option['id'] ); ?>">
29
  <label class="option-label">
30
- <input type="radio" class="happyforms-visuallyhidden" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php echo $o; ?>" <?php echo $checked; ?> <?php happyforms_the_part_attributes( $part, $form ); ?>>
31
  <span class="checkmark"><?php echo $checkmark_content; ?></span>
32
- <span class="label"><?php echo esc_attr( $option['label'] ); ?></span><?php echo $option['submissions_left_label']; ?>
 
 
33
  </label>
34
- <span class="happyforms-part-option__description"><?php echo esc_attr( $option['description'] ); ?></span>
 
 
35
  </div>
36
  <?php endforeach; ?>
37
 
13
  $checkmark_content = '<span class="happyforms-radio-circle"></span>';
14
 
15
  foreach( $options as $o => $option ) : ?>
16
+ <?php
17
+ $checked = false;
18
+ $option_classes = 'happyforms-part__option happyforms-part-option';
19
+
20
+ if ( is_string( $value ) ) {
21
+ $checked = checked( $value, $o, false );
22
+ }
23
 
24
+ if ( false === $checked ) {
25
+ $checked = checked( 1, $option['is_default'], false );
26
+ }
27
 
28
+ if ( 1 == $option['limit_submissions'] && 0 == $option['submissions_left'] ) {
29
+ $option_classes .= ' disabled-option';
30
+ }
31
 
32
+ ?>
33
+ <div class="<?php echo $option_classes; ?>" id="<?php echo esc_attr( $option['id'] ); ?>">
34
  <label class="option-label">
35
+ <input type="radio" class="happyforms-visuallyhidden" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php echo $o; ?>" <?php echo $checked; ?> <?php happyforms_the_part_attributes( $part, $form ); ?> <?php echo ( empty( $option['submissions_left'] ) && $option['limit_submissions'] ) ? 'disabled' : '' ?>>
36
  <span class="checkmark"><?php echo $checkmark_content; ?></span>
37
+ <span class="label-wrap">
38
+ <span class="label"><?php echo esc_attr( $option['label'] ); ?></span><?php echo $option['submissions_left_label']; ?>
39
+ </span>
40
  </label>
41
+ <?php if ( ! empty( $option['description'] ) ) : ?>
42
+ <div class="happyforms-part-option__description"><?php echo esc_attr( $option['description'] ); ?></div>
43
+ <?php endif; ?>
44
  </div>
45
  <?php endforeach; ?>
46
 
core/templates/parts/frontend-select.php CHANGED
@@ -6,6 +6,7 @@
6
 
7
  <?php
8
  $options = happyforms_get_part_options( $part['options'], $part, $form );
 
9
  $value = happyforms_get_part_value( $part, $form );
10
  $default_label = '';
11
 
@@ -22,15 +23,10 @@
22
 
23
  $placeholder_text = $part['placeholder'];
24
  ?>
25
-
26
  <div class="happyforms-part__el">
27
  <?php do_action( 'happyforms_part_input_before', $part, $form ); ?>
28
  <div class="happyforms-custom-select">
29
  <div class="happyforms-part__select-wrap">
30
- <input type="hidden" name="<?php happyforms_the_part_name( $part, $form ); ?>" value="<?php echo $value; ?>" data-serialize />
31
-
32
- <input id="<?php happyforms_the_part_id( $part, $form ); ?>" type="text" value="<?php echo $default_label; ?>" placeholder="<?php echo $placeholder_text; ?>" data-searchable="<?php echo ( count( $part['options'] ) > 5 ) ? 'true' : 'false'; ?>" autocomplete="off" <?php happyforms_the_part_attributes( $part, $form ); ?> />
33
-
34
  <?php
35
  $other_select = ( !empty( $part['other_option'] ) ) ? $part['other_option_label'] : '';
36
 
@@ -40,8 +36,20 @@
40
  'label' => $other_select,
41
  );
42
  }
 
43
  ?>
44
- <?php happyforms_select( $options, $part, $form ); ?>
 
 
 
 
 
 
 
 
 
 
 
45
  </div>
46
  </div>
47
 
6
 
7
  <?php
8
  $options = happyforms_get_part_options( $part['options'], $part, $form );
9
+
10
  $value = happyforms_get_part_value( $part, $form );
11
  $default_label = '';
12
 
23
 
24
  $placeholder_text = $part['placeholder'];
25
  ?>
 
26
  <div class="happyforms-part__el">
27
  <?php do_action( 'happyforms_part_input_before', $part, $form ); ?>
28
  <div class="happyforms-custom-select">
29
  <div class="happyforms-part__select-wrap">
 
 
 
 
30
  <?php
31
  $other_select = ( !empty( $part['other_option'] ) ) ? $part['other_option_label'] : '';
32
 
36
  'label' => $other_select,
37
  );
38
  }
39
+
40
  ?>
41
+ <select name="<?php happyforms_the_part_name( $part, $form ); ?>" data-serialize class='happyforms-select' required>
42
+ <option disabled hidden <?php echo ( $value === '' ) ? ' selected' : ''; ?> value='' class="happyforms-placeholder-option"><?php echo $placeholder_text; ?></option>
43
+ <?php foreach ( $options as $index => $option ) : ?>
44
+ <?php
45
+ $option_value = isset( $option['value'] ) ? $option['value'] : $index;
46
+ $submissions_left_label = isset( $option['submissions_left_label'] ) ? ' ' . $option['submissions_left_label'] : '';
47
+ $selected = ( $value != '' && $value == $option_value ) ? ' selected' : '';
48
+ $disabled = ( $option['limit_submissions'] == 1 && $option['submissions_left'] == 0 ) ? ' disabled' : '';
49
+ ?>
50
+ <option value="<?php echo $option_value; ?>" <?php echo $selected; ?> <?php echo $disabled; ?>><?php echo esc_attr( $option['label'] ); ?><?php echo $submissions_left_label; ?></option>
51
+ <?php endforeach; ?>
52
+ </select>
53
  </div>
54
  </div>
55
 
happyforms.php CHANGED
@@ -5,7 +5,7 @@
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
- * Version: 1.14.0
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
@@ -22,7 +22,7 @@ if ( defined( 'HAPPYFORMS_UPGRADE_VERSION' ) ) {
22
  /**
23
  * The current version of the plugin.
24
  */
25
- define( 'HAPPYFORMS_VERSION', '1.14.0' );
26
 
27
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
28
  /**
5
  * Plugin URI: https://happyforms.io
6
  * Description: We're changin' WordPress forms.
7
  * Author: Happyforms
8
+ * Version: 1.14.1
9
  * Author URI: https://happyforms.io
10
  * Upgrade URI: https://happyforms.io/upgrade
11
  */
22
  /**
23
  * The current version of the plugin.
24
  */
25
+ define( 'HAPPYFORMS_VERSION', '1.14.1' );
26
 
27
  if ( ! function_exists( 'happyforms_plugin_file' ) ):
28
  /**
inc/classes/class-happyforms.php CHANGED
@@ -59,9 +59,6 @@ class HappyForms extends HappyForms_Core {
59
  require_once( happyforms_get_include_folder() . '/classes/parts/class-part-scale-dummy.php' );
60
  $part_library->register_part( 'HappyForms_Part_Scale_Dummy', 14 );
61
 
62
- require_once( happyforms_get_include_folder() . '/classes/parts/class-part-rank-order-dummy.php' );
63
- $part_library->register_part( 'HappyForms_Part_RankOrder_Dummy', 15 );
64
-
65
  require_once( happyforms_get_include_folder() . '/classes/parts/class-part-likert-scale-dummy.php' );
66
  $part_library->register_part( 'HappyForms_Part_LikertScale_Dummy', 16 );
67
 
@@ -110,7 +107,7 @@ class HappyForms extends HappyForms_Core {
110
  $controls[1450] = array(
111
  'type' => 'checkbox_dummy',
112
  'dummy_id' => 'shuffle_parts',
113
- 'label' => __( 'Randomize fields to prevent bias', 'happyforms' ),
114
  );
115
 
116
  $controls[1500] = array(
@@ -145,8 +142,8 @@ class HappyForms extends HappyForms_Core {
145
 
146
  $controls[3190] = array(
147
  'type' => 'checkbox_dummy',
148
- 'dummy_id' => 'save_submissions',
149
- 'label' => __( 'Store replies and attachments in database', 'happyforms' ),
150
  );
151
 
152
  $controls[3191] = array(
@@ -177,24 +174,12 @@ class HappyForms extends HappyForms_Core {
177
  'label' => __( 'Include referral web address', 'happyforms' ),
178
  );
179
 
180
- $controls[541] = array(
181
- 'type' => 'checkbox_dummy',
182
- 'dummy_id' => 'owner_attach_pdf',
183
- 'label' => __( 'Attach .pdf', 'happyforms' ),
184
- );
185
-
186
  $controls[645] = array(
187
  'type' => 'email-parts-list_dummy',
188
  'dummy_id' => 'confirmation_email_respondent_address',
189
  'label' => __( 'To email address', 'happyforms' ),
190
  );
191
 
192
- $controls[871] = array(
193
- 'type' => 'checkbox_dummy',
194
- 'dummy_id' => 'attach_pdf',
195
- 'label' => __( 'Attach .pdf', 'happyforms' ),
196
- );
197
-
198
  $controls[1660] = array(
199
  'type' => 'checkbox_dummy',
200
  'dummy_id' => 'abandoned_resume_send_alert_email',
59
  require_once( happyforms_get_include_folder() . '/classes/parts/class-part-scale-dummy.php' );
60
  $part_library->register_part( 'HappyForms_Part_Scale_Dummy', 14 );
61
 
 
 
 
62
  require_once( happyforms_get_include_folder() . '/classes/parts/class-part-likert-scale-dummy.php' );
63
  $part_library->register_part( 'HappyForms_Part_LikertScale_Dummy', 16 );
64
 
107
  $controls[1450] = array(
108
  'type' => 'checkbox_dummy',
109
  'dummy_id' => 'shuffle_parts',
110
+ 'label' => __( 'Shuffle order of fields', 'happyforms' ),
111
  );
112
 
113
  $controls[1500] = array(
142
 
143
  $controls[3190] = array(
144
  'type' => 'checkbox_dummy',
145
+ 'dummy_id' => 'delete_submission_after',
146
+ 'label' => __( 'Delete permanently replies and attachments after set number of days', 'happyforms' ),
147
  );
148
 
149
  $controls[3191] = array(
174
  'label' => __( 'Include referral web address', 'happyforms' ),
175
  );
176
 
 
 
 
 
 
 
177
  $controls[645] = array(
178
  'type' => 'email-parts-list_dummy',
179
  'dummy_id' => 'confirmation_email_respondent_address',
180
  'label' => __( 'To email address', 'happyforms' ),
181
  );
182
 
 
 
 
 
 
 
183
  $controls[1660] = array(
184
  'type' => 'checkbox_dummy',
185
  'dummy_id' => 'abandoned_resume_send_alert_email',
inc/classes/parts/class-part-rank-order-dummy.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- class HappyForms_Part_RankOrder_Dummy extends HappyForms_Form_Part {
4
-
5
- public $type = 'rank_order_dummy';
6
-
7
- public function __construct() {
8
- $this->label = __( 'Rank', 'happyforms' );
9
- $this->description = __( 'For collecting preferences between choices in numeric order.', 'happyforms' );
10
- }
11
-
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
languages/happyforms.pot CHANGED
@@ -2,14 +2,14 @@
2
  # This file is distributed under the same license as the Happyforms (free) plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Happyforms (free) 1.14.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/happyforms/\n"
7
  "Last-Translator: The Theme Foundry\n"
8
  "Language-Team: The Theme Foundry\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2022-01-24T13:04:47+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: happyforms\n"
@@ -402,8 +402,8 @@ msgid "Submit form"
402
  msgstr ""
403
 
404
  #: core/classes/class-form-shuffle.php:43
405
- #: inc/classes/class-happyforms.php:113
406
- msgid "Randomize fields to prevent bias"
407
  msgstr ""
408
 
409
  #: core/classes/class-form-styles.php:54
@@ -689,12 +689,12 @@ msgstr ""
689
 
690
  #: core/classes/class-form-styles.php:716
691
  #: core/templates/parts/customize-checkbox.php:4
692
- #: core/templates/parts/customize-checkbox.php:124
693
  #: core/templates/parts/customize-email.php:4
694
  #: core/templates/parts/customize-multi-line-text.php:4
695
  #: core/templates/parts/customize-number.php:4
696
  #: core/templates/parts/customize-radio.php:4
697
- #: core/templates/parts/customize-radio.php:109
698
  #: core/templates/parts/customize-select.php:4
699
  #: core/templates/parts/customize-select.php:108
700
  #: core/templates/parts/customize-single-line-text.php:4
@@ -716,10 +716,12 @@ msgstr ""
716
 
717
  #: core/classes/class-form-styles.php:731
718
  #: core/templates/parts/customize-checkbox.php:20
 
719
  #: core/templates/parts/customize-email.php:28
720
  #: core/templates/parts/customize-multi-line-text.php:28
721
  #: core/templates/parts/customize-number.php:28
722
  #: core/templates/parts/customize-radio.php:20
 
723
  #: core/templates/parts/customize-select.php:24
724
  #: core/templates/parts/customize-single-line-text.php:28
725
  msgid "Hint"
@@ -958,11 +960,6 @@ msgstr ""
958
  msgid "For selecting one option from a long list. Default value adjustable."
959
  msgstr ""
960
 
961
- #: core/classes/parts/class-part-select.php:56
962
- #: core/assets/jsx/build/admin/block.js:127
963
- msgid "Choose"
964
- msgstr ""
965
-
966
  #: core/classes/parts/class-part-single-line-text.php:9
967
  msgid "For single line text fields."
968
  msgstr ""
@@ -3045,8 +3042,8 @@ msgstr ""
3045
 
3046
  #: core/templates/customize-form-item.php:33
3047
  #: core/templates/customize-form-part-footer.php:3
3048
- #: core/templates/parts/customize-checkbox.php:145
3049
- #: core/templates/parts/customize-radio.php:130
3050
  #: core/templates/parts/customize-select.php:129
3051
  msgid "Delete"
3052
  msgstr ""
@@ -3202,7 +3199,7 @@ msgstr ""
3202
  #: core/templates/parts/customize-checkbox.php:76
3203
  #: core/templates/parts/customize-radio.php:76
3204
  #: core/templates/parts/customize-select.php:82
3205
- msgid "Randomize choices to prevent bias"
3206
  msgstr ""
3207
 
3208
  #: core/templates/parts/customize-checkbox.php:81
@@ -3219,56 +3216,56 @@ msgstr ""
3219
 
3220
  #: core/templates/parts/customize-checkbox.php:95
3221
  #: core/templates/parts/customize-radio.php:80
3222
- msgid "Choices display"
3223
  msgstr ""
3224
 
3225
- #: core/templates/parts/customize-checkbox.php:97
3226
- #: core/templates/parts/customize-radio.php:82
3227
- msgid "Horizontal"
3228
  msgstr ""
3229
 
3230
- #: core/templates/parts/customize-checkbox.php:98
3231
- #: core/templates/parts/customize-radio.php:83
3232
- msgid "Vertical"
3233
  msgstr ""
3234
 
3235
- #: core/templates/parts/customize-checkbox.php:107
3236
  #: core/templates/parts/customize-email.php:58
3237
  #: core/templates/parts/customize-multi-line-text.php:71
3238
  #: core/templates/parts/customize-number.php:81
3239
- #: core/templates/parts/customize-radio.php:90
3240
  #: core/templates/parts/customize-select.php:89
3241
  #: core/templates/parts/customize-single-line-text.php:57
3242
  msgid "Additional CSS class(es)"
3243
  msgstr ""
3244
 
3245
- #: core/templates/parts/customize-checkbox.php:129
3246
- #: core/templates/parts/customize-radio.php:114
3247
  #: core/templates/parts/customize-select.php:113
3248
  msgid "Make this choice default"
3249
  msgstr ""
3250
 
3251
- #: core/templates/parts/customize-checkbox.php:132
3252
- #: core/templates/parts/customize-radio.php:117
3253
  #: core/templates/parts/customize-select.php:116
3254
- #: inc/classes/class-happyforms.php:143
3255
  msgid "Limit submissions"
3256
  msgstr ""
3257
 
3258
- #: core/templates/parts/customize-checkbox.php:136
3259
- #: core/templates/parts/customize-radio.php:121
3260
  #: core/templates/parts/customize-select.php:120
3261
  msgid "Max submissions"
3262
  msgstr ""
3263
 
3264
- #: core/templates/parts/customize-checkbox.php:140
3265
- #: core/templates/parts/customize-radio.php:125
3266
  #: core/templates/parts/customize-select.php:124
3267
  msgid "Show remaining submissions"
3268
  msgstr ""
3269
 
3270
- #: core/templates/parts/customize-checkbox.php:146
3271
- #: core/templates/parts/customize-radio.php:131
3272
  #: core/templates/parts/customize-select.php:130
3273
  msgid "More"
3274
  msgstr ""
@@ -3328,56 +3325,51 @@ msgstr ""
3328
  msgid "Click to edit this part."
3329
  msgstr ""
3330
 
3331
- #: inc/classes/class-happyforms.php:105
3332
  msgid "Upgrade"
3333
  msgstr ""
3334
 
3335
- #: inc/classes/class-happyforms.php:119
3336
  msgid "Use reCAPTCHA"
3337
  msgstr ""
3338
 
3339
- #: inc/classes/class-happyforms.php:125
3340
  msgid "Save incomplete and abandoned submissions"
3341
  msgstr ""
3342
 
3343
- #: inc/classes/class-happyforms.php:131
3344
  msgid "Let respondents save a draft submission and come back to it later"
3345
  msgstr ""
3346
 
3347
- #: inc/classes/class-happyforms.php:137
3348
  msgid "Require respondents to review a submission before submitting"
3349
  msgstr ""
3350
 
3351
- #: inc/classes/class-happyforms.php:149
3352
- msgid "Store replies and attachments in database"
3353
  msgstr ""
3354
 
3355
- #: inc/classes/class-happyforms.php:155
3356
  msgid "Capture user metadata (IP, language, platform, time and timezone)"
3357
  msgstr ""
3358
 
3359
- #: inc/classes/class-happyforms.php:161
3360
  msgid "Show an error message if field contains words in Disallowed Comment Keys"
3361
  msgstr ""
3362
 
3363
- #: inc/classes/class-happyforms.php:171
3364
  msgid "Include reply link"
3365
  msgstr ""
3366
 
3367
- #: inc/classes/class-happyforms.php:177
3368
  msgid "Include referral web address"
3369
  msgstr ""
3370
 
3371
- #: inc/classes/class-happyforms.php:183
3372
- #: inc/classes/class-happyforms.php:195
3373
- msgid "Attach .pdf"
3374
- msgstr ""
3375
-
3376
- #: inc/classes/class-happyforms.php:189
3377
  msgid "To email address"
3378
  msgstr ""
3379
 
3380
- #: inc/classes/class-happyforms.php:201
3381
  msgid "Send abandonment email"
3382
  msgstr ""
3383
 
@@ -3530,14 +3522,6 @@ msgstr ""
3530
  msgid "For collecting opinions and showing published results in a bar chart."
3531
  msgstr ""
3532
 
3533
- #: inc/classes/parts/class-part-rank-order-dummy.php:8
3534
- msgid "Rank"
3535
- msgstr ""
3536
-
3537
- #: inc/classes/parts/class-part-rank-order-dummy.php:9
3538
- msgid "For collecting preferences between choices in numeric order."
3539
- msgstr ""
3540
-
3541
  #: inc/classes/parts/class-part-rating-dummy.php:8
3542
  msgid "Rate"
3543
  msgstr ""
@@ -3831,6 +3815,10 @@ msgstr ""
3831
  msgid "Publishable key"
3832
  msgstr ""
3833
 
 
 
 
 
3834
  #: core/assets/jsx/build/admin/block.js:141
3835
  msgid "Pick a form to display on your site."
3836
  msgstr ""
2
  # This file is distributed under the same license as the Happyforms (free) plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Happyforms (free) 1.14.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/happyforms/\n"
7
  "Last-Translator: The Theme Foundry\n"
8
  "Language-Team: The Theme Foundry\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2022-02-15T12:42:08+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: happyforms\n"
402
  msgstr ""
403
 
404
  #: core/classes/class-form-shuffle.php:43
405
+ #: inc/classes/class-happyforms.php:110
406
+ msgid "Shuffle order of fields"
407
  msgstr ""
408
 
409
  #: core/classes/class-form-styles.php:54
689
 
690
  #: core/classes/class-form-styles.php:716
691
  #: core/templates/parts/customize-checkbox.php:4
692
+ #: core/templates/parts/customize-checkbox.php:130
693
  #: core/templates/parts/customize-email.php:4
694
  #: core/templates/parts/customize-multi-line-text.php:4
695
  #: core/templates/parts/customize-number.php:4
696
  #: core/templates/parts/customize-radio.php:4
697
+ #: core/templates/parts/customize-radio.php:115
698
  #: core/templates/parts/customize-select.php:4
699
  #: core/templates/parts/customize-select.php:108
700
  #: core/templates/parts/customize-single-line-text.php:4
716
 
717
  #: core/classes/class-form-styles.php:731
718
  #: core/templates/parts/customize-checkbox.php:20
719
+ #: core/templates/parts/customize-checkbox.php:135
720
  #: core/templates/parts/customize-email.php:28
721
  #: core/templates/parts/customize-multi-line-text.php:28
722
  #: core/templates/parts/customize-number.php:28
723
  #: core/templates/parts/customize-radio.php:20
724
+ #: core/templates/parts/customize-radio.php:120
725
  #: core/templates/parts/customize-select.php:24
726
  #: core/templates/parts/customize-single-line-text.php:28
727
  msgid "Hint"
960
  msgid "For selecting one option from a long list. Default value adjustable."
961
  msgstr ""
962
 
 
 
 
 
 
963
  #: core/classes/parts/class-part-single-line-text.php:9
964
  msgid "For single line text fields."
965
  msgstr ""
3042
 
3043
  #: core/templates/customize-form-item.php:33
3044
  #: core/templates/customize-form-part-footer.php:3
3045
+ #: core/templates/parts/customize-checkbox.php:155
3046
+ #: core/templates/parts/customize-radio.php:140
3047
  #: core/templates/parts/customize-select.php:129
3048
  msgid "Delete"
3049
  msgstr ""
3199
  #: core/templates/parts/customize-checkbox.php:76
3200
  #: core/templates/parts/customize-radio.php:76
3201
  #: core/templates/parts/customize-select.php:82
3202
+ msgid "Shuffle order of choices"
3203
  msgstr ""
3204
 
3205
  #: core/templates/parts/customize-checkbox.php:81
3216
 
3217
  #: core/templates/parts/customize-checkbox.php:95
3218
  #: core/templates/parts/customize-radio.php:80
3219
+ msgid "Align choices"
3220
  msgstr ""
3221
 
3222
+ #: core/templates/parts/customize-checkbox.php:99
3223
+ #: core/templates/parts/customize-radio.php:84
3224
+ msgid "Vertically"
3225
  msgstr ""
3226
 
3227
+ #: core/templates/parts/customize-checkbox.php:103
3228
+ #: core/templates/parts/customize-radio.php:88
3229
+ msgid "Horizontally"
3230
  msgstr ""
3231
 
3232
+ #: core/templates/parts/customize-checkbox.php:113
3233
  #: core/templates/parts/customize-email.php:58
3234
  #: core/templates/parts/customize-multi-line-text.php:71
3235
  #: core/templates/parts/customize-number.php:81
3236
+ #: core/templates/parts/customize-radio.php:96
3237
  #: core/templates/parts/customize-select.php:89
3238
  #: core/templates/parts/customize-single-line-text.php:57
3239
  msgid "Additional CSS class(es)"
3240
  msgstr ""
3241
 
3242
+ #: core/templates/parts/customize-checkbox.php:139
3243
+ #: core/templates/parts/customize-radio.php:124
3244
  #: core/templates/parts/customize-select.php:113
3245
  msgid "Make this choice default"
3246
  msgstr ""
3247
 
3248
+ #: core/templates/parts/customize-checkbox.php:142
3249
+ #: core/templates/parts/customize-radio.php:127
3250
  #: core/templates/parts/customize-select.php:116
3251
+ #: inc/classes/class-happyforms.php:140
3252
  msgid "Limit submissions"
3253
  msgstr ""
3254
 
3255
+ #: core/templates/parts/customize-checkbox.php:146
3256
+ #: core/templates/parts/customize-radio.php:131
3257
  #: core/templates/parts/customize-select.php:120
3258
  msgid "Max submissions"
3259
  msgstr ""
3260
 
3261
+ #: core/templates/parts/customize-checkbox.php:150
3262
+ #: core/templates/parts/customize-radio.php:135
3263
  #: core/templates/parts/customize-select.php:124
3264
  msgid "Show remaining submissions"
3265
  msgstr ""
3266
 
3267
+ #: core/templates/parts/customize-checkbox.php:156
3268
+ #: core/templates/parts/customize-radio.php:141
3269
  #: core/templates/parts/customize-select.php:130
3270
  msgid "More"
3271
  msgstr ""
3325
  msgid "Click to edit this part."
3326
  msgstr ""
3327
 
3328
+ #: inc/classes/class-happyforms.php:102
3329
  msgid "Upgrade"
3330
  msgstr ""
3331
 
3332
+ #: inc/classes/class-happyforms.php:116
3333
  msgid "Use reCAPTCHA"
3334
  msgstr ""
3335
 
3336
+ #: inc/classes/class-happyforms.php:122
3337
  msgid "Save incomplete and abandoned submissions"
3338
  msgstr ""
3339
 
3340
+ #: inc/classes/class-happyforms.php:128
3341
  msgid "Let respondents save a draft submission and come back to it later"
3342
  msgstr ""
3343
 
3344
+ #: inc/classes/class-happyforms.php:134
3345
  msgid "Require respondents to review a submission before submitting"
3346
  msgstr ""
3347
 
3348
+ #: inc/classes/class-happyforms.php:146
3349
+ msgid "Delete permanently replies and attachments after set number of days"
3350
  msgstr ""
3351
 
3352
+ #: inc/classes/class-happyforms.php:152
3353
  msgid "Capture user metadata (IP, language, platform, time and timezone)"
3354
  msgstr ""
3355
 
3356
+ #: inc/classes/class-happyforms.php:158
3357
  msgid "Show an error message if field contains words in Disallowed Comment Keys"
3358
  msgstr ""
3359
 
3360
+ #: inc/classes/class-happyforms.php:168
3361
  msgid "Include reply link"
3362
  msgstr ""
3363
 
3364
+ #: inc/classes/class-happyforms.php:174
3365
  msgid "Include referral web address"
3366
  msgstr ""
3367
 
3368
+ #: inc/classes/class-happyforms.php:180
 
 
 
 
 
3369
  msgid "To email address"
3370
  msgstr ""
3371
 
3372
+ #: inc/classes/class-happyforms.php:186
3373
  msgid "Send abandonment email"
3374
  msgstr ""
3375
 
3522
  msgid "For collecting opinions and showing published results in a bar chart."
3523
  msgstr ""
3524
 
 
 
 
 
 
 
 
 
3525
  #: inc/classes/parts/class-part-rating-dummy.php:8
3526
  msgid "Rate"
3527
  msgstr ""
3815
  msgid "Publishable key"
3816
  msgstr ""
3817
 
3818
+ #: core/assets/jsx/build/admin/block.js:127
3819
+ msgid "Choose"
3820
+ msgstr ""
3821
+
3822
  #: core/assets/jsx/build/admin/block.js:141
3823
  msgid "Pick a form to display on your site."
3824
  msgstr ""
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: contact form, contact form plugin, forms, form builder, custom form, intak
5
  Requires at least: 5.0
6
  Tested up to: 5.9
7
  Requires PHP: 7.0
8
- Stable tag: 1.14.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -151,16 +151,24 @@ Aw, honestly, the thought that you're writing about our contact form builder is
151
 
152
  == Changelog ==
153
 
 
 
 
 
 
 
 
 
154
  = 1.14.0 =
155
  * Improvement: Nonce checks have been removed for improved compatibility with cache plugins.
156
- * Removal: "Tooltip" styling for field hints has been deprecated.
157
- * Removal: "Add 'select all' choice" control has been deprecated.
158
- * Removal: Long Text field's "Add rich text editor toolbar" control has been deprecated.
159
  * Bugfix: Form width was rendered incorrectly on specific PHP versions.
160
 
161
  = 1.13.12 =
162
- * Removal: Long Text field "Rows" control has been removed.
163
- * Removal: "Add other choice" control has been deprecated.
164
 
165
  = 1.13.11 =
166
  * Improvement: Miscellaneous improvements to Forms screen.
@@ -900,6 +908,9 @@ Aw, honestly, the thought that you're writing about our contact form builder is
900
 
901
  == Upgrade Notice ==
902
 
 
 
 
903
  = 1.14.0 =
904
  * Improved cache compatibility, feature deprecations, minor bugfixes.
905
 
5
  Requires at least: 5.0
6
  Tested up to: 5.9
7
  Requires PHP: 7.0
8
+ Stable tag: 1.14.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
151
 
152
  == Changelog ==
153
 
154
+ = 1.14.1 =
155
+ * New feature: "Hint" control for adding descriptive text to Radio and Checkbox field choices.
156
+ * Improvement: Nicer vertical alignment of choices spanning multiple lines in Radio and Checkbox fields.
157
+ * Improvement: "Align choices" control is now a button group for better usability.
158
+ * Improvement: Exhausted choices are now always tagged with "(0 remaining)" to avoid confusion.
159
+ * Improvement: All instances of "submit" type inputs have been replaced with buttons for easier styling.
160
+ * Improvement: All custom form dropdowns have been replaced with their native counterparts for better performance and accessibility.
161
+
162
  = 1.14.0 =
163
  * Improvement: Nonce checks have been removed for improved compatibility with cache plugins.
164
+ * Removal: "Tooltip" styling for field hints has been deprecated to improve usability of forms.
165
+ * Removal: "Add 'select all' choice" was redundant and has been deprecated.
166
+ * Removal: Long Text field's more lightweight with "Add rich text editor toolbar" deprecation.
167
  * Bugfix: Form width was rendered incorrectly on specific PHP versions.
168
 
169
  = 1.13.12 =
170
+ * Removal: Long Text field "Rows" behaved inconsistently and has been removed.
171
+ * Removal: "Add other choice" control has been deprecated in favor of conditional logic.
172
 
173
  = 1.13.11 =
174
  * Improvement: Miscellaneous improvements to Forms screen.
908
 
909
  == Upgrade Notice ==
910
 
911
+ = 1.14.1 =
912
+ * Radio and Checkbox fields choice hints, true submit buttons, layout and usability improvements.
913
+
914
  = 1.14.0 =
915
  * Improved cache compatibility, feature deprecations, minor bugfixes.
916